swarm-nats: require the responder's store identity, and drop its no-store mode
The responder reads the callout xkey before it connects, so a responder with no secret store no longer starts, and its "deny every agent token, serve OIDC" mode could not run. That mode is gone: `agent_token::Store` is built from the settings the xkey load already read, and `authorize` takes a source rather than an `Option` of one. On the nix side, `deploy.nats.authBaoClientCertFile` and `authBaoClientKeyFile` are now asserted at eval when the queue is enabled. The units' no-identity branches, the copy unit's empty-file fallback and its "denies agent tokens" message are removed; an absent leaf file fails `swarm-nats-auth-secrets` like an absent seed does.
This commit is contained in:
parent
9a241a1df1
commit
52c931c3a7
5 changed files with 193 additions and 248 deletions
|
|
@ -82,6 +82,12 @@ let
|
|||
|
||||
responderOf = h: h.containers.swarm-nats.config.systemd.services.swarm-nats-auth;
|
||||
|
||||
refusedWithoutIdentity =
|
||||
m:
|
||||
lib.any (
|
||||
a: !a.assertion && lib.hasInfix "deploy.nats.authBaoClientCertFile and" a.message
|
||||
) m.assertions;
|
||||
|
||||
# A hive running NOTHING of the swarm's own services — no IdP here, no
|
||||
# `swarm.authelia.url` set by hand. The whole point of the fixture is what it
|
||||
# does *not* say: no IdP address is given and none is derived from
|
||||
|
|
@ -91,6 +97,17 @@ let
|
|||
autheliaColocated = hive { deploy.authelia.enable = true; };
|
||||
|
||||
cases = [
|
||||
{
|
||||
# The xkey and the responder's OIDC client secret are read only from
|
||||
# the store, so a queue with no responder leaf cannot start. Refused at
|
||||
# eval; the controls are a leaf named by hand and the store host's
|
||||
# minted one.
|
||||
name = "a queue with no responder store identity is refused at eval, one with a leaf is not";
|
||||
ok =
|
||||
refusedWithoutIdentity natsOldPath
|
||||
&& !(refusedWithoutIdentity natsWithStoreIdentity)
|
||||
&& !(refusedWithoutIdentity natsOnStoreHost);
|
||||
}
|
||||
{
|
||||
# Reads the RENDERED settings, not the option: `calloutBlocks {…} // {
|
||||
# … }` is a shallow merge, and a future edit that dropped or shadowed
|
||||
|
|
@ -182,17 +199,6 @@ let
|
|||
&& !(lib.hasInfix "exit 0" s)
|
||||
&& u.serviceConfig.Restart == "on-failure";
|
||||
}
|
||||
{
|
||||
name = "a queue host with no responder leaf renders an xkey fetch that fails naming the options";
|
||||
ok =
|
||||
let
|
||||
u = natsOldPath.systemd.services.swarm-bao-nats-callout-xkey;
|
||||
in
|
||||
!(u.environment ? BAO_CLIENT_CERT)
|
||||
&& lib.hasInfix "deploy.nats.authBaoClientCertFile" u.script
|
||||
&& lib.hasInfix "exit 1" u.script
|
||||
&& !(lib.hasInfix "ensure-xkey" u.script);
|
||||
}
|
||||
{
|
||||
# Its creates are what the responder's role was granted; on the store's
|
||||
# host the role's unit has to have run first.
|
||||
|
|
@ -281,16 +287,16 @@ let
|
|||
&& lib.hasPrefix "https://" u.environment.BAO_ADDR;
|
||||
}
|
||||
{
|
||||
# An absent leaf must not stop the responder's agent-token path: it is
|
||||
# delivered empty, beside the two seeds.
|
||||
name = "the copy unit delivers the store identity, and an absent one as an empty file";
|
||||
# Copied as the seeds are, so an absent leaf fails the unit rather than
|
||||
# reaching the responder as a file it cannot log in with.
|
||||
name = "the copy unit delivers the store identity beside the two seeds, and nothing in its place when absent";
|
||||
ok =
|
||||
let
|
||||
s = natsWithStoreIdentity.systemd.services.swarm-nats-auth-secrets.script;
|
||||
in
|
||||
lib.hasInfix "install -m 0400 /etc/pki/nats-auth.pem " s
|
||||
&& lib.hasInfix "install -m 0400 /etc/pki/nats-auth-key.pem " s
|
||||
&& lib.hasInfix "install -m 0400 /dev/null " s
|
||||
&& !(lib.hasInfix "/dev/null" s)
|
||||
&& lib.hasInfix "callout-user.seed" s
|
||||
&& lib.hasInfix "issuer.seed" s;
|
||||
}
|
||||
|
|
@ -318,31 +324,6 @@ let
|
|||
&& !(lib.hasInfix "oidc-client" copy)
|
||||
&& !(lib.hasInfix "authelia" copy);
|
||||
}
|
||||
{
|
||||
# No responder leaf is a responder with no OIDC secret, which refuses
|
||||
# every client. The unit still renders, and fails naming the options.
|
||||
name = "a queue host with no responder leaf renders a secret fetch that fails naming the options";
|
||||
ok =
|
||||
let
|
||||
fetch = natsOldPath.systemd.services.swarm-bao-nats-auth-oidc;
|
||||
in
|
||||
!(fetch.environment ? BAO_CLIENT_CERT)
|
||||
&& lib.hasInfix "deploy.nats.authBaoClientCertFile" fetch.script
|
||||
&& lib.hasInfix "exit 1" fetch.script
|
||||
&& !(lib.hasInfix "bao login" fetch.script);
|
||||
}
|
||||
{
|
||||
# The control: no identity, no store wiring, and the responder's
|
||||
# credentials are exactly the three it cannot run without.
|
||||
name = "a responder with no store identity is not pointed at a store";
|
||||
ok =
|
||||
let
|
||||
u = responderOf natsOldPath;
|
||||
in
|
||||
!(u.environment ? BAO_ADDR)
|
||||
&& !(u.environment ? BAO_CLIENT_CERT)
|
||||
&& lib.length u.serviceConfig.LoadCredential == 3;
|
||||
}
|
||||
{
|
||||
# On the store's host the fetch logs in under the responder's leaf, so it
|
||||
# waits for the unit writing that role.
|
||||
|
|
|
|||
Loading…
Reference in a new issue