refactor(maestro): drop allow_inbound policy gate, keep JWT session binding (NAP-339)

The peer (T2) attach path had a per-pair access-control layer
(`[daemon.policy].allow_inbound`): a target-side allow-list of daemon ids
permitted to broker-attach, enforced inside JWT verification, hot-reloadable via
SIGHUP / `POST /api/policy/reload`, with a `maestro policy` CLI. On a flat-trust
perimeter (the operator's VPN/firewall is the boundary for which hosts connect)
that granularity is unused, and deny-by-default made it config friction —
cross-daemon attach silently failed until every peer was listed.

Remove the allow-list; keep the registry-minted pair-attach JWT and ALL its
binding checks (iss=registry, aud=target, sid=session, exp). The firewall gates
host->port reachability; it does not stop a reachable host from attaching to a
session it wasn't handed or replaying a token elsewhere — that's the JWT's job
and it stays. Only the `sub in allow_inbound` check is dropped.

Removed: DaemonPolicySection / [daemon.policy].allow_inbound (config + daemon),
policy.rs (SIGHUP listener + GET/POST /api/policy), the `maestro policy` CLI,
PairAttachVerifier's allow-list field/reload/snapshot + JwtError::NotAllowed,
and the e2e broker_rejects_when_target_doesnt_allow_inbound test. The NAP-265
pre-upgrade-502 path stays covered by broker_attach_returns_502_on_perimeter_mismatch.

Also dropped the unit's ExecReload=kill -HUP: with no SIGHUP handler left,
default SIGHUP disposition is terminate, so wiring `systemctl reload` to it would
kill the daemon. Re-introducing a per-pair gate later is a verify-time change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-19 07:07:55 +00:00
co-authored by Claude Opus 4.8
parent 02475191df
commit b6833ede43
20 changed files with 60 additions and 722 deletions
+9 -13
View File
@@ -190,20 +190,16 @@ Pick `/tmp` if the daemon must outlive your login session and you can't run
tmux sockets with it). The env var `MAESTRO_DAEMON_TMUX_TMPDIR` takes
precedence over the file.
## Hot-reloading policy
## Peer attach trust model
`[daemon.policy].allow_inbound` (the list of peer daemons allowed to broker-
attach into this one) can be changed without restarting the daemon — restarting
would kill every live session. Three ways to apply an edit:
```sh
maestro policy reload # POSTs to the local daemon's /api/policy/reload
maestro policy show # prints the current effective list
kill -HUP <maestro-pid> # equivalent; what `systemctl --user reload` does
```
Only newly-arriving attach attempts see the change — sessions already
attached stay attached. To boot a live attacher out, kill the session.
There is no per-peer allow-list. The operator's network perimeter (VPN/firewall)
is the trust boundary for *which hosts can connect*; every daemon reachable on
the perimeter may broker-attach to any other. Attach is still authenticated: the
registry mints a short-lived, pair-scoped JWT bound to the target daemon and the
specific session (`iss`/`aud`/`sid`/`exp`), which the target verifies — so a
reachable host still can't attach to a session it wasn't handed, or replay a
token elsewhere. (NAP-339 dropped the earlier `[daemon.policy].allow_inbound`
gate; re-introducing a per-pair allow-list later is a verify-time change.)
## What the systemd unit looks like