hive-ci: give the runner daemon the hive CA it needs for TLS

NODE_EXTRA_CA_CERTS beside it is Node's and additive. gitea-runner is Go,
whose trust store is replacing: it reads SSL_CERT_FILE and trusts only
what that names. So the container trusted the hive CA for its Node
actions and never for the daemon itself.

The daemon then fails startup with x509 unknown authority the moment it
reaches a TLS endpoint, crash-loops on Restart=on-failure, and no job is
picked up -- every pull request just sits at Waiting to run.

Not claimed as the whole cause of that outage: which address the daemon
holds is a separate question. The trust gap is real under every
explanation, and adding a CA to one unit cannot break a working path.
This commit is contained in:
atlas 2026-08-26 18:30:24 +02:00
commit a7dbe732fb

View file

@ -24,6 +24,30 @@ let
useSelfSigned = caTrust.useSelfSigned;
caContainerPath = caTrust.caContainerPath;
# The runner daemon needs the hive CA too, and `NODE_EXTRA_CA_CERTS` above
# does not give it to them: that variable is Node's, and it is ADDITIVE.
# `gitea-runner` is Go, whose trust store is REPLACING -- it reads
# `SSL_CERT_FILE` and then trusts only what that file contains. So the two
# consumers need different treatment from the same CA, which is exactly the
# split the helper documents at its head.
#
# Without this the daemon fails every startup call with
# `x509: certificate signed by unknown authority` the moment it reaches a
# TLS endpoint -- and it reaches one whenever the address it is registered
# at redirects to the gateway's https vhost. The unit then crash-loops on
# `Restart=on-failure`, no job is ever picked up, and nothing reports it as
# broken: every pull request simply sits at "Waiting to run".
#
# ⚠️ This is deliberately NOT claimed as the whole story of that outage --
# what address the daemon holds is a separate question. It is here because
# the trust gap is real under every explanation of it, and adding a CA to
# one unit cannot break a path that already works.
caBundleModule = caTrust.trustBundle {
inherit pkgs;
name = "hive-ci";
consumers = [ "gitea-runner-hive" ];
};
in
{
# Forgejo Actions runner in a `hive-ci` nixos-container.
@ -224,6 +248,11 @@ in
config =
{ pkgs, lib, ... }:
{
# Assembles system CAs + the hive CA into one bundle and sets
# `SSL_CERT_FILE` on the runner unit. See `caBundleModule` above for
# why the Node variable beside it is not enough.
imports = [ caBundleModule ];
system.stateVersion = "26.05";
# Point the forge domain at the bridge IP so the runner can