feat(#1886): trust a peer hive's root CA hive-wide for self-signed federation
Add swarm.peers.<domain>.caCert (path to a peer hive's root CA PEM), trusted everywhere the hive's own internal CA is — so a self-signed peer hive can federate (matrix) and any in-hive consumer validates its certs. Mechanism (reuses the existing hive-CA embedding): the meta-flake renderer embeds a LIST of CA files next to each agent's flake — hive-ca.pem (the hive's own self-signed CA, when active) plus each peer caCert as peer-ca-<N>.pem — and emits them all in security.pki.certificateFiles, so every agent trusts them at build time. The matrix container trusts the same peer CAs for federation TLS. Nothing is installed in the host trust store; the certs live in the nix store (no mutable host file). - meta.rs: embedded_ca_files() = hive CA + peer CAs (from new HIVE_PEER_CA_PATHS env); ca_embed_state() tracks the list (content + add/remove); sync_agents materialises + stages the list; render emits the multi-entry certificateFiles. Tests cover hive-only / hive+peers / peers-only / none. - hive-c0re.nix: HIVE_PEER_CA_PATHS service env (colon-joined caCerts); caCert / certFingerprint option docs updated to the hive-wide scope. - hive-matrix.nix + docs/swarm.md: scope + comment updates. certFingerprint stays the c0re-only leaf-pin path.
This commit is contained in:
parent
eb09ec4e28
commit
edad6f863c
4 changed files with 288 additions and 70 deletions
|
|
@ -40,25 +40,35 @@ and `qualify()` / `qualified_label()` semantics.
|
|||
```nix
|
||||
services.hyperhive.swarm.peers = {
|
||||
"lab.example.com" = { }; # CA-trusted (Let's Encrypt etc.)
|
||||
"edge.corp" = { certFingerprint = "sha256:…"; }; # self-signed TLS
|
||||
"edge.corp" = { certFingerprint = "sha256:…"; }; # self-signed TLS, c0re peer checks only
|
||||
"mesh.internal" = { caCert = ./mesh-ca.pem; }; # self-signed, trusted for matrix federation
|
||||
};
|
||||
```
|
||||
|
||||
The attrset key is the peer's DNS domain. `certFingerprint` is
|
||||
optional:
|
||||
The attrset key is the peer's DNS domain. Two independent, optional
|
||||
trust knobs — pick by what you need to trust:
|
||||
|
||||
- **Omitted / null** — the system CA bundle validates the peer's TLS
|
||||
cert. Correct for peers with Let's Encrypt or any standard CA cert.
|
||||
- **Set** (`"sha256:…"`) — pin a specific cert fingerprint. Use this
|
||||
for peers whose self-signed TLS cert doesn't chain to a CA your
|
||||
host trusts.
|
||||
|
||||
`certFingerprint` scopes **only** to hive-c0re's own peer HTTPS checks
|
||||
(the P33RS dashboard links and agent peer discovery below). It is
|
||||
**not** consulted by matrix federation — tuwunel validates a peer's
|
||||
federation certificate against the system CA bundle independently (see
|
||||
*Matrix federation* below), so pinning a fingerprint here does nothing
|
||||
for a self-signed matrix gateway cert.
|
||||
- **`certFingerprint`** (`"sha256:…"`) — pin the peer's TLS *leaf*
|
||||
fingerprint. Scopes **only** to hive-c0re's own peer HTTPS checks
|
||||
(the P33RS dashboard links + agent peer discovery below). It is
|
||||
**not** consulted by matrix federation — tuwunel validates a peer's
|
||||
federation certificate against the system CA bundle independently
|
||||
(see *Matrix federation* below), so a fingerprint pin does nothing
|
||||
for a self-signed matrix cert.
|
||||
- **`caCert`** (path to the peer's root CA PEM) — embeds that CA (at
|
||||
build time, into the nix store — no runtime file on the host) and
|
||||
trusts it **everywhere the hive's own internal CA is**: it rides
|
||||
alongside `hive-ca.pem` in every agent's
|
||||
`security.pki.certificateFiles` (via the meta-flake renderer) **and**
|
||||
in the matrix container's trust bundle, so tuwunel validates the
|
||||
peer's *federation* TLS when it chains to that CA. Trust stays
|
||||
**inside the hive** (agents + the matrix container), never the host
|
||||
system trust store. **This is the knob that unblocks federation with
|
||||
a self-signed peer hive** — use it instead of `certFingerprint` when
|
||||
you control the peer's CA. (It does not affect hive-c0re's own peer
|
||||
HTTPS checks — those stay on `certFingerprint` / the system bundle.)
|
||||
- **Both omitted** — the stock system CA bundle validates the peer
|
||||
(correct for Let's Encrypt / any publicly-trusted peer).
|
||||
|
||||
### Fingerprint format
|
||||
|
||||
|
|
@ -114,13 +124,13 @@ environment and forwarded to agent containers.
|
|||
3. **Matrix federation** — when `matrix.enable` is on, tuwunel
|
||||
federates with the peer's matrix server (discovered via the peer's
|
||||
`.well-known/matrix/server` delegation, which the gateway serves).
|
||||
Federation validates the peer's TLS certificate against the
|
||||
**system CA bundle** — independently of `certFingerprint`, which it
|
||||
never consults. A self-signed gateway certificate therefore won't
|
||||
federate even with a fingerprint pinned above: the peers need
|
||||
CA-issued certs (ACME) or a shared private CA trusted on both
|
||||
gateway hosts. See `docs/matrix.md` for federation firewall + TLS
|
||||
requirements.
|
||||
Federation validates the peer's TLS certificate against the matrix
|
||||
**container's** trust bundle — independently of `certFingerprint`,
|
||||
which it never consults. A self-signed gateway certificate therefore
|
||||
won't federate unless the peer's root CA is trusted: set `caCert`
|
||||
above (embeds the peer CA into the matrix container's trust bundle),
|
||||
or give the peers CA-issued certs (ACME). See `docs/matrix.md` for
|
||||
federation firewall + TLS requirements.
|
||||
|
||||
## Bilateral setup
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue