Severity: Medium · Found during AUTHZ-1 deploy recon
The break-glass ADMIN_KEY is overloaded as a credential on non-admin surfaces that bypass the WAYFORTH_ADMIN_KEY_ENABLED kill-switch:
routers/auth.py:203 — non-free key provisioning (body.admin_key).
routers/search/compare.py:308 — /intelligence/{service_id} (key via query param api_key=).
routers/search/compare.py:641 — /analytics (key via query param key=).
routers/search/compare.py:708 — /competitive (key via query param key=).
Two problems: (1) these bypass the kill-switch, so a leaked key still works there even with break-glass off; (2) three accept the key via query string (leaks into access logs) — the pattern the admin routers already moved away from.
Why not fixed in the High batch: gating them on the kill-switch would break the intelligence/analytics product when break-glass is off, because they use ADMIN_KEY as their only credential. Proper fix = a dedicated credential (separate API key / admin session) decoupled from break-glass. Needs a product decision.
Blocks: flipping WAYFORTH_ADMIN_KEY_ENABLED=false (a leaked key would still reach these). See deploy runbook step 7.
Severity: Medium · Found during AUTHZ-1 deploy recon
The break-glass
ADMIN_KEYis overloaded as a credential on non-admin surfaces that bypass theWAYFORTH_ADMIN_KEY_ENABLEDkill-switch:routers/auth.py:203— non-free key provisioning (body.admin_key).routers/search/compare.py:308—/intelligence/{service_id}(key via query paramapi_key=).routers/search/compare.py:641—/analytics(key via query paramkey=).routers/search/compare.py:708—/competitive(key via query paramkey=).Two problems: (1) these bypass the kill-switch, so a leaked key still works there even with break-glass off; (2) three accept the key via query string (leaks into access logs) — the pattern the admin routers already moved away from.
Why not fixed in the High batch: gating them on the kill-switch would break the intelligence/analytics product when break-glass is off, because they use ADMIN_KEY as their only credential. Proper fix = a dedicated credential (separate API key / admin session) decoupled from break-glass. Needs a product decision.
Blocks: flipping
WAYFORTH_ADMIN_KEY_ENABLED=false(a leaked key would still reach these). See deploy runbook step 7.