otel: refuse a half-configured escape hatch instead of 404ing silently

Turning ingest auth off without clearing a hive's credential leaves that
hive's collector authenticating and addressing its own path, while an
unauthenticated swarm tier serves one catch-all and forwards the URI
unchanged. The receiver is asked for a path it does not serve, so telemetry
stops with 404s and retries — no 401, no assertion, nothing in any log
naming auth.

Only reachable by overriding one side without the other, since both defaults
derive from the same flag. That is what makes it worth a build error rather
than a caveat: an operator who flips the documented escape hatch has no
reason to suspect the sending half.

Found in review by argus.
This commit is contained in:
atlas 2026-08-19 15:11:37 +02:00 committed by mara
commit 7da7915150
2 changed files with 41 additions and 0 deletions

View file

@ -403,6 +403,41 @@ in
false to accept unauthenticated ingest.
'';
}
{
# The mirror of the assertion above, and the reason it exists is
# that the failure is SILENT rather than loud. With ingest
# unauthenticated the swarm tier serves one catch-all location
# and passes the URI through unchanged — but this tier still
# appends `/<hive>` whenever it holds a credential, so the
# receiver is asked for `/<hive>/v1/metrics`, a path it does not
# serve. The result is 404s and retries: no 401, no assertion, no
# log anywhere saying telemetry stopped.
#
# Only reachable by overriding one side without the other, since
# both defaults derive from `swarm.authelia.enable` and move
# together. That is exactly why it is worth a build error — an
# operator who flips the escape hatch has no reason to suspect
# the sending half.
assertion = !(swarmOtelCfg.enable && !swarmOtelCfg.requireHiveIdentity && senderAuth);
message = ''
This host accepts unauthenticated telemetry ingest
(services.hyperhive.swarm.otel.requireHiveIdentity = false),
but its own collector still holds a credential:
services.hyperhive.otel.clientSecretFile = ${
if otel.clientSecretFile == null then "null" else otel.clientSecretFile
}
A collector that authenticates also addresses its hive's own
path, and an unauthenticated swarm tier serves no per-hive
paths so this hive's samples would 404 rather than be
refused, which no log names as an auth problem.
Set services.hyperhive.otel.clientSecretFile = null to send
unauthenticated too, or drop the requireHiveIdentity
override.
'';
}
];
}
);