docs: trim the trustBundle comment under the 30-line lint

Keeps the three constraints a reader cannot derive; the reasoning behind
them lives in the PR.
This commit is contained in:
atlas 2026-08-17 19:45:06 +02:00 committed by mara
commit e7a5e93bbc

View file

@ -63,46 +63,25 @@ in
requires = [ "hive-tls-ca.service" ]; requires = [ "hive-tls-ca.service" ];
}; };
# Assemble system CAs + the hive CA into one bundle, for runtimes whose # System CAs + hive CA in one bundle, with `SSL_CERT_FILE` set on each
# trust variable *replaces* the default store (Go's `SSL_CERT_FILE`, # consumer — for runtimes whose trust variable *replaces* the store (Go,
# rustls-native-certs) rather than adding to it — pointing those at # rustls-native-certs). An additive one (Node's `NODE_EXTRA_CA_CERTS`,
# `caContainerPath` alone would drop every public anchor. # hive-ci) needs no bundle and should not use this.
# #
# The header above says consumption stays at the call site, and the *env # imports = [ (caTrust.trustBundle { inherit pkgs; name = "swarm-nats";
# var* still does. The assembly does not: four containers were each # consumers = [ "swarm-nats-auth" ]; }) ];
# hand-rolling this concat, which is how they came to share one defect —
# `wantedBy` + `before` express ordering but not success, so a failed
# assembly let the consumer start against a missing file and end up
# trusting **nothing**, which fails every outbound TLS call while the unit
# looks healthy.
# #
# Two things this does that a hand-rolled version kept getting wrong: # Three constraints, each earned:
# - `requires` on the CONSUMER, so a failed bundle stops it — and the # - `requires` on the CONSUMER: `before` orders but does not gate, so a
# dependency is visible in `systemctl status <consumer>`, where someone # failed assembly otherwise leaves it running and trusting *nothing*.
# debugging a TLS failure actually looks. # - assemble to a temp path, verify, then move: `cat` of an empty bind
# - assemble to a temp path, check the result is non-empty and actually # exits 0, and a partial bundle must never appear under the final name.
# contains a certificate, and only then move it into place. `cat` of an # - `consumers` are BARE unit names — they are `systemd.services` keys
# empty bind exits 0, so `set -e` alone does not catch it, and a partial # (no suffix) *and* go in `before`/`requires` (suffixed). Reversed, the
# bundle must never appear under the final name. # edge names a unit that does not exist and systemd orders nothing.
# #
# Returns a MODULE to import inside the container, not an attrset to splice # Returns a module, not bare services: a caller already writing
# in — same shape as `swarm-container-resolver.nix`, and for a concrete # `systemd.services.<consumer>` cannot also write `systemd.services`.
# reason: a caller that already writes `systemd.services.<consumer> = …`
# cannot also write `systemd.services = …` in the same attrset, so anything
# returning bare services forces the call site to be restructured.
#
# imports = [ (caTrust.trustBundle { inherit pkgs; name = "swarm-nats"; consumers = [ "swarm-nats-auth" ]; }) ];
#
# It sets `SSL_CERT_FILE` on each consumer itself. That is the right default
# for this helper's audience — runtimes whose trust variable *replaces* the
# store. A runtime with an additive variable (Node's `NODE_EXTRA_CA_CERTS`,
# hive-ci) needs no bundle at all and should not use this.
#
# `consumers` are BARE unit names (no `.service`): they are used both as
# `systemd.services` attribute keys, which must not carry the suffix, and
# inside `before`/`requires`, which must. Getting that backwards produces an
# edge to a unit that does not exist — which systemd accepts in silence,
# ordering nothing.
trustBundle = trustBundle =
{ {
name, name,