Watch
0
0
Fork
You've already forked hyperhive
0

swarm CA: retire the host-held root CA, the store holds the only anchor

The secret store's pki root issues every hive's gateway leaf and the
swarm's service names, so the root swarm-ca.service generated on the
host anchors nothing and its key is a secret outside the store.

- swarm-ca.nix is gone: swarm-ca.service, root.pem and root-key.pem,
  and the swarm.ca.{autoConfigure,stateDir,validityDays} options. A
  definition of any of them fails evaluation with a removal message
  (swarm-ca-removed.nix), and a tmpfiles rule deletes /var/lib/swarm-ca
  on every host. singleHostSwarm no longer sets a swarm.* option.
- hive-tls-ca drops the $root slot: trust-bundle.pem holds the store's
  pki root and a hive CA's public ca.pem/ca-previous.pem only.
- hivectl peer-config no longer prints the scp line for the swarm root;
  the store's pki root is the one step.
- The gateway's cert import no longer stands a hive leaf or a throwaway
  in for a missing swarm-services leaf where it Requires= the issuing
  unit: it fails, naming swarm-services-cert.service. The stand-in stays
  where the gateway does not wait (no swarm name, or the store's UI
  only, whose passthrough must start with the store sealed).

Comments and docs that named swarm-ca.nix, swarm.ca.* or the host root
now name the store's pki root.

Refs #4588
This commit is contained in:
atlas 2026-10-05 19:37:35 +02:00 • committed by mara
commit 93f1a76ea7
22 changed files with 305 additions and 395 deletions

View file

@ -32,7 +32,6 @@ in
toggles that an all-on-one-box deployment implies: the swarm's
shared services
(`services.hyperhive.deploy.allSwarmServices`), the swarm
CA (`services.hyperhive.swarm.ca.autoConfigure`), the swarm
controller (`services.hyperhive.deploy.swarm-controller.enable`), and the
host's `/etc/hosts` entries for the names this hive serves
(`services.hyperhive.gateway.localHostsEntry`) — with no real DNS
@ -71,11 +70,8 @@ in
# break every agent's access to the forge.
config.services.hyperhive.gateway.localHostsEntry = lib.mkDefault cfg.deploy.singleHostSwarm;
# Out of the `swarm` attrset below, because it is a `deploy.*` option now
# (./deploy.nix): "does THIS host run the swarm's services" is a per-host
# decision. Written as a path rather than folded into a second
# `config.services.hyperhive.deploy = { … }` attrset, for the same reason
# the ⚠️ below gives about `swarm`.
# A `deploy.*` option (./deploy.nix): "does THIS host run the swarm's
# services" is a per-host decision.
config.services.hyperhive.deploy.allSwarmServices = lib.mkDefault cfg.deploy.singleHostSwarm;
# The queue's auth-callout nkeys. Generating them is safe exactly
@ -86,15 +82,6 @@ in
config.services.hyperhive.deploy.nats.autoGenerateCallout =
lib.mkDefault cfg.deploy.singleHostSwarm;
# ⚠️ Every `swarm.*` default this mode sets lives INSIDE this attrset, not
# as a second `config.services.hyperhive.swarm.…` path beside it — written
# that way the two definitions of `swarm` collide and the nested one is
# silently lost. The gate caught exactly that on the controller's queue URL,
# when this mode still set it: mode on, `natsUrl` still "".
config.services.hyperhive.swarm = {
ca.autoConfigure = lib.mkDefault cfg.deploy.singleHostSwarm;
};
# The controller is asserted by the MODE and by nothing else. Its own
# option stays `default = false` precisely because running it is a
# statement about swarm topology — but "this box is the whole
@ -103,11 +90,8 @@ in
# instead would be wrong: a hive in a larger swarm can legitimately
# want the shared services without being the host that controls them.
#
# Sits outside the `swarm` attrset above because it is a `deploy.*`
# option (./deploy.nix): "does THIS host run the controller" is exactly
# the per-host fact `swarm.*` may not carry. The ⚠️ collision note above
# does not apply here — that one is about two definitions of `swarm`
# itself, and this is a different top-level path.
# A `deploy.*` option (./deploy.nix): "does THIS host run the controller"
# is exactly the per-host fact `swarm.*` may not carry.
config.services.hyperhive.deploy.swarm-controller.enable = lib.mkDefault cfg.deploy.singleHostSwarm;
# Where the operator drops the token that writes the swarm's first bao
@ -122,8 +106,7 @@ in
# substitute for the other: one unseals the store, this one authorises the
# first write.
#
# Outside the `swarm` attrset above for the same reason the controller's
# options are — a path on this host is a `deploy.*` fact.
# A path on this host is a `deploy.*` fact, like the controller's options.
config.services.hyperhive.deploy.bao.bootstrapTokenFile = lib.mkIf cfg.deploy.singleHostSwarm (
lib.mkDefault "/var/lib/swarm-bao-bootstrap/grant.token"
);