fix(#3524): stop naming the trust bundle as the oidc issuer anchor

The swarm collector could never verify its OIDC issuer, so it exited at
startup on every boot and the hive tier dropped every metric.

`issuer_ca_path` loads only the FIRST certificate in the file it names.
The bundle assembled for this container is `system CAs ++ hive anchors`,
so the swarm CA sits ~123rd and was never in the pool: the extension got
whichever public CA sorts first, could verify nothing of ours, and failed
`x509: certificate signed by unknown authority` — with 125 valid
certificates in the file.

Leaving the option unset makes the extension use the process trust store,
which `trustBundle` already populates via `SSL_CERT_FILE`, and that
consumer reads every certificate regardless of order. One file, two
consumers, opposite parsing; the fix is to stop naming it twice rather
than to reorder the bundle.

Measured with the deployed binary against the deployed config, varying
only the CA source: root-only OK, root-first OK, root-last FAILS,
root-second FAILS, and unset-with-SSL_CERT_FILE OK against a control that
correctly fails when the anchor is absent.
This commit is contained in:
atlas 2026-08-19 17:54:26 +02:00 committed by mara
commit b8b571fea0
2 changed files with 48 additions and 11 deletions

View file

@ -52,11 +52,27 @@ in
# Where `trustBundle` below puts the assembled bundle, for the callers
# that must NAME it rather than just have it exported. `SSL_CERT_FILE` is
# set for you and needs no path here; a consumer that takes its own CA
# argument (an OIDC verifier's `issuer_ca_path`, a client's `--cacert`)
# does, and the alternative is copying `/run/<name>-ca/…` to the call
# site. That copy breaks silently: the bundle keeps being written, the
# consumer keeps reading a path that no longer exists, and the failure
# surfaces as a TLS error naming the peer rather than the file.
# argument (a client's `--cacert`) does, and the alternative is copying
# `/run/<name>-ca/…` to the call site. That copy breaks silently: the
# bundle keeps being written, the consumer keeps reading a path that no
# longer exists, and the failure surfaces as a TLS error naming the peer
# rather than the file.
#
# ⛔ **Do not hand this path to a consumer that reads only ONE
# certificate from it.** This comment used to offer an OIDC verifier's
# `issuer_ca_path` as the motivating example; that is exactly what took
# the swarm collector down for forty minutes once. The bundle is
# `system CAs ++ hive anchors`, so the anchor is ~123rd, and a
# first-certificate-only reader gets whichever public CA sorts first and
# can verify nothing of ours — with a full, valid, 125-certificate file
# on disk and no check able to see it.
#
# 🔑 The general trust store (`SSL_CERT_FILE`, set by `trustBundle`)
# reads every certificate and is order-independent, which is why a
# consumer that can use the process trust store should simply be left to
# do so. Before naming this path, check how that consumer parses it —
# the requirement is a property of the *reader*, and nothing here can
# enforce it.
inherit bundlePathFor;
# Fold into the container's `bindMounts` via `//`. Binds ONLY the public