swarm-bao: keep the store forwarder's OIDC secret on the host's /run, not in the container's root
swarm-bao-forwarder-oidc still reads the secret from bao under the forwarder's own leaf, but now writes it to /run/swarm-bao-forwarder-oidc on the host (tmpfs), which the swarm-bao container bind-mounts read-only for the collector's LoadCredential. Before, it wrote it to /var/lib/nixos-containers/swarm-bao/var/lib/swarm-bao-otel-oidc/<id>.secret on persistent disk, where a superseded secret stayed after rotation and went into backups of the container root. Host tmpfiles now removes that old file. Rotation is unchanged: the ten-minute timer rewrites the file when the value differs and refresh_consumer restarts the forwarder. After a reboot the secret is fetched again; the file is not pre-created, so until the store answers the forwarder stays down (LoadCredential refuses a missing source) and resumes from its journal cursor afterwards. The container now starts after systemd-tmpfiles-resetup, since the new bind source is made there. Part of #4998 (slice 3: forwarder).
This commit is contained in:
parent
a1f99c77f8
commit
6f5bd1dc5d
3 changed files with 80 additions and 29 deletions
|
|
@ -112,7 +112,7 @@ The **secret store's own** collector — the forwarder inside the `swarm-bao`
|
|||
container — needs a delivery step too, and it takes the same route with one
|
||||
principal of its own: `swarm-bao-forwarder-oidc.service` reads
|
||||
`swarm/services/<client-id>/oidc/client` under a leaf of its own and
|
||||
lands it in the container's tree, where `LoadCredential` hands it to the
|
||||
writes it to `/run/swarm-bao-forwarder-oidc` on the host's tmpfs, which the container bind-mounts read-only and where `LoadCredential` hands it to the
|
||||
collector. The client id is its own
|
||||
(`services.hyperhive.swarm.bao.otel.clientId`), registered by
|
||||
`glue-swarm-bao-otel-oidc-client.nix` wherever authelia runs, and the swarm
|
||||
|
|
@ -123,11 +123,11 @@ this forwarder borrows neither the swarm collector's client nor
|
|||
⚠️ **This one has no degraded mode, and the difference is structural.** The
|
||||
route it exports over accepts an authenticated request and nothing else, so a
|
||||
forwarder without the secret has nothing to fall back to: the unit fails and
|
||||
retries, and the collector refuses to start until the file arrives rather than
|
||||
retries, and the collector refuses to start until the file arrives, after every boot, rather than
|
||||
exporting into a 401 while reporting healthy. Its ordering differs from the
|
||||
unit above it for the same structural reason — it reads the store inside the
|
||||
container it delivers into, so it runs **after** that container rather than
|
||||
before it, and only a first boot ever waits.
|
||||
before it. The fetch creates the file, so when the store stays sealed or unreachable after a boot the forwarder stays down, then resumes from its saved journal cursor once the store answers.
|
||||
|
||||
### The queue's callout nkeys
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue