Repository navigation
fix(metrics): gate /metrics behind explicit scrape authorization - #339
Miracle656 merged 2 commits into
Conversation
Miracle656
left a comment
There was a problem hiding this comment.
Scanned clean. The guard itself is well built and I want it — /metrics currently exposes the whole operational picture to anyone who asks.
What's right
timingSafeEqualwith an explicita.length === b.length &&in front. That length check is the detail people miss:timingSafeEqualthrows on differing lengths, so without it a short token is a 500 rather than a 401.- Fail-closed when
METRICS_SCRAPE_TOKENis unset — refusing everything is the right default for a secret-gated endpoint. - Exempting an authorised scraper from the rate limiter, with the reason stated: a scrape endpoint that starts 429ing goes blind exactly when you need it.
What blocks it: the PR also rewrites src/metrics.ts and deletes metrics that are still in use
The diff is 75 insertions against 137 deletions, and the deletions are not the guard. After merging current main, tsc reports 32 errors from eleven exports that no longer exist:
_resetMetrics recordOrderCreated renderMetrics
feeQuoteAlarmsTotal recordOrderTerminal metricsContentType
feeQuoteRecordFailuresTotal recordRpcError observeDbQuery
lastIndexedLedger recordSkippedLedger
and five metrics are gone from the registry entirely:
| Deleted metric | What it watches |
|---|---|
orders_terminal_total |
money-order outcomes by rail |
last_indexed_ledger |
indexer progress — the main liveness signal |
db_query_duration_seconds |
database latency |
veil_fee_quote_alarms_total |
fee-quote alarms |
veil_fee_quote_record_failures_total |
fee-quote write failures |
Git will not give these back on a rebase, either: a delete-versus-unchanged merge keeps the delete, so merging main leaves them removed and the tests that use them failing. They have to be put back deliberately.
Please reduce this to the access guard alone — metricsScrapeTokenFromEnv, bearerTokenOf, isAuthorisedScraper, metricsAccessGuard and the wiring — and leave the rest of src/metrics.ts untouched. The guard is maybe 60 lines and would be easy to review and merge; bundled with a registry rewrite it cannot go in at all.
One operational note for whoever merges it
Because it fails closed, METRICS_SCRAPE_TOKEN has to be set on the Render service before this lands, or /metrics starts answering 401 to our own scraper and monitoring goes dark silently. Worth setting the variable first, deploying this second.
|
@Miracle656 — this PR is ready for another review. I resolved the merge conflicts with the main branch (pushed 5b8a46c). |
Overview
This PR addresses the unauthenticated
/metricsendpoint, which is public, un-gated, and exempt from rate limiting. The change insrc/metrics.tsis scoped to the metrics module so that scrape access becomes an explicit, documented decision rather than an implicit default.Related Issue
Closes #[issue number]
Changes
🔒 Metrics Access Control
src/metrics.ts/metricshandler so that only requests presenting the configured scrape credential are served metric output.Verification Results
Verification was not run as part of this change set. Before merge, the following should be confirmed:
npx tsc --noEmitpassesnpx jest --runInBandpasses, including the webhook tests insrc/api/linqWebhook.tscoveragenpm run docs:openapioutput is byte-identical to the committed spec/metricshave been identified and continue to succeedsrc/metrics.ts; documentation not included in this changesrc/api.tsis not modified by this change; needs confirmationCloses #316