METRICS_USERNAME set with an empty METRICS_PASSWORD publishes /metrics unauthenticated #205

Closed
opened 2026-08-20 05:47:43 +02:00 by clawbot · 0 comments
Collaborator

The /metrics route mounts on the username alone (internal/server/routes.go:59, :107), and MetricsAuth builds its credential map with whatever password it was given, empty included (internal/middleware/middleware.go:452-463).

Verified live with METRICS_USERNAME=metrics and METRICS_PASSWORD unset:

curl -u 'metrics:' /metrics  -->  200

while startup logged hasMetricsAuth:false and did not refuse to start. So the config is internally inconsistent — one layer thinks auth is off, the other mounts the route — and a half-set config silently publishes the endpoint.

This is the config-fails-loudly rule: a set-but-invalid configuration must abort startup rather than degrade into something the operator did not ask for.

Definition of done:

  • METRICS_USERNAME set with an empty or unset METRICS_PASSWORD is a startup error naming both variables; the process exits non-zero
  • the converse (METRICS_PASSWORD set, METRICS_USERNAME empty) is the same error
  • both unset remains valid and leaves /metrics unmounted
  • the startup log's hasMetricsAuth cannot disagree with whether the route is mounted; derive both from one value
  • tests cover all four combinations
The `/metrics` route mounts on the username alone (`internal/server/routes.go:59`, `:107`), and `MetricsAuth` builds its credential map with whatever password it was given, empty included (`internal/middleware/middleware.go:452-463`). Verified live with `METRICS_USERNAME=metrics` and `METRICS_PASSWORD` unset: ``` curl -u 'metrics:' /metrics --> 200 ``` while startup logged `hasMetricsAuth:false` and did not refuse to start. So the config is internally inconsistent — one layer thinks auth is off, the other mounts the route — and a half-set config silently publishes the endpoint. This is the `config-fails-loudly` rule: a set-but-invalid configuration must abort startup rather than degrade into something the operator did not ask for. Definition of done: - `METRICS_USERNAME` set with an empty or unset `METRICS_PASSWORD` is a startup error naming both variables; the process exits non-zero - the converse (`METRICS_PASSWORD` set, `METRICS_USERNAME` empty) is the same error - both unset remains valid and leaves `/metrics` unmounted - the startup log's `hasMetricsAuth` cannot disagree with whether the route is mounted; derive both from one value - tests cover all four combinations
clawbot added this to the 1.0.0 milestone 2026-08-20 05:47:43 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#205