fix(#3462): the swarm-services leaf never covered grafana, metrics or otel

swarm.serviceDomains is what gateway.lib.tlsFor consults to pick the
services leaf over the hive leaf. grafana, victoriametrics and otel each
claim a gateway name under the swarm apex but were absent from that list,
so their vhosts were served the HIVE certificate -- which cannot cover a
name under a different apex.

Invisible until a machine client hit it: a name mismatch is a
click-through warning in a browser and an outright refusal in an OTLP
exporter. The metrics UI and store looked healthy while the collector
failed every POST and dropped the samples.

  tls: failed to verify certificate: x509: certificate is valid for
  probe.example, *.probe.example, not otel.swarm.example
This commit is contained in:
atlas 2026-08-18 21:27:07 +02:00 committed by mara
commit 2dea5798e4

View file

@ -45,7 +45,21 @@ let
# `forge.<apex>` is, and no CA in the hierarchy issues for it
# implicitly. Left out, its vhost falls back to the hive leaf and the
# swarm's front page opens with a name mismatch.
++ lib.optional swarmCfg.ui.enable swarmCfg.ui.domain;
++ lib.optional swarmCfg.ui.enable swarmCfg.ui.domain
# Every swarm service that claims a gateway name belongs here, and
# these three were missing it. Membership is what `gateway.lib.tlsFor`
# consults to pick the services leaf over the hive one, so a name
# absent from this list is served the HIVE certificate — which cannot
# cover a name under a different apex however the sub-CA is set up.
#
# ⚠️ How that stayed invisible: a mismatch a browser shows as a
# click-through warning is one a machine client rejects outright. The
# metrics UI and store looked fine for as long as only people opened
# them; the collector's exporter — same defect, no human in the loop —
# failed every POST and dropped the samples.
++ lib.optional swarmCfg.grafana.enable swarmCfg.grafana.domain
++ lib.optional swarmCfg.victoriametrics.enable swarmCfg.victoriametrics.domain
++ lib.optional swarmCfg.otel.enable swarmCfg.otel.domain;
# Hives whose entry still carries the removed `certFingerprint`. Scanned
# here, at top level, because that is the only place an assertion about a