fix(#3349): point the swarm-queue client at the hive's trust bundle

The queue client built a bare reqwest::Client, so it trusted only the
platform roots. Against a swarm whose authelia is signed by the swarm
CA that is fatal: minting a token dies with 'invalid peer certificate:
UnknownIssuer', inside the auth callback, on a four-second retry loop,
with the queue never connecting.

The anchor was never missing. hive-tls.nix assembles trust-bundle.pem
and already hands it to hive-c0re as HIVE_TLS_CA_PATH; nothing pointed
the queue client at it.

QueueConfig gains an optional ca_file from <prefix>_OIDC_CA_FILE, read
outside the all-or-none tuple on purpose: a CA path with no queue is
meaningless rather than half-configured, and requiring it would break a
swarm fronted by a public certificate in order to fix one that is not.
add_root_certificate extends the default roots rather than replacing
them, so both deployments work.

A bad path fails loudly instead of falling back to the platform roots.
An operator who names a CA file wants that anchor; a silent fallback
turns their typo into UnknownIssuer five layers away.

hive-tls.nix names the bundle for both clients, beside the line that
already does it for hive-c0re, rather than having each consumer
re-derive the path.
This commit is contained in:
atlas 2026-08-16 20:45:51 +02:00 committed by mara
commit ef9339da16
2 changed files with 85 additions and 4 deletions

View file

@ -563,5 +563,27 @@ in
# spelled out where the bundle is written above; no key path is ever
# exposed (an agent that could read one could mint trusted certs).
systemd.services.hive-c0re.environment.HIVE_TLS_CA_PATH = "${cfg.stateDir}/trust-bundle.pem";
# The same anchor, named for the swarm-queue clients that need it when
# they mint a token from authelia over TLS. Declared HERE, beside the
# bundle, rather than in each consumer's module: the path is this
# module's fact, and two consumers re-deriving `${stateDir}/…` would be
# two places to fix the day it moves.
#
# ⚠️ This is what was missing. `swarm-queue-client` built a bare
# `reqwest::Client`, so it trusted only the platform roots and died at
# `invalid peer certificate: UnknownIssuer` against a swarm whose
# authelia is signed by the swarm CA — while this very bundle sat on
# disk, already assembled, already handed to hive-c0re under a different
# variable name. The anchor was never missing; nothing pointed the queue
# client at it.
#
# Set unconditionally within this module's `active` guard, exactly like
# the line above: where there is no hive CA this module contributes
# nothing at all, and the clients then fall back to the platform roots —
# which is correct for a swarm fronted by a public certificate.
systemd.services.hive-c0re.environment.HIVE_C0RE_OIDC_CA_FILE = "${cfg.stateDir}/trust-bundle.pem";
systemd.services.swarm-controller.environment.SWARM_CONTROLLER_OIDC_CA_FILE =
"${cfg.stateDir}/trust-bundle.pem";
};
}