swarm-ca: state the store-is-world-readable rule once, not three times

`docs/swarm/ca.md` said it under *Constraints on the material* and again
under *Distributing the root*; this module's header said it a third time,
directly above a line already pointing at that doc.

Measured: 6-gram intersection between the module's comments and the doc,
32 -> 6. The sentence now appears once in the tree.

Module header keeps what a reader editing this file cannot see from the
config: that one root makes cross-hive trust O(1), that the two
provisioning modes differ only in who writes the artifacts, and the ⚠️
that both root key and root cert are runtime files — the cert as a
consequence, and that one costs something real, since nothing whose trust
store is built at build time can name it. Everything behind those is a
`docs/x.md::Section` pointer with the heading checked to exist.

Dropped the O(n²)-per-peer-pinning story: the live reason is that one root
is O(1), and how it used to be configured is history.

In the doc, *Distributing the root* now links to *Constraints on the
material* rather than restating it. Intra-doc `#anchor` links are already
the convention there — 85 of them across `docs/`, 8 in `gateway.md` alone.

Comments + one doc paragraph; no behaviour change. Refs #3901.
This commit is contained in:
atlas 2026-09-02 05:36:42 +02:00 committed by mara
commit 83bbd7a5ea
2 changed files with 13 additions and 28 deletions

View file

@ -154,9 +154,8 @@ this: it self-signs exactly as it always has.
## Distributing the root ## Distributing the root
The root **key** is a runtime file for an obvious reason: the nix store The root **key** is a runtime file for the reason in
is world-readable and content-addressed, so a key committed to a flake [Constraints on the material](#constraints-on-the-material).
is a key *published* to every consumer of that flake.
The root **certificate** is a runtime file as a *consequence* — it lives The root **certificate** is a runtime file as a *consequence* — it lives
beside the key under `swarm.ca.stateDir` — and that has a cost worth beside the key under `swarm.ca.stateDir` — and that has a cost worth

View file

@ -1,33 +1,19 @@
# The swarm root CA: the anchor a whole swarm shares, and the issuer of # The swarm root CA: the anchor a whole swarm shares, and the issuer of
# each hive's own CA (which is where it gets used — see ./hive-tls.nix). # each hive's own CA (which is where it gets used — see ./hive-tls.nix).
# #
# Why a hierarchy at all: cross-hive trust used to be hand-pinned per # One root rather than per-peer pinning, because cross-hive trust is then
# peer, so every hive had to name every other one — O(n²) configuration # O(1): trust the root once and every present *and future* peer validates,
# that a new hive could only join by editing all the others. One root # instead of every hive having to name every other one.
# makes it O(1): trust the root once and every present *and future* peer
# validates. The per-peer CA field is gone precisely because this
# replaced it.
# #
# Two provisioning modes, ONE structure — what differs is who puts the # Two provisioning modes share ONE structure — what differs is who puts
# artifacts on disk, never what the artifacts are: # the artifacts on disk, never what the artifacts are. Which mode does
# what, and what moving between them costs:
# `docs/swarm/ca.md::Two provisioning modes, one structure`.
# #
# - autoconfigured (`services.hyperhive.deploy.singleHostSwarm`, or # ⚠️ Root key AND root cert are runtime files, never nix options. The key
# `autoConfigure` set directly): the unit below generates the root # for the obvious reason; the cert as a consequence, and that one costs
# here on first boot. # something real — nothing whose trust store is built at build time can
# - operator-provided (multi-host): the operator installs the root cert # name it: `docs/swarm/ca.md::Distributing the root`.
# — and, on a host that does not hold the root key, the hive CA too —
# into the state dirs, and this unit does nothing. Splitting a
# single-host swarm across hosts is then a matter of moving the
# service dirs and turning `autoConfigure` off, not of a second code
# path that has to be kept agreeing with the first.
#
# The root KEY is the reason this is a runtime file and not a nix option:
# the store is world-readable and content-addressed, so a key committed
# to a flake is a key *published* to every consumer of that flake.
#
# ⚠️ The root CERT is therefore a runtime file too, which costs something:
# nothing whose trust store is built at build time can name it. See
# docs/swarm/ca.md § "Distributing the root".
{ {
lib, lib,
config, config,