chore(auth): require auth on the previously-open GET routes#537
Conversation
The GET handlers for repos, automation/repos, automation/sync, agent-runs, and
audit allowed unauthenticated reads (repo lists, sync history, audit logs).
Guard them with authorizeRequest, matching every other route.
Safe for the dashboard: the board/agents pages server-render via Prisma (they
don't fetch these), and the automation page fetches automation/{repos,sync} via
authedFetch (sends Authorization), which authorizeRequest accepts (basic/bearer/
oidc-session). Only anonymous callers are now rejected.
Closes #509
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — routed smart (risk match: public_route_changes)
PR Review: chore(auth): require auth on the previously-open GET routes
Recommendation
Approve. This PR correctly addresses the security issue in PR 509 by adding authorizeRequest authentication guards to all five previously-open GET routes. The implementation is consistent, well-tested, and follows existing patterns in the codebase. CI passed (typecheck, docker build, tests, lint, build).
Change-by-Change Findings
1. src/app/api/repos/route.ts
- Added
authorizeRequestcheck at the top of the GET handler - Returns
401with{ "error": "Unauthorized" }when not authorized - Status: ✅ Correct — matches the pattern used elsewhere in the codebase (see
agent-work/checkpoint/route.ts:55,agents/[agentName]/heartbeat/route.ts:38, etc.)
2. src/app/api/agent-runs/route.ts
- Added
authorizeRequestcheck at the top of the GET handler - Status: ✅ Correct
3. src/app/api/audit/route.ts
- Added
authorizeRequestcheck at the top of the GET handler - Status: ✅ Correct
- The diff also shows removal of the "intentionally unauthenticated" NOTE comment from the test file, which is appropriate since the policy is now to require auth
4. src/app/api/automation/repos/route.ts
- Added
authorizeRequestcheck; also addedrequest: Requestparameter (was missing before) - Status: ✅ Correct — adds proper typing while guarding the route
5. src/app/api/automation/sync/route.ts
- Added
authorizeRequestcheck; also addedrequest: Requestparameter (was missing before) - Status: ✅ Correct
Test Changes
route.test.tsfiles updated to:- Add explicit
it("401s an unauthenticated request", ...)test for each route - Add
Authorization: Bearerheader to existing GET tests that now require auth - Remove outdated "intentionally unauthenticated" NOTE comments
- Add explicit
- Status: ✅ Tests verify the new behavior correctly
Required Checks
✅ verify route access controls are in place
All five routes now have authorizeRequest guards at the entry point of their GET handlers:
GET /api/reposGET /api/agent-runsGET /api/auditGET /api/automation/reposGET /api/automation/sync
The guards consistently return 401 with { "error": "Unauthorized" }, matching the pattern established by other secured routes in the repository (e.g., agent-work/checkpoint/route.ts:55, agents/[agentName]/heartbeat/route.ts:38).
✅ check for unintended public endpoints
No new public endpoints were introduced. The PR only adds auth guards to existing routes. The POST handlers on these routes were already protected (the PR body notes that automation/{repos,sync} were POST-only and already authed).
Standards Compliance
- API routes return appropriate HTTP status codes: ✅ Uses
401for unauthorized, consistent with existing auth patterns - Error handling uses
error instanceof Errorpattern: ✅ Not applicable here (no error paths modified) - No commit of secrets: ✅ No secrets added
Linked Issue Fit
Issue PR 509 required guarding GETs on repos, automation/repos, automation/sync, agent-runs, and audit with authorizeRequest. This PR fulfills that requirement exactly:
| Route | Before | After | Status |
|---|---|---|---|
GET /api/repos |
Unauthenticated | 401 when unauthenticated | ✅ Fixed |
GET /api/automation/repos |
Unauthenticated | 401 when unauthenticated | ✅ Fixed |
GET /api/automation/sync |
Unauthenticated | 401 when unauthenticated | ✅ Fixed |
GET /api/agent-runs |
Unauthenticated | 401 when unauthenticated | ✅ Fixed |
GET /api/audit |
Unauthenticated | 401 when unauthenticated | ✅ Fixed |
Evidence Provider Findings
No evidence providers configured; not applicable.
Tool Harness Findings
The tool-calling loop issued no tool calls; this review is based on direct corpus analysis.
Unknowns / Needs Verification
None. The diff is self-contained, CI passed, and the implementation pattern is verified against existing auth-protected routes in the repository.
Summary
repos,automation/repos,automation/sync,agent-runs, andauditwithauthorizeRequest— they previously allowed unauthenticated reads of repo lists, sync history, and audit logs.Why it's safe for the dashboard (validated)
board/agentspages are server components reading Prisma directly — they don't HTTP-fetch these routes, so guarding them has zero UI impact.automationpage fetchesautomation/{repos,sync}viaauthedFetch, which attachesAuthorization: Basic …(and the oidc session cookie rides along).authorizeRequestaccepts basic/bearer/oidc-session, so the logged-in dashboard passes; only anonymous callers get 401.Verification
automation/{repos,sync}had no GET tests (POST-only, already authed).tsc→ 0;eslint→ clean; the five route suites → 51 passing.Closes #509 · completes the audit umbrella #498