# The route-switch helper (gateway hosts) The dashboard's one narrow write is a route switch: one named connection on the ingress goes `#off` (a marker the agent's own parser reads) or comes back. It is not a sudoers line. The grant is a **file mode systemd enforces**: the socket the agent talks to is `0600` and owned by the agent's own user, and the helper's peer check (`--allow-uid`) is the second look. No account on the host — `ops` included — can reach the write; only the agent's uid can connect, and only that uid is accepted on the other end. ## The two units | unit | what it is | | ---- | ---------- | | `dashboards-routectl.socket` | a systemd-activated stream socket at `/run/dashboards-routectl.sock`, `0600`, owned by `dashboards-agent` | | `dashboards-routectl@.service` | the helper, **root**, one instance per connection (the connected socket on stdin), answers one request and exits | The service unit's `ReadWritePaths` lists exactly the directories whose file the helper replaces — `/etc/haproxy`, `/etc/nginx/conf.d`, `/etc/nginx/stream.d` — and nothing else. There is never a long-lived privileged process: each request spawns a fresh instance that exits after its one answer. ## See them ``` systemctl status dashboards-routectl.socket systemctl status 'dashboards-routectl@*.service' journalctl -u 'dashboards-routectl@*' ``` ## Run the helper by hand on the box The installed copy is `/usr/local/sbin/dashboards-routectl.py`. It takes its agent parser by file path and refuses to run without one: ``` # what is off (the state sidecar) sudo /usr/local/sbin/dashboards-routectl.py list # preview one route without writing a byte (no checker, no reload, no state) sudo /usr/local/sbin/dashboards-routectl.py diff --id nginx:443->127.0.0.1:44450 --action enable # verify the sidecar against the files (drift is reported, never repaired) sudo /usr/local/sbin/dashboards-routectl.py verify ``` A manual `disable --apply` runs the whole protocol: write, the proxy's own checker (`nginx -t` / `haproxy -c -f`), restore the previous bytes on a checker failure, `systemctl reload` (never `restart`) on success, then record the state. ## Undo it all ``` sudo ./deploy/install-agent.sh --without-routectl ``` That disables and removes the helper and its two units, **leaves the proxy configs and the helper's state directory alone**, and prints the list of still-off routes first — those are yours to switch back on. ## The one safety sentence No sudoers line is involved. The agent's unit keeps every one of its security directives (`NoNewPrivileges=true`, `ProtectSystem=strict`, …); the read-only collector stayed read-only in its sandbox and talked to a peer outside it. The grant is the socket's mode and ownership, enforced by systemd.