Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: read the queue client secret from the store, drop the file
Some checks were skipped
public bin cache / build + push to preem:grid (push) Has been skipped

The controller's OIDC client secret (client `swarm-controller`, used for
the queue connection, the auth-bridge bearer and the OTLP push) came from
an operator-placed file, `deploy.swarm-controller.queue.clientSecretFile`,
handed in by `LoadCredential=`.

Now `swarm-secret-publish`, which already copies authelia's minted OIDC
secrets into the store, also publishes this one, to
`swarm/controller/swarm-controller/oidc/client`. That path sits under
`controller/`, which no hive's policy reads. The controller reads it once
at start with its existing store certificate and holds it in memory, as
`swarm_queue_client::ClientSecret::Value`. If the store is down, it
retries for about a minute and then fails the start, so `Restart=` tries
again.

Policy delta: the controller gets `read` on that leaf, and the publisher
gets `create`/`update` on that leaf.

Removed: the `queue.clientSecretFile` option (both spellings, now removed
options with a message), its singleHostSwarm default, the credential and
placeholder, and the path watcher plus its restart oneshot. A controller
without a store identity is now an eval error, because it has no other
way to get the secret.
This commit is contained in:
atlas 2026-09-28 19:00:31 +02:00
commit e94406cdb9
22 changed files with 595 additions and 247 deletions

View file

@ -360,9 +360,9 @@ let
# re-run keeps the value a live agent already holds instead of rotating it —
# the read is required, not incidental.
#
# The swarm appservice token, read-only: the controller creates agents'
# matrix accounts with it and never writes it. matrix-ctl mints and publishes
# it (`matrixCtlPolicyText` below).
# The swarm appservice token and its own OIDC client secret, read-only: it
# uses both and writes neither. matrix-ctl publishes the token
# (`matrixCtlPolicyText` below), the publisher the secret.
#
# The agent PKI grant is its only path on that mount: it can ask the one role
# for a certificate, not write that role or reach the issuer.
@ -391,6 +391,10 @@ let
capabilities = ["read"]
}
path "${credentialMountPath}/data/${controllerClientLeaf}" {
capabilities = ["read"]
}
path "${agentPkiMountPath}/issue/${agentPkiRoleName}" {
capabilities = ["update"]
}
@ -403,17 +407,18 @@ let
secretPublisherPolicyName = "swarm-secret-publisher";
secretPublisherCn = baoDeploy.secretPublisherCommonName;
# Two grants, and every narrowing in each is load-bearing.
# Three grants, and every narrowing in each is load-bearing.
#
# `secret/data/` is KV v2's ACL prefix, inserted by the engine rather than
# written by the caller — same trap as the controller's grant above.
#
# Two prefixes and not `swarm/*`: this principal has no business with an
# agent's credentials or the controller's, and these two are the only paths
# it produces. It grew the `services/` one when the publisher gained a swarm
# service's OIDC secret to copy, which is the rule ../module-eval.nix states
# for the controller's side of the same wall — a grant widens when a path
# gains a WRITER, not when a kind is declared.
# Two prefixes and one leaf, not `swarm/*`: this principal has no business
# with an agent's credentials, and these are the only paths it produces.
# Under `controller/` it writes the controller's OIDC client alone, spelled
# to the leaf so the appservice token beside it stays out of reach. The rule
# ../module-eval.nix states for the controller's side of the same wall holds
# here too — a grant widens when a path gains a WRITER, not when a kind is
# declared.
#
# Write-only. It copies secrets in and never reads one back; a read
# capability would let a file-copier recover every hive's credentials.
@ -425,6 +430,10 @@ let
path "${credentialMountPath}/data/swarm/services/*" {
capabilities = ["create", "update"]
}
path "${credentialMountPath}/data/${controllerClientLeaf}" {
capabilities = ["create", "update"]
}
'';
# The identity the matrix container's `swarm-matrix-ctl` presents. Named outside `hive-*`
@ -489,6 +498,11 @@ let
# homeserver's admin.
swarmAppserviceTokenLeaf = "swarm/controller/swarm-controller/matrix/appservice-token";
# The controller's own OIDC client secret, the nix half of
# `swarm_secret_client::queue::controller_client_path`. The publisher writes
# it; the controller reads it and holds no other copy.
controllerClientLeaf = "swarm/controller/swarm-controller/oidc/client";
# The KV v2 engine the controller writes agent credentials through. Named
# once because the grant above and the `secrets enable` in the bootstrap unit
# have to agree: a policy pointing at a mount nobody created is precisely the