swarm CA: describe the store's pki root as the only anchor in docs and comments
The docs, option descriptions and comments that named the swarm root, the swarm CA or the hive CA as an existing trust anchor now name the secret store's pki root or the trust bundle that holds it: - docs/swarm/README.md, secrets.md, bao.md - deploy.bao.clientCaFile's and gateway.verifiedProxyTo's descriptions - comments in hive-c0re/src/meta.rs, hive-agent/src/swarm_queue.rs, swarm-logs/src/auth.rs, swarm-controller/src/vcs_metrics.rs, hive-forge, swarm-authelia, swarm-ci-runner, glue-bao-tls, swarm-bao, swarm-grafana, swarm-otel, otel, hive-c0re, lib/hive-ca-trust.nix, hive-forge/Cargo.toml and the flake-update workflow Nothing behaves differently: every edit is a nix, Rust or TOML comment, an option description, or a test assertion message. The Rust edits change the workspace source, which this PR already rebuilds for hivectl. Refs #4588
This commit is contained in:
parent
15f7d4d0cf
commit
cf7d357f17
20 changed files with 79 additions and 82 deletions
|
|
@ -13,10 +13,10 @@
|
|||
# handed. A deployment with a real internal CA drops this file and names its
|
||||
# own paths; nothing in the store changes.
|
||||
#
|
||||
# ⚠️ Not the hive CA and not the swarm CA. The store will eventually
|
||||
# distribute both, and an authority you must already hold a certificate from
|
||||
# cannot be one the store hands out — reach the store to get the CA material,
|
||||
# need a cert from that CA to reach the store. This CA signs a fixed, short
|
||||
# ⚠️ Not the store's `pki` root, which the store distributes. An authority
|
||||
# you must already hold a certificate from cannot be one the store hands
|
||||
# out — reach the store to get the CA material, need a cert from that CA to
|
||||
# reach the store. This CA signs a fixed, short
|
||||
# list of leaves and distributes nothing, so it cannot enter that cycle.
|
||||
#
|
||||
# ⚠️ Files like this are the only place a `deploy.<foo>` value may derive from
|
||||
|
|
|
|||
|
|
@ -136,9 +136,9 @@ in
|
|||
# ⚠️ `SSL_CERT_FILE` REPLACES the trust store, and unlike the other
|
||||
# consumers of this helper, hive-c0re already makes a *public*-TLS call:
|
||||
# the OTEL exporter reaches whatever `otel.endpoint` names, typically a
|
||||
# normal internet host. The bundle is system CAs + hive CA precisely so
|
||||
# that path keeps working — narrowing it to the hive CA alone would fix
|
||||
# a case nobody hits yet and break one that runs today.
|
||||
# normal internet host. The bundle is system CAs + the store's root
|
||||
# precisely so that path keeps working — narrowing it to the store's root
|
||||
# alone would fix a case nobody hits yet and break one that runs today.
|
||||
(caTrust.trustBundle {
|
||||
inherit pkgs;
|
||||
name = "hive-c0re";
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ in
|
|||
# --link-journal=try-guest, and EXTRA_NSPAWN_FLAGS expands after it.
|
||||
extraFlags = [ "--link-journal=host" ];
|
||||
inherit privateNetwork;
|
||||
# Self-signed mode: bind the public hive CA cert read-only so forgejo
|
||||
# Self-signed mode: bind the hive's trust bundle read-only so forgejo
|
||||
# can trust the gateway's self-signed leaf for outbound webhook
|
||||
# delivery. The bind-mount, the `container@` ordering and the bundle
|
||||
# the container's consumers read all come from the hive-ca-trust
|
||||
|
|
@ -480,12 +480,12 @@ in
|
|||
|
||||
# Forgejo is Go, and `SSL_CERT_FILE` *replaces* the default store
|
||||
# rather than adding to it — so it needs the system CAs and the
|
||||
# hive CA concatenated, not the CA alone, or public mirror fetches
|
||||
# lose every anchor they had.
|
||||
# store's root concatenated, not the root alone, or public mirror
|
||||
# fetches lose every anchor they had.
|
||||
#
|
||||
# BOTH units that make an outbound HTTPS call are consumers, not
|
||||
# just the obvious one: `forgejo-sso-source` fetches the issuer's
|
||||
# `.well-known/openid-configuration` over the swarm CA, and it
|
||||
# `.well-known/openid-configuration` under the store's root, and it
|
||||
# once shipped without the trust its sibling had. `optional`
|
||||
# rather than a flat list because that unit only exists when SSO
|
||||
# is on — naming an absent unit would order nothing and quietly
|
||||
|
|
@ -801,7 +801,8 @@ in
|
|||
# container's `imports` above, which is where `SSL_CERT_FILE`
|
||||
# comes from): registering the login source makes an **outbound
|
||||
# HTTPS call** to `<issuer>/.well-known/openid-configuration`,
|
||||
# served under the swarm CA the default store has never heard of.
|
||||
# served under the store's `pki` root, which the default store has
|
||||
# never heard of.
|
||||
# It once shipped without the trust `forgejo.service` had, and
|
||||
# failed every single time with `x509: certificate signed by
|
||||
# unknown authority`. The trust belongs to every process that
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ in
|
|||
description = ''
|
||||
Read-only: `name -> the proxy_ssl_* lines` for dialling
|
||||
another service on this hive **by name over https**, with the
|
||||
certificate actually verified against the hive CA bundle.
|
||||
certificate actually verified against the hive's trust bundle.
|
||||
|
||||
Published rather than written per module because nginx
|
||||
verifies nothing by default: `proxy_ssl_verify` is **off**, so
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Shared hive-CA trust plumbing for containers that must trust the
|
||||
# Shared trust-bundle plumbing for containers that must trust the
|
||||
# self-signed gateway/forge leaf for *outbound* TLS (webhook delivery,
|
||||
# CI artifact upload, …). The anchors exist only at runtime — the host
|
||||
# `hive-tls-ca.service` (see `hive-tls.nix`) assembles them into
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
# *consumption* differs per runtime: an additive variable (Node's
|
||||
# `NODE_EXTRA_CA_CERTS`, swarm-ci-runner) points straight at `caContainerPath` from
|
||||
# the call site, while a *replacing* one (Go's `SSL_CERT_FILE`, rustls) needs
|
||||
# the system-CAs+hive-CA concat that `trustBundle` below does for it.
|
||||
# the system-CAs+bundle concat that `trustBundle` below does for it.
|
||||
#
|
||||
# Pure function — NOT a NixOS module (don't add it to the host-modules
|
||||
# aggregator). Call it from a module's `let`:
|
||||
|
|
@ -93,7 +93,7 @@ in
|
|||
requires = [ "hive-tls-ca.service" ];
|
||||
};
|
||||
|
||||
# System CAs + hive CA in one bundle, with `SSL_CERT_FILE` set on each
|
||||
# System CAs + the trust bundle in one file, with `SSL_CERT_FILE` set on each
|
||||
# consumer — for runtimes whose trust variable *replaces* the store (Go,
|
||||
# rustls-native-certs). An additive one (Node's `NODE_EXTRA_CA_CERTS`,
|
||||
# swarm-ci-runner) needs no bundle and should not use this.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
let
|
||||
# This tier now reaches the swarm's collector by name through the
|
||||
# gateway (`swarm-otel-service.nix`'s `domain`) instead of a loopback URL, so it
|
||||
# needs the same hive-CA trust every other host consumer of an `https://`
|
||||
# needs the same trust-bundle wiring every other host consumer of an `https://`
|
||||
# swarm-service name needs — see `swarm-controller.nix` for the sibling
|
||||
# wiring this copies.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -97,9 +97,8 @@ let
|
|||
tlsCfg = deployCfg.hive-controller.tls;
|
||||
};
|
||||
# `swarm-authelia-bridge` verifies the gateway when it introspects by name.
|
||||
# Nothing in this container trusted the swarm CA, which is a runtime file no
|
||||
# build-time option can name — so an https call out of here could only ever
|
||||
# fail `UnknownIssuer`. Same defect the queue's responder hit.
|
||||
# The store's `pki` root is a runtime file no build-time option can name, so
|
||||
# without this bundle an https call out of here fails `UnknownIssuer`.
|
||||
caBundleModule = caTrust.trustBundle {
|
||||
inherit pkgs;
|
||||
name = cfg.machine;
|
||||
|
|
|
|||
|
|
@ -1180,8 +1180,8 @@ let
|
|||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
||||
|
||||
# Outbound TLS for that collector: it dials the swarm collector's gateway
|
||||
# name and authelia's token endpoint, both leaves of the runtime-generated
|
||||
# hive CA, which cannot be baked into a derivation. Same helper, same two
|
||||
# name and authelia's token endpoint, both leaves under the store's runtime
|
||||
# pki root, which cannot be baked into a derivation. Same helper, same two
|
||||
# halves and the same `SSL_CERT_FILE` consumption as ./swarm-otel.nix's own
|
||||
# container — a Go process whose trust variable REPLACES the store, which is
|
||||
# what the bundle (system CAs ++ our anchors) is for.
|
||||
|
|
@ -1374,10 +1374,9 @@ in
|
|||
description = ''
|
||||
Authority the store validates hive **client** certificates against.
|
||||
|
||||
This module declares no default and does not reach for the hive
|
||||
CA: the hive CA is a future *consumer* of the store, so a store
|
||||
that authenticated against it could not come up before the thing
|
||||
it issues.
|
||||
This module declares no default, and the store's own `pki` root
|
||||
can't be this authority: a store that authenticated against a root
|
||||
it issues could not come up before the thing it issues.
|
||||
|
||||
On a hive that runs the store, a glue module supplies the CA it
|
||||
minted for exactly this, as a `mkDefault`. Point this at something
|
||||
|
|
@ -3430,7 +3429,7 @@ in
|
|||
isReadOnly = true;
|
||||
};
|
||||
}
|
||||
# The hive CA, for the forwarder's two outbound calls: the swarm
|
||||
# The trust bundle, for the forwarder's two outbound calls: the swarm
|
||||
# collector's gateway name and authelia's token endpoint. Empty when
|
||||
# the gateway is not self-signed, so the whole path drops out.
|
||||
// caTrust.bindMount;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ let
|
|||
# below compares the two, so both come from here.
|
||||
forgeUrl = "https://${forgeCfg.domain}";
|
||||
|
||||
# The forge's gateway serves a leaf from the swarm CA in self-signed mode.
|
||||
# The forge's gateway serves a leaf from the store's `pki` mount in
|
||||
# self-signed mode.
|
||||
# The runner daemon is Go, whose `SSL_CERT_FILE` replaces the system store,
|
||||
# so it gets the assembled bundle; the Node actions it runs get
|
||||
# `NODE_EXTRA_CA_CERTS`, which is additive, further down.
|
||||
|
|
|
|||
|
|
@ -686,9 +686,9 @@ in
|
|||
})
|
||||
# Grafana is Go, and `SSL_CERT_FILE` *replaces* the default store
|
||||
# rather than adding to it — so it needs the system CAs and the
|
||||
# hive CA concatenated, not the CA alone. Without it the browser
|
||||
# half of the login succeeds and the server-to-server token
|
||||
# exchange fails `x509: unknown authority`.
|
||||
# store's root concatenated, not the root alone. Without it the
|
||||
# browser half of the login succeeds and the server-to-server
|
||||
# token exchange fails `x509: unknown authority`.
|
||||
(caTrust.trustBundle {
|
||||
inherit pkgs;
|
||||
name = cfg.machine;
|
||||
|
|
|
|||
|
|
@ -796,7 +796,7 @@ in
|
|||
isReadOnly = true;
|
||||
};
|
||||
}
|
||||
# The public hive CA, read-only — only when something in here
|
||||
# The public trust bundle, read-only — only when something in here
|
||||
# actually verifies a swarm-service name.
|
||||
// caTrust.bindMount
|
||||
# The host's journal, read-only, and only when something will read it.
|
||||
|
|
|
|||
Loading…
Reference in a new issue