diff --git a/nix/host-modules/hive-tls.nix b/nix/host-modules/hive-tls.nix index 8f785282..553e5251 100644 --- a/nix/host-modules/hive-tls.nix +++ b/nix/host-modules/hive-tls.nix @@ -322,38 +322,24 @@ in fi # --- Trust bundle: what a consumer must TRUST, as opposed to - # `ca.pem`, which is what this host SIGNS with. The two were the - # same file while the hive CA was self-signed, and stopped being - # the same file the moment it became an intermediate: openssl - # refuses to end a chain at a trusted cert that isn't - # self-signed (that's what `-partial_chain` is for), so an - # agent's curl handed only `ca.pem` fails with "unable to get - # issuer certificate". Verified in both directions before this - # was written — rustls and Go accept a trusted intermediate, - # which is what makes the breakage partial and easy to miss. + # `ca.pem`, which is what this host SIGNS with. Why they stopped + # being the same file, and why `ca-previous.pem` stays in the set + # after an adoption, are in docs/swarm/ca.md. Three constraints + # the code cannot state: # - # Consumers therefore trust hive CA + swarm root; on a hive that - # still has a self-signed CA the bundle is just that CA, so the - # consumer side needs no condition at all. Trusting the root is - # also the point of the hierarchy — it is what lets a peer hive - # validate without being hand-pinned. + # Written IN PLACE, never renamed into position — containers + # bind-mount this file and a bind mount follows the inode, so a + # rename leaves every consumer holding the old one. # - # Written IN PLACE, never renamed into position: containers bind - # -mount this file, and a bind mount follows the inode. A - # rename would leave every consumer holding the old one. - # `ca-previous.pem` rides along after an adoption for the same - # reason: a consumer that has not restarted yet is still pinned to - # the old anchor, and dropping it the instant the new one exists - # would break exactly the hosts the migration was supposed to - # spare. Removing it is a deliberate later step, not this unit's - # call — "long enough" is a deployment fact. + # Dropping `ca-previous.pem` is deliberately NOT done here: + # "long enough" is a deployment fact, not a unit's call. # - # Built as an explicit anchor ARRAY with `if` guards, not + # Built as an array with `if` guards, not # `[ -s f ] && anchors+=(f)`: under `set -e` an && list whose test - # fails IS a failing command and kills the unit, so the tidier - # form would break precisely on the hive where the optional file - # is legitimately absent. The `|| true` patch for that is worse — - # it would also swallow a real failure to read the hive CA. + # fails IS a failing command and kills the unit — on exactly the + # hive where the optional file is legitimately absent. The + # reflexive `|| true` is worse; it also swallows a real failure to + # read the hive CA. bundle="$d/trust-bundle.pem" anchors=("$ca") if [ -s "$prev" ]; then anchors+=("$prev"); fi