From 2fc63d844bb0130abff1ff866c4fc1da0813e65a Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 30 Oct 2026 04:32:22 +0100 Subject: [PATCH] name the mint, not the publisher, as the writer of the client secrets Finishes the sweep of prose that said the publisher unit writes or carries the OIDC client secrets: rust docs, nix comments and option descriptions, test names and docs. --- docs/scheduler/observability.md | 2 +- nix/host-modules/glue-bao-tls.nix | 2 +- .../glue-secret-publisher-bao-identity.nix | 2 +- nix/host-modules/hive-forge/default.nix | 4 ++-- nix/host-modules/hive-matrix.nix | 3 +-- nix/host-modules/otel.nix | 4 ++-- nix/host-modules/swarm-authelia.nix | 6 +++--- nix/host-modules/swarm-bao.nix | 14 +++++++------- nix/host-modules/swarm-builder.nix | 4 ++-- nix/host-modules/swarm-claude-login.nix | 4 ++-- nix/host-modules/swarm-grafana.nix | 8 ++++---- nix/host-modules/swarm-notify-router.nix | 4 ++-- nix/host-modules/swarm-otel.nix | 6 +++--- nix/host-modules/swarm-review-classifier.nix | 4 ++-- nix/module-eval/bao-grants.nix | 2 +- nix/module-eval/bao-otel-collector.nix | 2 +- nix/module-eval/grafana.nix | 2 +- nix/module-eval/swarm-otel-core.nix | 2 +- swarm-nats-auth/src/oidc_secret.rs | 10 +++++----- swarm-secret-client/src/builder.rs | 2 +- swarm-secret-client/src/ci_metrics.rs | 2 +- swarm-secret-client/src/queue.rs | 9 +++++---- swarm-secret-client/src/review_classifier.rs | 2 +- swarm-secret-client/src/stored_secret.rs | 4 ++-- 24 files changed, 52 insertions(+), 52 deletions(-) diff --git a/docs/scheduler/observability.md b/docs/scheduler/observability.md index 0e7468b3..705b7b45 100644 --- a/docs/scheduler/observability.md +++ b/docs/scheduler/observability.md @@ -152,7 +152,7 @@ the label isn't taken from the payload at all. **Nothing to set where the hive holds its store identity.** The hive's collector reads its secret from the swarm's secret store under the hive's own leaf (`deploy.bao.clientCertFile`): `swarm-bao-hive-otel-oidc.service` fetches -`swarm/hives//oidc/client`, which the publisher in authelia's container +`swarm/hives//oidc/client`, which authelia's mint, in its container, writes, into `/run/hive-otel-oidc/` (tmpfs, so never on persistent disk). It runs at boot and retries every 30s until the store answers; until then the collector runs on an empty file and the swarm refuses its exports. When a diff --git a/nix/host-modules/glue-bao-tls.nix b/nix/host-modules/glue-bao-tls.nix index e7486997..27d4e202 100644 --- a/nix/host-modules/glue-bao-tls.nix +++ b/nix/host-modules/glue-bao-tls.nix @@ -204,7 +204,7 @@ in # The secret publisher's, minted here for the reason the controller's # line above gives — and it serves that case more often, not less: the - # publisher runs in AUTHELIA's container, on the one host + # publisher's unit runs in AUTHELIA's container, on the one host # guaranteed not to be this one once the store has a host of its own. [ -s ${pkiDir}/secret-publisher.pem ] || ${signLeaf} ${pkiDir} secret-publisher \ ${lib.escapeShellArg deployCfg.bao.secretPublisherCommonName} "" clientAuth diff --git a/nix/host-modules/glue-secret-publisher-bao-identity.nix b/nix/host-modules/glue-secret-publisher-bao-identity.nix index 342f0639..599ca2b1 100644 --- a/nix/host-modules/glue-secret-publisher-bao-identity.nix +++ b/nix/host-modules/glue-secret-publisher-bao-identity.nix @@ -6,7 +6,7 @@ # # ⚠️ The minting is NOT here. ./glue-bao-tls.nix holds the CA and signs the # leaf, because the thing that owns a private key owns issuing from it. What -# belongs here is the pairing: which host paths go to the publisher in +# belongs here is the pairing: which host paths go to the publisher's identity in # authelia's container. # # ⚠️ Gated on a PKI directory existing, not on the store alone — the same rule diff --git a/nix/host-modules/hive-forge/default.nix b/nix/host-modules/hive-forge/default.nix index da744469..59548c80 100644 --- a/nix/host-modules/hive-forge/default.nix +++ b/nix/host-modules/hive-forge/default.nix @@ -1201,8 +1201,8 @@ in # The forge's OIDC client secret, out of the swarm secret store under the # forge publisher's leaf — the one route, wherever authelia runs. Same # shape as ../hive-matrix.nix's `swarm-bao-matrix-oidc`: the login and the - # read both fail loudly, and `storeRetry` retries until the publisher in - # authelia's container has written the secret. + # read both fail loudly, and `storeRetry` retries until authelia's mint, + # in its container, has stored the secret. # # On the host, which reads that leaf from its own files. A host with no # publisher leaf fails here, naming the options, rather than rendering no diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index 1c048531..694ce759 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -1064,8 +1064,7 @@ in # # `Restart=on-failure` covers a sealed store or one still starting; # the timer below repeats the run, which a unit without `RemainAfterExit` allows. - # The start timeout is bounded for the reason - # ./swarm-secret-publisher.nix states: a sealed store answers on the + # The start timeout is bounded because a sealed store answers on the # port and never answers the read. systemd.services.swarm-matrix-appservice-sync = lib.mkIf ctlActive { description = "keep the swarm's appservice registration in step with the swarm secret store"; diff --git a/nix/host-modules/otel.nix b/nix/host-modules/otel.nix index 64580b22..edcc615d 100644 --- a/nix/host-modules/otel.nix +++ b/nix/host-modules/otel.nix @@ -786,8 +786,8 @@ in # This hive's OIDC client secret, out of the swarm secret store under the # hive's own leaf. Same shape as ./hive-matrix.nix's # `swarm-bao-matrix-oidc`: the login and the read both fail loudly, and - # `storeRetry` retries until the publisher in authelia's container has - # written the secret, because the collector does not start without it. + # `storeRetry` retries until authelia's mint, in its container, has + # stored the secret, because the collector does not start without it. # # The collector re-reads `client_secret_file` on every token fetch, but # the file it reads is `LoadCredential`'s copy, made at start: a changed diff --git a/nix/host-modules/swarm-authelia.nix b/nix/host-modules/swarm-authelia.nix index 9fa57198..92e0128d 100644 --- a/nix/host-modules/swarm-authelia.nix +++ b/nix/host-modules/swarm-authelia.nix @@ -212,7 +212,7 @@ let # no other collector shares it. The module requires a value. forwarderTelemetryPort = 8901; # A client this container registers and mints for itself. Its secret goes - # through the store like every other forwarder's: the publisher carries it + # through the store like every other forwarder's: the mint creates it # there and the forwarder reads it back under the same identity. forwarderClient = { id = forwarderClientId; @@ -227,8 +227,8 @@ let accessTokenSignedResponseAlg = "RS256"; }; - # The secret publisher runs in this container, beside the mint whose secrets - # it copies. It needs a store identity, and a reader is defined by holding a + # The mint runs in this container and creates its secrets in the store. It + # needs a store identity, and a reader is defined by holding a # certificate the store accepts, never by standing next to it — the rule # ./swarm-bao.nix's `deploy.bao` options block states in full. # `deploy.bao.enable` here would be the co-location assumption itself. diff --git a/nix/host-modules/swarm-bao.nix b/nix/host-modules/swarm-bao.nix index c1b0aaa2..d514b338 100644 --- a/nix/host-modules/swarm-bao.nix +++ b/nix/host-modules/swarm-bao.nix @@ -539,8 +539,8 @@ let } ''; - # The identity that copies authelia's minted OIDC client secrets into the - # store. Named outside `hive-*` for the same reason as the controller's: the + # The identity authelia's mint creates its OIDC client secrets in the store + # with. Named outside `hive-*` for the same reason as the controller's: the # controller may create policies under that prefix, and a policy it can # rewrite is not a constraint on anything. secretPublisherPolicyName = "swarm-secret-publisher"; @@ -685,7 +685,7 @@ let swarmAppserviceRegistrationLeaf = "swarm/controller/swarm-controller/matrix/appservice-registration"; # The controller's own OIDC client secret, the nix half of - # `swarm_secret_client::queue::controller_client_path`. The publisher writes + # `swarm_secret_client::queue::controller_client_path`. Authelia's mint writes # it; the controller reads it and holds no other copy. controllerClientLeaf = "swarm/controller/swarm-controller/oidc/client"; @@ -771,7 +771,7 @@ let # and read like the API key above. classifierAcpKeyLeaf = "swarm/services/review-classifier/acp-provider"; - # The UI's OIDC client secret. The publisher writes it; the granter reads it + # The UI's OIDC client secret. Authelia's mint writes it; the granter reads it # into the `oidc` auth method's config, which is the only copy bao uses. baoUiClientLeaf = "swarm/services/${cfg.ui.oidc.clientId}/oidc/client"; @@ -1672,7 +1672,7 @@ let # own and lands it in a collector's container — because that route is # proven and there is no second one worth inventing. # - # Where the publisher in authelia's container leaves it. A swarm service's + # Where authelia's mint, in its container, stores it. A swarm service's # client is registered once for the whole swarm, so its secret is one value. # The `swarm-forwarder-oidc` role's grant is this one path, so any other # answers 403 however correct it looks. @@ -1983,8 +1983,8 @@ in example = "swarm-secret-publisher.svc"; description = '' Subject the store's secret-publisher cert-auth role accepts — the - identity that copies authelia's minted OIDC client secrets into the - store so a hive that does not host authelia can read its own. + identity authelia's mint creates its OIDC client secrets in the + store with, so a hive that does not host authelia can read its own. A **second** identity rather than reuse of {option}`services.hyperhive.deploy.bao.controllerCommonName`: the diff --git a/nix/host-modules/swarm-builder.nix b/nix/host-modules/swarm-builder.nix index d98b87e5..2ab058e5 100644 --- a/nix/host-modules/swarm-builder.nix +++ b/nix/host-modules/swarm-builder.nix @@ -105,8 +105,8 @@ in description = '' The OAuth2 client id the swarm builder presents to the swarm queue. Read-only: the host running authelia registers it, the queue's - auth-callout responder grants it the build subject, and the secret - publisher carries its secret to the store, all from this one value. + auth-callout responder grants it the build subject, and + authelia's mint stores its secret in the store, all from this one value. ''; }; diff --git a/nix/host-modules/swarm-claude-login.nix b/nix/host-modules/swarm-claude-login.nix index c7d3b782..c38eff80 100644 --- a/nix/host-modules/swarm-claude-login.nix +++ b/nix/host-modules/swarm-claude-login.nix @@ -96,8 +96,8 @@ in description = '' The OAuth2 client id the claude login minter presents to the swarm queue. Read-only: the host running authelia registers it, the queue's - auth-callout responder grants it the login subject, and the secret - publisher carries its secret to the store, all from this one value. + auth-callout responder grants it the login subject, and + authelia's mint stores its secret in the store, all from this one value. ''; }; diff --git a/nix/host-modules/swarm-grafana.nix b/nix/host-modules/swarm-grafana.nix index ee1b864f..eb2bbbaf 100644 --- a/nix/host-modules/swarm-grafana.nix +++ b/nix/host-modules/swarm-grafana.nix @@ -351,7 +351,7 @@ let "/var/lib/grafana-metrics/bearer" ]; - # Where the publisher in authelia's container leaves this client's secret. A + # Where authelia's mint, in its container, stores this client's secret. A # swarm service's client is registered once for the whole swarm, so its # secret is one value and not one per hive. Both ends compose this from the # same swarm-wide client id, so a rename cannot leave one of them behind. @@ -719,8 +719,8 @@ in ++ map (p: "r ${p}") legacyHostSecretPaths; # THE delivery unit — one route, in every deployment. The secret authelia - # minted arrives out of the swarm secret store, which the publisher in - # authelia's container wrote it into, and that is true whether authelia is + # minted arrives out of the swarm secret store, which authelia's mint, + # in its container, wrote it into, and that is true whether authelia is # a network away or in the container next door. # # 🩸 No second unit copies the plaintext out of authelia's tree @@ -737,7 +737,7 @@ in # there" into a value. # # ⚠️ An ABSENT secret is "not published yet", not a fault of this host's. - # The publisher runs in authelia's container and authelia mints on its + # The mint runs in authelia's container and authelia mints on its # first boot, so early in a swarm's life there is legitimately nothing to # read. # Nothing here writes a stand-in: there is no such thing as a locally valid diff --git a/nix/host-modules/swarm-notify-router.nix b/nix/host-modules/swarm-notify-router.nix index 06e8d492..83e43692 100644 --- a/nix/host-modules/swarm-notify-router.nix +++ b/nix/host-modules/swarm-notify-router.nix @@ -85,8 +85,8 @@ in description = '' The OAuth2 client id the notification router presents to the swarm queue. Read-only: the host running authelia registers it, the queue's - auth-callout responder grants it the router's subjects, and the secret - publisher carries its secret to the store, all from this one value. + auth-callout responder grants it the router's subjects, and + authelia's mint stores its secret in the store, all from this one value. ''; }; diff --git a/nix/host-modules/swarm-otel.nix b/nix/host-modules/swarm-otel.nix index 58982a00..31063e98 100644 --- a/nix/host-modules/swarm-otel.nix +++ b/nix/host-modules/swarm-otel.nix @@ -261,7 +261,7 @@ let # regression rather than a choice anyone made. hiveReaderIdentity = baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null; - # Where the publisher in authelia's container leaves this client's secret — + # Where authelia's mint, in its container, stores this client's secret — # composed from the same swarm-wide `clientId` the registration in # ./glue-swarm-otel-oidc-client.nix uses, so a rename cannot leave one of # them behind. The same prefix ./swarm-grafana.nix reads its own client @@ -554,8 +554,8 @@ in # ./swarm-grafana.nix has for its own client. # THE delivery unit — one route, in every deployment. The secret authelia - # minted arrives out of the swarm secret store, which the publisher in - # authelia's container wrote it into, whether authelia is a network away or + # minted arrives out of the swarm secret store, which authelia's mint, + # in its container, wrote it into, whether authelia is a network away or # in the container next door. # # 🩸 No unit here copies the plaintext directly out of authelia's diff --git a/nix/host-modules/swarm-review-classifier.nix b/nix/host-modules/swarm-review-classifier.nix index 02a110a1..05ccd87f 100644 --- a/nix/host-modules/swarm-review-classifier.nix +++ b/nix/host-modules/swarm-review-classifier.nix @@ -119,8 +119,8 @@ in description = '' The OAuth2 client id the review classifier presents to the swarm queue. Read-only: the host running authelia registers it, the queue's - auth-callout responder grants it the try-out subject, and the secret - publisher carries its secret to the store, all from this one value. + auth-callout responder grants it the try-out subject, and + authelia's mint stores its secret in the store, all from this one value. ''; }; diff --git a/nix/module-eval/bao-grants.nix b/nix/module-eval/bao-grants.nix index 2d6a7047..9b56c63d 100644 --- a/nix/module-eval/bao-grants.nix +++ b/nix/module-eval/bao-grants.nix @@ -2417,7 +2417,7 @@ let && !(lib.hasInfix "appservice-registration" baoGrantHere.systemd.services.swarm-bao-controller-policy.script); } { - # The controller's own OIDC client secret, which the publisher writes and + # The controller's own OIDC client secret, which authelia's mint writes and # the controller reads at start. Pinned as the whole stanza, so an added # capability fails. name = "the controller reads its own client secret and cannot write it"; diff --git a/nix/module-eval/bao-otel-collector.nix b/nix/module-eval/bao-otel-collector.nix index f0edb1ee..ddae6680 100644 --- a/nix/module-eval/bao-otel-collector.nix +++ b/nix/module-eval/bao-otel-collector.nix @@ -421,7 +421,7 @@ let # for: the reader's grant is one path under `services`, so a secret # filed under the hive that happens to run the store would be refused # rather than missing, however correct the path reads. - name = "the forwarder's secret is read from the prefix the publisher writes"; + name = "the forwarder's secret is read from the prefix the mint writes"; ok = let s = baoWithCollector.systemd.services.swarm-bao-forwarder-oidc.script; diff --git a/nix/module-eval/grafana.nix b/nix/module-eval/grafana.nix index 617ffad7..783df8bf 100644 --- a/nix/module-eval/grafana.nix +++ b/nix/module-eval/grafana.nix @@ -315,7 +315,7 @@ let # refused rather than empty, however correct it reads. The negative arm is # the rename this is exposed to — a secret filed under the hive that runs # the service instead of under the service itself. - name = "grafana's OIDC secret is read from the prefix the publisher writes"; + name = "grafana's OIDC secret is read from the prefix the mint writes"; ok = let s = grafanaRemoteAuthelia.systemd.services.swarm-bao-grafana-oidc.script; diff --git a/nix/module-eval/swarm-otel-core.nix b/nix/module-eval/swarm-otel-core.nix index 5662d5a3..b122664e 100644 --- a/nix/module-eval/swarm-otel-core.nix +++ b/nix/module-eval/swarm-otel-core.nix @@ -125,7 +125,7 @@ let # Same 403-not-a-miss reason as grafana's arm above: the reader's grant # covers the `services` prefix, so a path outside it is refused rather # than empty, however correct it reads. - name = "the collector's OIDC secret is read from the prefix the publisher writes"; + name = "the collector's OIDC secret is read from the prefix the mint writes"; ok = let s = otelBaoRemoteAuthelia.systemd.services.swarm-bao-otel-oidc.script; diff --git a/swarm-nats-auth/src/oidc_secret.rs b/swarm-nats-auth/src/oidc_secret.rs index c31c7270..3f2ca1c3 100644 --- a/swarm-nats-auth/src/oidc_secret.rs +++ b/swarm-nats-auth/src/oidc_secret.rs @@ -2,8 +2,8 @@ //! with. Read from the secret store as the responder starts and held in //! memory, never in a file, `argv` or the environment. //! -//! The secret can change under a running responder: the publisher in authelia's -//! container re-publishes it when it is re-minted. So when the `IdP` refuses an +//! The secret can change under a running responder: authelia's mint, in its +//! container, writes a new one when it re-mints. So when the `IdP` refuses an //! introspection as a credential (a 400 or 401), the secret is read from the //! store again ([`StoredSecret::after_refusal`]) and, when it changed, the //! introspection is tried once more. Both fit in the one request's @@ -36,9 +36,9 @@ pub fn path(client_id: &str) -> Result { Ok(format!("{prefix}/oidc/client")) } -/// The secret at `path`, with surrounding whitespace trimmed: the publisher -/// stores the minted file as is, and a trailing newline is not part of the -/// secret. Errors name the path, never the value. +/// The secret at `path`, with surrounding whitespace trimmed: an earlier +/// release stored the minted file as is, and a trailing newline is not part of +/// the secret. Errors name the path, never the value. /// /// # Errors /// When the store cannot be read, or holds nothing or only whitespace there. diff --git a/swarm-secret-client/src/builder.rs b/swarm-secret-client/src/builder.rs index 1151f7d7..d573400b 100644 --- a/swarm-secret-client/src/builder.rs +++ b/swarm-secret-client/src/builder.rs @@ -66,7 +66,7 @@ pub fn client_secret_path(client_id: &str) -> Result { /// No `Debug`: `value` authenticates the builder at the queue. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ClientSecret { - /// The secret, under the field name the publisher writes. + /// The secret, under the field name authelia's mint writes. pub value: String, } diff --git a/swarm-secret-client/src/ci_metrics.rs b/swarm-secret-client/src/ci_metrics.rs index f2d095aa..29097b91 100644 --- a/swarm-secret-client/src/ci_metrics.rs +++ b/swarm-secret-client/src/ci_metrics.rs @@ -41,7 +41,7 @@ pub fn client_secret_path(client_id: &str) -> Result { /// No `Debug`: `value` authenticates the poller at the collector. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ClientSecret { - /// The secret, under the field name the publisher writes. + /// The secret, under the field name authelia's mint writes. pub value: String, } diff --git a/swarm-secret-client/src/queue.rs b/swarm-secret-client/src/queue.rs index 70e78744..53a63ba9 100644 --- a/swarm-secret-client/src/queue.rs +++ b/swarm-secret-client/src/queue.rs @@ -119,8 +119,8 @@ pub struct AgentCredential { mod tests { use super::*; - /// Spelled out in full because `swarm-secret-publisher.nix` and - /// `swarm-bao.nix` write the same string by hand. + /// Spelled out in full because the path layout in `swarm-secret-publisher.nix` + /// and `swarm-bao.nix` is written out by hand there too. #[test] fn the_controller_client_lands_under_the_controller() { assert_eq!( @@ -147,8 +147,9 @@ mod tests { assert!(reads(&own), "{own} should be readable under {granted:?}"); } - /// Spelled out in full because `swarm-secret-publisher.nix` writes the - /// same string by hand. + /// Spelled out in full because the path layout in + /// `swarm-secret-publisher.nix`, where authelia's mint takes it from, is + /// written out by hand there too. #[test] fn a_hives_own_client_lands_under_its_own_principal_prefix() { assert_eq!( diff --git a/swarm-secret-client/src/review_classifier.rs b/swarm-secret-client/src/review_classifier.rs index 7c6a0b54..bcb5ac6d 100644 --- a/swarm-secret-client/src/review_classifier.rs +++ b/swarm-secret-client/src/review_classifier.rs @@ -74,7 +74,7 @@ pub fn client_secret_path(client_id: &str) -> Result { /// No `Debug`: `value` authenticates the classifier at the queue. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ClientSecret { - /// The secret, under the field name the publisher writes. + /// The secret, under the field name authelia's mint writes. pub value: String, } diff --git a/swarm-secret-client/src/stored_secret.rs b/swarm-secret-client/src/stored_secret.rs index 51a4ee3f..d4f51b47 100644 --- a/swarm-secret-client/src/stored_secret.rs +++ b/swarm-secret-client/src/stored_secret.rs @@ -1,8 +1,8 @@ //! A client secret held in memory and read again from where it is kept when //! the `IdP` refuses it. //! -//! The secret can change under a running process: the publisher in authelia's -//! container re-publishes it when it is re-minted. A refusal asks for a re-read +//! The secret can change under a running process: authelia's mint, in its +//! container, writes a new one when it re-mints. A refusal asks for a re-read //! ([`StoredSecret::after_refusal`]); when the read lands a different secret, //! the caller tries once more with it. One re-read runs at a time, and a //! refusal while one is running waits for it rather than starting another.