wire swarm-authelia-bridge: systemd unit, oidc client, controller auth env

This commit is contained in:
damocles 2026-08-16 21:59:02 +02:00 committed by mara
commit c1eb6b9834
4 changed files with 215 additions and 37 deletions

View file

@ -87,6 +87,14 @@ let
SWARM_CONTROLLER_FORGE_TOKEN_FILE = "%d/forge-token";
};
# Not a secret to deliver — `swarm-authelia-bridge`'s own bearer check
# is satisfied by THIS daemon's existing queue OIDC identity
# (`queueEnv` above): "one identity per principal" already covers this,
# so there is nothing new to mint or copy, just the bridge's address.
authBridgeEnv = lib.optionalAttrs (cfg.authBridgeUrl != null) {
SWARM_CONTROLLER_AUTH_BRIDGE_URL = cfg.authBridgeUrl;
};
# Wrapped rather than documented: every one of these values is derived
# from an option this deployment already set, so making the operator
# re-supply them on the command line would be asking them to repeat the
@ -325,6 +333,30 @@ in
graceful-absence shape the queue coordinates already use.
'';
};
authBridgeUrl = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = if autheliaCfg.enable then autheliaCfg.bridgeUrl else null;
defaultText = lib.literalExpression ''
authelia's own `bridgeUrl` when this host also runs
`swarm-authelia`, else null
'';
example = "http://127.0.0.1:9092";
description = ''
Where `swarm-authelia-bridge` (the only writer of authelia's
users database) answers see that option's own doc comment for
the cross-host caveat, since this default is only correct when
this host also runs `swarm-authelia`.
No new credential to configure: the bearer token presented to
the bridge is minted from THIS daemon's own existing queue OIDC
identity (`queue.*` above) "one identity per principal"
already covers it. `null` means no agent-identity support:
`CreateIdentity` jobs fail with a clear "no auth bridge
configured here" error rather than the daemon refusing to
start, the same graceful-absence shape `forgeTokenFile` uses.
'';
};
};
config = lib.mkIf (config.services.hyperhive.enable && cfg.enable) {
@ -480,15 +512,16 @@ in
];
};
# Queue coordinates (`queueEnv`) and forge coordinates (`forgeEnv`)
# merge in last. The daemon refuses a PARTIAL set of either rather
# than treating it as absent, which is why each is built as one
# attrset and never assigned individually.
# Queue coordinates (`queueEnv`), forge coordinates (`forgeEnv`), and
# the auth-bridge address (`authBridgeEnv`) merge in last. The
# daemon refuses a PARTIAL set of any of them rather than treating
# it as absent, which is why each is built as one attrset and never
# assigned individually.
#
# They differ in how absence is prevented: the queue's is checked by
# the assertions above, because a controller without a queue is
# broken rather than lighter; the forge's is genuinely optional and
# stays gated on `forgeTokenFile` resolving.
# broken rather than lighter; forge's and the auth bridge's are
# genuinely optional and stay gated on their own option resolving.
environment = {
SWARM_CONTROLLER_SOCKET = cfg.socketPath;
# The swarm's hive directory, JSON-encoded — the full directory
@ -514,7 +547,8 @@ in
SWARM_CONTROLLER_STALE_AFTER_SECS = toString cfg.staleAfterSeconds;
}
// queueEnv
// forgeEnv;
// forgeEnv
// authBridgeEnv;
};
# A systemd credential is a SNAPSHOT: it is materialised into `%d` once,