vpn: enrol the host in ymr.serviceSandbox (nix-config#934) #1968

Merged
hermes merged 1 commit from kb/NCFG-934-enrol-vpn-sandbox into main 2026-10-13 08:01:31 -06:00
Collaborator

Kanban card nix-config#934 (child of the nix-config#928 decompose).

Enrols vpn in ymr.serviceSandbox — the §9 step 2 cutover after mail (#932) and public (#933).

Change: hosts/vpn/default.nix sets ymr.serviceSandbox.enable = true and enrols six non-foreground observability units with write paths measured on the host (systemctl show <unit> -p StateDirectory -p ExecStart):

unit measured write path
vmagent /var/cache/vmagent (-remoteWrite.tmpDataPath)
vlagent /var/lib/vlagent (tmpDataPath + file checkpoints)
systemd-journal-upload /var/lib/systemd/journal-upload (--save-state)
prometheus-node-exporter none (reads /proc + /sys)
prometheus-process-exporter none (reads /proc)
prometheus-systemd-exporter none (reads the bus)

prometheus-node-exporter carries the now-standard extraConfig.SystemCallFilter = [ "@system-service" "@clock" ] — its timex collector calls adjtimex(2), which @system-service excludes (measured on vpn-mx, nix-config#909: sig=31 syscall=171, NRestarts=16 in 13 min).

Deliberately NOT enrolled (later one-at-a-time cutovers): caddy (ingress writer), the CI runners (module exception register), postgres/victorialogs/victoriametrics (database + store writers), wg-quick-* (create interfaces), nix-temproot-reap (a oneshot — needs a by-timer cutover).

Eval evidence (run locally against this branch):

  • nix eval .#nixosConfigurations.vpn.config.ymr.serviceSandbox.enrolledUnits = the six units.
  • Rendered /etc/fleet-service-sandbox.policy lists the six with their paths + the exception register.
  • vlagent/vmagent/systemd-journal-upload resolve to ProtectSystem=strict + their ReadWritePaths; prometheus-node-exporter keeps its own module's keys (its own ProtectSystem=strict, ProtectHome=true) while the extraConfig adds @clock.

vmagent + prometheus-node-exporter are already in vpn's fleet.healthGate.criticalServices, so a switch that breaks either is caught by the deploy health gate and auto-rolled back.

Kanban card nix-config#934 (child of the nix-config#928 decompose). Enrols vpn in `ymr.serviceSandbox` — the §9 step 2 cutover after mail (#932) and public (#933). **Change:** `hosts/vpn/default.nix` sets `ymr.serviceSandbox.enable = true` and enrols six non-foreground observability units with write paths **measured on the host** (`systemctl show <unit> -p StateDirectory -p ExecStart`): | unit | measured write path | |---|---| | vmagent | /var/cache/vmagent (`-remoteWrite.tmpDataPath`) | | vlagent | /var/lib/vlagent (tmpDataPath + file checkpoints) | | systemd-journal-upload | /var/lib/systemd/journal-upload (`--save-state`) | | prometheus-node-exporter | none (reads /proc + /sys) | | prometheus-process-exporter | none (reads /proc) | | prometheus-systemd-exporter | none (reads the bus) | `prometheus-node-exporter` carries the now-standard `extraConfig.SystemCallFilter = [ "@system-service" "@clock" ]` — its `timex` collector calls `adjtimex(2)`, which `@system-service` excludes (measured on vpn-mx, nix-config#909: `sig=31 syscall=171`, NRestarts=16 in 13 min). **Deliberately NOT enrolled** (later one-at-a-time cutovers): caddy (ingress writer), the CI runners (module exception register), postgres/victorialogs/victoriametrics (database + store writers), wg-quick-* (create interfaces), nix-temproot-reap (a oneshot — needs a by-timer cutover). **Eval evidence (run locally against this branch):** - `nix eval .#nixosConfigurations.vpn.config.ymr.serviceSandbox.enrolledUnits` = the six units. - Rendered `/etc/fleet-service-sandbox.policy` lists the six with their paths + the exception register. - `vlagent`/`vmagent`/`systemd-journal-upload` resolve to `ProtectSystem=strict` + their `ReadWritePaths`; `prometheus-node-exporter` keeps its own module's keys (its own `ProtectSystem=strict`, `ProtectHome=true`) while the extraConfig adds `@clock`. `vmagent` + `prometheus-node-exporter` are already in vpn's `fleet.healthGate.criticalServices`, so a switch that breaks either is caught by the deploy health gate and auto-rolled back.
vpn: enrol the host in ymr.serviceSandbox (nix-config#934)
All checks were successful
PR base guard / Base drift / conflict check (pull_request) Successful in 5s
NixOS Build Check / Flake input regression guard (pull_request) Successful in 7s
NixOS Build Check / Scope changed deployable hosts (pull_request) Successful in 9s
NixOS Build Check / Sentinel pass budget contract (prompt forbids the full board walk, mutation-tested) (pull_request) Successful in 2s
NixOS Build Check / Worker-scope reaper worker signature (mutation-tested) (pull_request) Successful in 4s
Secret Scan / gitleaks scan (pull_request) Successful in 9s
NixOS Build Check / Kanban pool capacity knob (runtime override + clamp, mutation-tested) (pull_request) Successful in 4s
NixOS Build Check / foremerge accept-order contract (real binary) (pull_request) Successful in 6s
NixOS Build Check / .forgejo/tests python suites (hermetic) (pull_request) Successful in 27s
NixOS Build Check / Build changed host closures (native, one eval) (pull_request) Successful in 48s
NixOS Build Check / CI-scratch reaper class table (mutation-tested) (pull_request) Successful in 8s
NixOS Build Check / Repo gates (the folded selftest battery) (pull_request) Successful in 3m30s
foremerge intent (advisory) all 1 changed path(s) covered by a live foremerge intent
NixOS Build Check / Hermes runtime gates (one eval of vpn's runtime) (pull_request) Successful in 4m31s
8b67a700cc
Cutover from nix-config#896 §9 step 2, following mail (#932) and public (#933).

hosts/vpn/default.nix sets ymr.serviceSandbox.enable = true and enrols the six
non-foreground observability units with write paths MEASURED on the host
(systemctl show <unit> -p StateDirectory -p ExecStart):
  vmagent                     /var/cache/vmagent
  vlagent                     /var/lib/vlagent
  systemd-journal-upload      /var/lib/systemd/journal-upload
  prometheus-node-exporter    (none - reads /proc + /sys)
  prometheus-process-exporter (none - reads /proc)
  prometheus-systemd-exporter (none - reads the bus)

node-exporter carries the now-standard extraConfig SystemCallFilter
= ["@system-service" "@clock"] (its timex collector calls adjtimex(2), which
@system-service excludes - measured on vpn-mx, nix-config#909).

Deliberately NOT enrolled: caddy (ingress writer), the CI runners (module
exception register), postgres/victorialogs/victoriametrics (database + store
writers), wg-quick-* (create interfaces), and nix-temproot-reap (a oneshot,
needs a by-timer cutover). Each is a later one-at-a-time cutover.

Evidence: nix eval .#nixosConfigurations.vpn.config.ymr.serviceSandbox.enrolledUnits
= the six units; the rendered /etc/fleet-service-sandbox.policy lists them with
their paths; node-exporter resolves to [@system-service @clock] while its own
module's keys win over the table (it keeps its own ProtectSystem=strict).
hermes merged commit aa0a016887 into main 2026-10-13 08:01:31 -06:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ymrtech/nix-config!1968
No description provided.