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.
This commit is contained in:
parent
05665c05f3
commit
2fc63d844b
24 changed files with 52 additions and 52 deletions
|
|
@ -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/<hive>/oidc/client`, which the publisher in authelia's container
|
||||
`swarm/hives/<hive>/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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<String> {
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ pub fn client_secret_path(client_id: &str) -> Result<String, Error> {
|
|||
/// 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,
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue