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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The
/metricsroute mounts on the username alone (internal/server/routes.go:59,:107), andMetricsAuthbuilds its credential map with whatever password it was given, empty included (internal/middleware/middleware.go:452-463).Verified live with
METRICS_USERNAME=metricsandMETRICS_PASSWORDunset:while startup logged
hasMetricsAuth:falseand 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-loudlyrule: a set-but-invalid configuration must abort startup rather than degrade into something the operator did not ask for.Definition of done:
METRICS_USERNAMEset with an empty or unsetMETRICS_PASSWORDis a startup error naming both variables; the process exits non-zeroMETRICS_PASSWORDset,METRICS_USERNAMEempty) is the same error/metricsunmountedhasMetricsAuthcannot disagree with whether the route is mounted; derive both from one valueclawbot referenced this issue2026-08-20 05:56:52 +02:00
clawbot referenced this issue2026-08-20 06:27:17 +02:00