Fail startup on half-set metrics credentials (closes #205)
All checks were successful
check / check (push) Successful in 4m49s

METRICS_USERNAME alone mounted /metrics behind a credential map
whose only password was the empty string, so `curl -u 'metrics:'`
returned 200 while the startup log reported hasMetricsAuth:false.
The route mount tested the username and the log tested both, so the
two could disagree about whether the endpoint existed.

Config.MetricsAuthEnabled is now the single value behind both: the
/metrics mount, the Prometheus recording middleware and the startup
log's hasMetricsAuth field all read it, and it requires both
credentials. loadFromEnv rejects a half-set pair outright with an
error naming both variables in either direction, so a set-but-invalid
configuration aborts startup rather than degrading into an endpoint
the operator did not ask for. Both unset stays valid and leaves
/metrics unmounted.

Tests cover all four combinations at the config layer, counting
"set to the empty string" and "not set at all" as separate inputs,
plus the route tree's behaviour in each state.
This commit is contained in:
2026-08-20 04:11:01 +00:00
parent 10c8dd2331
commit c172deee72
5 changed files with 401 additions and 22 deletions

View File

@@ -55,8 +55,11 @@ func (s *Server) setupGlobalMiddleware() {
s.router.Use(s.mw.SecurityHeaders())
s.router.Use(s.mw.Logging())
// Metrics middleware (only if credentials are configured)
if s.params.Config.MetricsUsername != "" {
// Metrics recording middleware, registered only when the
// endpoint that exposes what it records is served. The
// condition is the same MetricsAuthEnabled the /metrics mount
// in setupRoutes reads.
if s.params.Config.MetricsAuthEnabled() {
s.router.Use(s.mw.Metrics())
}
@@ -103,8 +106,14 @@ func (s *Server) setupRoutes() {
s.h.HandleHealthCheck(),
)
// set up authenticated /metrics route:
if s.params.Config.MetricsUsername != "" {
// Authenticated /metrics route. The condition is
// Config.MetricsAuthEnabled and never the username alone: a
// username with an empty password would otherwise mount the
// endpoint behind a credential map that accepts an empty
// password. Config rejects that combination at startup, and
// this reads the same value the startup log reports, so the
// two cannot disagree about whether the route exists.
if s.params.Config.MetricsAuthEnabled() {
s.router.Group(func(r chi.Router) {
r.Use(s.mw.MetricsAuth())
r.Get(