diff --git a/docs/swarm/ca.md b/docs/swarm/ca.md index 23182dc4..9d176946 100644 --- a/docs/swarm/ca.md +++ b/docs/swarm/ca.md @@ -78,15 +78,51 @@ on. ## Adopting the hierarchy on an existing hive -An existing `ca.pem` is never re-rooted automatically — swapping it -would break every consumer that already trusts it, and agents only pick -up new trust when their container restarts. To adopt, delete `ca.pem` + -`ca-key.pem` under `tls.stateDir` and restart `hive-tls-ca.service`; -the CA is re-issued under the root and the leaf re-signed. Until then -the hive serves TLS exactly as before and is simply not part of the -swarm's trust hierarchy. +A hive that predates the swarm root carries a self-signed `ca.pem`, and +adopting the hierarchy means replacing it. That invalidates an anchor +consumers already trust, and they refresh on their own schedule — agents +only pick up new trust when their container restarts, peers only on +their own rebuild. **Who is allowed to decide that is what splits the +two cases.** -Making that adoption a first-class, non-disruptive operation — rather -than a documented `rm` — is tracked separately; the mechanism it needs -(carrying the previous CA in the trust bundle across the overlap) -already exists. +### Where this host owns the root (`autoConfigure`) + +Adoption happens by itself, once. `hive-tls-ca.service` notices that +`ca.pem` does not chain to the root, keeps the old certificate as +`ca-previous.pem`, and re-issues under the root; the next leaf is signed +by the new CA. + +It is safe to automate here precisely because this is the +all-on-one-host shape: every consumer is on this box, so "when will they +have refreshed" is knowable rather than guessed. + +The old CA stays in `trust-bundle.pem` afterwards, so adoption is +**additive to the anchor set before it is subtractive** — a container +that has not restarted yet still validates. Removing `ca-previous.pem` +is a deliberate later step: how long is long enough is a property of the +deployment, not something the unit can know. + +A marker file (`.swarm-ca-adopted`) records that this ran. Its *absence* +is the trigger, so adoption fires once per hive rather than being +re-decided on every activation. + +### Everywhere else + +No automatic adoption. `hive-tls-ca.service` fails, loudly, naming both +certificates and giving the two-command recipe: + +``` +rm /ca.pem /ca-key.pem +systemctl restart hive-tls-ca.service +``` + +Failing rather than warning is deliberate: a hive whose CA does not +chain to the root it has been given is misconfigured, and a warning in a +build log is not something anyone reads twice. + +To keep the current CA on purpose — a hive that deliberately stays +outside the hierarchy, or one mid-migration — `touch` the marker file +named in the message. That is a decision, and it is recorded as one. + +A hive with **no** root configured at all is not affected by any of +this: it self-signs exactly as it always has.