otel: a hive always authenticates — drop the unauthenticated mode

mara, reviewing this PR: "hives always require an identity, swarm controller
and auth is not optional."

So `requireHiveIdentity` is gone rather than defaulted, and with it every
branch that had to describe an unauthenticated collector. The swarm tier now
serves per-hive receivers only, and `/` answers 404 because there is no
swarm-wide inbox to route to. A hive with no credential is a build error, not
a quieter mode.

`hivePortBase` goes too: with per-hive receivers unconditional, `port` IS the
base of the range. That keeps one documented knob instead of adding a second,
and its advice ("move it if something else claims that range") still holds.

Two assertions replace the toggle — an empty hive roster, and a null
`authelia.url`. The second matters because a guessed issuer URL evaluates
cleanly, deploys cleanly, and then refuses every hive at runtime.

⚠️ `cfg.port` is deliberately no longer compared against the derived range in
the collision assertion: it is now the range's first element, so listing it
would make that assertion fire on every config.

This also retires the asymmetry guard added earlier in review — the state it
protected against (auth off on one side, credential still set on the other)
is no longer representable.
This commit is contained in:
atlas 2026-08-19 15:22:29 +02:00 committed by mara
commit 9bd2b9e9e6
3 changed files with 107 additions and 192 deletions

View file

@ -203,26 +203,13 @@ somehow — copy it across and name it:
services.hyperhive.otel.clientSecretFile = "/run/secrets/hive-telemetry.secret";
```
Getting that wrong shows up as the hive's collector logging 401s from the swarm
tier and no metrics appearing for that hive. When a single host runs both tiers
the build catches it instead, because it can see both sides.
**There is no unauthenticated mode.** A hive always presents an identity, so a
missing credential is a build error rather than a quieter fallback — the
collector has no anonymous route to accept samples on, and every path it serves
belongs to exactly one hive.
To accept unauthenticated ingest — every writer on the swarm network already
trusted, or a swarm with no authelia:
```nix
services.hyperhive.swarm.otel.requireHiveIdentity = false;
services.hyperhive.otel.clientSecretFile = null; # on each hive that had one
```
Both halves, because a collector that authenticates also addresses its hive's
own path, and an unauthenticated swarm tier serves no per-hive paths. Set only
the first and that hive's samples 404 instead of arriving. On a host running
both tiers the build says so; on a split host it is yours to keep in step.
⚠️ That reopens the original hole rather than merely skipping a check: while an
unauthenticated port is listening, anything that can reach the collector can
attribute metrics to any hive.
Getting the secret wrong shows up as the hive's collector logging 401s from the
swarm tier and no metrics appearing for that hive.
### `services.hyperhive.otel.collector.port` — port, default `4318`