swarm-grafana: one delivery route for the OIDC client secret
The previous commit left two delivery paths and a three-way gate: `swarm-grafana-oidc-secret.service` copied authelia's minted plaintext out of its host tree wherever the two were co-located, `swarm-bao-grafana-oidc.service` read the same value from the swarm secret store wherever they were not, and `ssoConfigured && (ssoLocal || haveClientIdentity)` decided whether Grafana got an OIDC block at all. Delete the co-located path. The store reader is now THE delivery unit, in every deployment — the publisher on authelia's host writes `swarm/services/<id>/oidc/client` whether the reader is a network away or in the container next door. The ruling behind it: the store exists so a host holds ONE out-of-band secret, its client certificate, and reads everything else with it. Skipping the store when the producer happens to be local saves a round trip and costs a second delivery unit, a second way for the file to be wrong, and a gate to choose between them. The gate goes too, and both of its questions become assertions, scoped to hosts that run Grafana: - `swarm.authelia.url` must be set. `auth.disable_login_form` is unconditional — Grafana ships an admin/admin account on a public vhost — so dropping the OIDC block when the swarm names no IdP produced a container with no SSO and no password box, silently. An eval-time refusal naming the option is the only report that reaches anyone, the shape swarm-nats.nix already uses for the same option. - `deploy.bao.clientCertFile` / `clientKeyFile` must be set. This replaces a warning that nothing reads back, and its message names both options and where the leaf comes from. Fixtures follow. `grafanaWithAuthelia` gains the cert pair, because a co-located host is a store reader like any other. The old `grafanaRemoteAutheliaNoIdentity` is kept rather than deleted, renamed `grafanaNoIdentity`: the shape is still reachable, only its deliverable changed from silence to a refusal, and an arm now reads that refusal back. Its mirror `grafanaNoSso` covers the other assertion, each fixture wrong in exactly one way so an arm can name which refusal fired. Every positive keeps an explicit negative — the one-delivery-unit arm asserts the deleted unit is absent in both topologies rather than merely that the store reader is present. Refs #4234 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
4aa982cc2a
commit
815f977d7c
5 changed files with 295 additions and 233 deletions
|
|
@ -71,11 +71,11 @@ for the whole swarm, so its credential's path names the service and never the
|
|||
host — and which hive runs a given service is a `deploy.*` fact, per-host by
|
||||
definition, so nothing swarm-wide exists to scope the grant to. The host running
|
||||
such a service has no store identity of its own either; it reads with the
|
||||
certificate of the hive it is. So **any hive can read any swarm service's client
|
||||
secret**, which is worth what it buys: a swarm service whose identity provider
|
||||
lives on another machine can get its secret at all, instead of only working
|
||||
co-located. Giving such a service its own store identity is what would remove
|
||||
this rather than re-scope it.
|
||||
certificate of the hive it is. **Any hive can therefore read any swarm service's
|
||||
client secret**, which is worth what it buys: every swarm service gets its
|
||||
credential the same way from anywhere, instead of only where the identity
|
||||
provider happens to sit. Giving such a service its own store identity is what
|
||||
would remove this rather than re-scope it.
|
||||
|
||||
**A tracked follow-up** narrows this, with the two candidate directions: scope
|
||||
the grant per hive (and pay for the re-emission), or give each agent container
|
||||
|
|
|
|||
Loading…
Reference in a new issue