swarm: wire the agents' queue coordinates and credential through the modules
The host end: `HIVE_C0RE_AGENT_QUEUE_CREDENTIAL_DIR` tells the daemon where the reader unit put the files, and a new `deploy.hive-controller.queue.agentNatsUrl` says where the queue is as an agent *container* reaches it. That address defaults to the bridge one and never to loopback — `statusPublish.natsUrl` beside it is loopback and correct, because hive-c0re shares the host netns and an agent does not. Paired with the swarm's token endpoint, gated together, and forwarded by `hive_c0re::meta` as both an env var and an agent option: the harness reads the variable at runtime, its unit is built from the option. The agent end: `nix/agent-modules/queue.nix` declares that option pair and, when set, has the harness unit inherit the two credentials by name. Bare-id `LoadCredential=` is the terse form documented for inheriting what the service manager received, and is non-fatal when the credential is absent — which a hive whose publisher has not run yet needs. No `HIVE_AGENT_OIDC_CA_FILE`: the meta flake already embeds the hive CA and the swarm root into each container's trust store at build time, and reqwest's rustls backend verifies against it. Refs #3805
This commit is contained in:
parent
353cdd9264
commit
86652f051a
7 changed files with 290 additions and 0 deletions
|
|
@ -168,6 +168,21 @@ reader runs before `hive-c0re.service` and is wanted (not required) by it, so
|
|||
an agent container never renders ahead of the credential; an unreachable store
|
||||
delays the daemon's start rather than failing it.
|
||||
|
||||
That credential still has one hop left, because the reader of it lives inside
|
||||
an agent container. **It crosses as a systemd credential, not as a bind
|
||||
mount**, and the mode decides that: the secret is `root:0600` and a harness
|
||||
runs as its own unprivileged agent user, so a bind would deliver a file that
|
||||
user can't open. `hive-c0re` stats the two files — the directory is `0755`, so
|
||||
it needs no read access to either — and hands them to
|
||||
`systemd-nspawn --load-credential` through `hive-priv`, which runs as root.
|
||||
Inside, `hive-agent.service` names the same two ids in `LoadCredential=` and
|
||||
reads them out of its own `$CREDENTIALS_DIRECTORY`, owned by the agent user
|
||||
and by nobody else. `hive-c0re` never reads the bytes at any point: it runs as
|
||||
`hive-core`, which is the reason a copy wasn't an option either. When the
|
||||
files aren't there the daemon forwards nothing and says so in its journal, and
|
||||
the harness logs that it has no queue — the same absent-and-legal state, twice,
|
||||
rather than a container that refuses to start.
|
||||
|
||||
⚠️ **Service↔store mTLS is its own trust domain.** A credential you must
|
||||
already hold to authenticate can't be fetched from the thing it authenticates
|
||||
you to, so the store's identity can't come from an authority the store
|
||||
|
|
|
|||
Loading…
Reference in a new issue