swarm-secret-publish and its path unit now run inside authelia's container, beside the mint, and read each client secret at the path authelia writes it. The host unit and host path unit, which read the secrets through the container's root on the host, are gone, and so is deploy.authelia.hostClientSecretDir, which only they read. The publisher keeps its store identity, the secret-publisher leaf. The host hands the leaf and the store's CA into the container as nspawn system credentials, and the unit loads them; where this host mints the leaf, the container waits for swarm-bao-pki. Authelia does not wait for the publisher, which retries every 30 seconds while the store is down. The container also runs the journal forwarder the other service containers run, pushing to a receiver of its own on the swarm collector (serviceProducers swarm-authelia) as a new machine OIDC client (swarm.authelia.otel.clientId) that authelia registers for itself and the publisher carries to the store. The fetch unit reads it back under the publisher's leaf, also handed to it as a system credential, so the swarm-secret-publisher policy gains read on that one leaf; its stanza keeps create and update, which the exact path would otherwise take from the services/* prefix. Without the leaf the forwarder is off. The container drops --link-journal=host, and the host collector stops reading it. The services' "nothing at <path>" errors name the publisher in authelia's container.
41 lines
1.7 KiB
Nix
41 lines
1.7 KiB
Nix
# Glue: point the secret publisher at the bao leaf minted for it.
|
|
#
|
|
# ONE PAIRING PER FILE — publisher ← bao, and nothing else. Deleting this
|
|
# leaves a publisher that takes operator-provided certificate paths, which is
|
|
# what any deployment not minting its own already does.
|
|
#
|
|
# ⚠️ 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
|
|
# authelia's container.
|
|
#
|
|
# ⚠️ Gated on the leaf existing, not on the store being enabled — the same rule
|
|
# ./glue-controller-bao-identity.nix states. A publisher on the store's own
|
|
# host is one deployment; a publisher beside a remote authelia holding a leaf
|
|
# issued out of band is another, and both want this wiring.
|
|
#
|
|
# Everything is `mkDefault`. An operator naming their own paths wins.
|
|
{
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
let
|
|
hyperhiveCfg = config.services.hyperhive;
|
|
deployCfg = hyperhiveCfg.deploy;
|
|
baoDeploy = deployCfg.bao;
|
|
|
|
# Where ./glue-bao-tls.nix puts the leaves, derived from the reader's own
|
|
# path rather than repeating that file's directory literal: an operator who
|
|
# moves the PKI moves both, and the two cannot drift apart.
|
|
haveMintedPki = baoDeploy.clientCertFile != null;
|
|
pkiDir = if haveMintedPki then builtins.dirOf baoDeploy.clientCertFile else null;
|
|
in
|
|
{
|
|
config = lib.mkIf (deployCfg.swarm-secret-publisher.enable && haveMintedPki) {
|
|
services.hyperhive.deploy.swarm-secret-publisher = {
|
|
baoClientCertFile = lib.mkDefault "${pkiDir}/secret-publisher.pem";
|
|
baoClientKeyFile = lib.mkDefault "${pkiDir}/secret-publisher-key.pem";
|
|
};
|
|
};
|
|
}
|