fix(#3396): move grafana and matrix onto the shared trust-bundle helper

Both hand-rolled the same concat with wantedBy + before and no requires,
so a failed assembly let the consumer start against a missing file and
trust nothing at all -- which fails every outbound TLS call while the unit
looks healthy. The helper puts requires on the consumer and verifies the
assembled bundle before moving it into place.

Removes each module's now-dead useSelfSigned binding: its only use was the
mkIf on the deleted block, and nix does not warn about an unused let
binding. Also corrects two comments the deletion orphaned -- one described
the removed path binding, the other pointed at a bundle service that no
longer exists.
This commit is contained in:
atlas 2026-08-17 20:29:22 +02:00
commit 9073c9b3f7
2 changed files with 31 additions and 74 deletions

View file

@ -23,7 +23,6 @@ let
swarmDomain = hyperhiveCfg.swarm.domain;
caTrust = import ./lib/hive-ca-trust.nix { inherit lib tlsCfg gatewayCfg; };
useSelfSigned = caTrust.useSelfSigned;
# Total on a null swarm domain for the same reason every sibling module is:
# the required-domain assertion in hive-network.nix should be what an
@ -61,7 +60,6 @@ let
# the authelia client and Grafana itself.
redirectUri = "https://${cfg.domain}/login/generic_oauth";
grafanaCaBundle = "/run/swarm-grafana-ca/ca-bundle.crt";
in
{
options.services.hyperhive.swarm.grafana = {
@ -357,6 +355,16 @@ in
inherit (networkCfg) bridgeIp;
dnsConsumers = [ "grafana.service" ];
})
# 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`.
(caTrust.trustBundle {
inherit pkgs;
name = cfg.machine;
consumers = [ "grafana" ];
})
];
system.stateVersion = "26.05";
@ -371,37 +379,6 @@ in
# the boundary after start.
networking.resolvconf.enable = lib.mkForce false;
# Self-signed mode: Grafana is Go, and Go's `SSL_CERT_FILE`
# *replaces* the default bundle rather than adding to it — so
# concatenate the system CAs with the bind-mounted hive CA instead
# of pointing at the CA alone, which would lose every public
# anchor. /run is tmpfs, so this is rebuilt from the current CA
# each boot rather than going stale.
#
# Without it the browser half of the login succeeds and the
# server-to-server token exchange fails with an x509 "unknown
# authority" — the same shape of failure the swarm queue hit.
systemd.services.swarm-grafana-ca-bundle = lib.mkIf useSelfSigned {
description = "assemble Grafana TLS trust bundle (system CAs + hive CA)";
wantedBy = [ "grafana.service" ];
before = [ "grafana.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
SyslogIdentifier = "swarm-grafana-ca-bundle";
};
path = [ pkgs.coreutils ];
script = ''
set -euo pipefail
install -d -m 0755 /run/swarm-grafana-ca
cat /etc/ssl/certs/ca-certificates.crt ${caTrust.caContainerPath} \
> ${grafanaCaBundle}
chmod 0644 ${grafanaCaBundle}
'';
};
systemd.services.grafana.environment.SSL_CERT_FILE = lib.mkIf useSelfSigned grafanaCaBundle;
# Grafana's `secret_key` has **no default in nixpkgs** and an
# assertion refuses the build without one — which is how the first
# version of this module broke a deploy. It signs the datasource