Repository navigation
feat: add API key authentication to management endpoints - #397
Conversation
All /api/v1/ management endpoints were unauthenticated, letting any client with network access create, modify or delete productions, sessions and presets. Add an opt-in API key guard applied to the management routes. - Add src/auth.ts exporting a `requireApiKey` Fastify preHandler hook that reads process.env.API_KEY; when unset/empty auth is disabled (dev mode, preserves current behaviour), otherwise requires an `Authorization: Bearer <API_KEY>` header and replies 401 on absence/mismatch. - Use a constant-time comparison (timingSafeEqual) and a generic 401 body; the key is read only from env and never logged. - Apply the hook to POST/PATCH/DELETE /production, POST/DELETE /session, GET/POST/PATCH/DELETE /preset and POST /ingest. - Leave WHIP/WHEP routes untouched (they keep their own WHIP_AUTH_KEY auth). - Add src/auth.test.ts covering disabled/missing/wrong/correct key cases. Closes #222 Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
code-reviewer verdict: LGTM (automated self-review by a separate code-reviewer invocation; recorded as a marker because GitHub blocks state-bearing self-review when author and reviewer are the same account). Independent reviewer re-ran the suite in a fresh clone: typecheck clean, lint 0 errors, 438/438 tests pass, Prettier-clean. Routing audit confirmed the Non-blocking warnings for a possible follow-up (not in #222's scope): the production-line mutation routes ( |
|
code-reviewer verdict: NEEDS CHANGES (automated self-review; recorded as a marker because GitHub blocks state-bearing review when author and reviewer are the same account). Build/typecheck/lint clean and all 446 tests pass, but the PR does not yet meet issue #222: four production-mutating management endpoints are left unauthenticated, so an unauthenticated caller can still create/modify/delete production lines and force-disconnect participants. Blocking
Warnings
Suggestions
Addressing the four Blocking endpoints (plus the session/startup warnings and an integration test) and re-review will clear this. |
… requireApiKey (#222) A code review found the API key guard was not applied to several production-mutating endpoints. Apply requireApiKey to them and close the gaps: - POST /production/:productionId/line - PATCH /production/:productionId/line/:lineId - DELETE /production/:productionId/line/:lineId - POST /production/:productionId/line/:lineId/participants/:sessionId/disconnect Also guard PATCH /session/:sessionId so the /session lifecycle is consistent with the already-guarded POST/DELETE /session management endpoints. Add a startup SECURITY warning in server.ts when API_KEY is unset, mirroring the existing WHIP/WHEP/reauth UNAUTHENTICATED warnings, so operators get a signal that management auth is disabled. Note the dead-code route-level guard in api_ingests.ts as unreachable (the global 501 gate short-circuits every ingest route first); kept rather than removed to avoid scope creep. Add an integration test (api_auth_guard.test.ts) that registers the real routes with API_KEY set and asserts each newly-guarded endpoint rejects an unauthenticated request with 401. Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
code-reviewer verdict: LGTM (automated self-review; recorded as a marker because GitHub blocks state-bearing review when author and reviewer are the same account — reviewed by a separate code-reviewer invocation, not the implementer). Reviewed at head Out-of-scope follow-up (not blocking #222): two unauthenticated mutating |
Summary
/api/v1/management endpoints were unauthenticated; any client with network access could create/modify/delete productions, sessions and presets. Adds an opt-in API key guard.src/auth.tsexporting arequireApiKeyFastifypreHandlerhook: readsprocess.env.API_KEY; when unset/empty, auth is disabled (dev mode, preserves current behaviour and all existing tests); otherwise requiresAuthorization: Bearer <API_KEY>and replies401 { error: 'Unauthorized' }on absence/mismatch.timingSafeEqual) and a generic 401 body; the key is read only fromprocess.envand is never logged./production, POST/DELETE/session, GET/POST/PATCH/DELETE/presetand POST/ingest; WHIP/WHEP routes are left unchanged (they keep their ownWHIP_AUTH_KEYauth).src/auth.test.ts(7 tests) covering disabled/missing/wrong/correct key behaviour.Test plan
npm test)npm run typecheck)npm run lint)Closes #222
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.8 [email protected]