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
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:
parent
97c4771514
commit
e94406cdb9
22 changed files with 595 additions and 247 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue