fix(#3442): give hive-c0re hive-CA trust

hive-c0re is a host unit that wired no CA trust at all. Harmless today
-- every endpoint it is handed defaults to plain http or loopback, so
nothing verifies a certificate -- and latent for the split-host shape the
options invite: `swarm.matrix.apiUrl`'s own example is an https URL, and
pointing it or `statusPublish.natsUrl` at another hive's gateway means
verifying a leaf signed by a CA generated at runtime.

Unlike the other consumers of this helper, hive-c0re already makes a
public-TLS call -- the OTEL exporter reaches whatever `otel.endpoint`
names. `SSL_CERT_FILE` replaces the trust store rather than adding to it,
so the bundle being system CAs + hive CA is what keeps that path working;
narrowing it to the hive CA alone would fix a case nobody hits yet and
break one that runs today.
This commit is contained in:
atlas 2026-08-18 17:55:57 +02:00 committed by mara
commit 3efeffd95f

View file

@ -13,6 +13,12 @@
let
cfg = config.services.hyperhive.c0re;
caTrust = import ../lib/hive-ca-trust.nix {
inherit lib;
tlsCfg = config.services.hyperhive.tls;
gatewayCfg = config.services.hyperhive.gateway;
};
# Privsep splits ownership across users, so git/libgit2's dubious-
# ownership guard trips on legitimate cross-user reads: hive-priv (root)
# fetches the hive-core-owned meta/applied repos via nix, and hive-c0re
@ -105,6 +111,28 @@ in
imports = [
./options.nix
./theme.nix
# Hive-CA trust for this daemon's outbound TLS. Nothing it is given by
# default is https — the forge, matrix and queue URLs all resolve to
# plain http or loopback — so this changes nothing on an all-local
# hive. It matters for the split-host shape the options invite:
# `swarm.matrix.apiUrl`'s own example is `https://matrix.example.com`,
# and pointing it (or `statusPublish.natsUrl`) at another hive's
# gateway means verifying a leaf signed by a CA generated at runtime,
# which no build-time trust store can contain.
#
# ⚠️ `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.
(caTrust.trustBundle {
inherit pkgs;
name = "hive-c0re";
consumers = [ "hive-c0re" ];
hostUnit = true;
enable = cfg.enable;
})
];
config = lib.mkIf cfg.enable {