api: restore access control on the unified Prometheus /metrics endpoint - #63
Merged
priscaenoch merged 1 commit intoAug 24, 2026
Conversation
…point GET /metrics (src/index.ts) already exposed the shared prom-client registry, but the operator-token/loopback access control added in 81e6186 was silently dropped by an unrelated CI-fix merge (6edbf65) and the endpoint has been unauthenticated on main since. The existing tests/metrics-access.test.ts masked this: it re-implemented the guard logic in a throwaway Express app instead of exercising the real route, so it kept passing after the regression. - Extract the guard into src/middleware/metricsAuthGuard.ts (mirrors the existing metricsMiddleware.ts convention) and wire it onto GET /metrics. METRICS_TOKEN set -> Bearer/X-Metrics-Token required (401 otherwise); unset -> loopback-only (403 for remote callers). - Rewrite tests/metrics-access.test.ts to import and exercise the real metricsAuthGuard via supertest, so a future regression here fails the suite instead of silently passing. - Document the endpoint, both services' registries, and METRICS_TOKEN in README.md. Closes octraban#52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The API service already had a single, documented-in-code
GET /metricsexposing the sharedprom-clientregistry (src/metrics.tsviasrc/index.ts) — most of #52 was already in place. What was missing:81e6186(fix(security): protect GET /metrics with operator token or loopback restriction) addedMETRICS_TOKEN/loopback gating on this route. A later, unrelated CI-fix commit (6edbf655,fix(ci): resolve compilation issues and restore missing proxyTrust middleware) was based on a pre-81e6186copy ofsrc/index.tsand its merge silently dropped that gating —mainhas been serving/metricswith no access control since.tests/metrics-access.test.tsdidn't catch this because it re-implemented the guard logic inline in a throwaway Express app instead of exercising the real route, so it kept passing straight through the regression.METRICS_TOKEN.What changed
src/middleware/metricsAuthGuard.ts(same pattern as the existingsrc/middleware/metricsMiddleware.ts) and wired it ontoGET /metricsinsrc/index.ts. Behavior (unchanged from the original81e6186design):METRICS_TOKENset →Authorization: Bearer <token>orX-Metrics-Tokenrequired,401otherwise;METRICS_TOKENunset → only loopback (127.0.0.1/::1) allowed,403for remote callers.tests/metrics-access.test.tsto import and exercise the realmetricsAuthGuard(viasupertestagainst a minimal app that mounts it) instead of a hand-rolled copy, so a future regression here fails the suite instead of silently passing.## Metricssection toREADME.mddocumenting both services'/metricsendpoints (API:3000vs indexer:3001, their separate registries, default process metrics) and theMETRICS_TOKENenv var, plus a/metricsrow in the API Endpoints table.Context / before-after
curl http://<host>:3000/metricsreturned the full metrics payload to anyone, unauthenticated — an internal-topology/ops-visibility leak on a publicly reachable service. No mention of the endpoint orMETRICS_TOKENin the README.81e6186; documented for operators.Testing
tests/metrics-access.test.ts— now imports the realmetricsAuthGuardfromsrc/middleware/:X-Metrics-TokenwhenMETRICS_TOKENis set; 200 with the correct token via either header.METRICS_TOKENis unset.vitest run tests/metrics-access.test.ts tests/metrics-middleware.test.ts→ 17/17 passing.tsc --noEmit— clean.eslint src/middleware/metricsAuthGuard.ts src/index.ts tests/metrics-access.test.ts— clean.Closes #52