Description
When PATCHPILOT_API_KEY is set in the backend environment, verify_api_key requires a Bearer token in the Authorization header. However, the frontend has absolutely no mechanism to store an API key or attach it to fetch requests. Every fetch call in api.ts is a bare fetch(url) with no headers. The entire frontend becomes non-functional when authentication is enabled.
Actual Behavior
Backend enforces auth on critical endpoints:
backend/app/security.py (lines 10-41):
def verify_api_key(authorization: str = Header(...)):
if not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="Missing API key")
if not hmac.compare_digest(provided_key, API_KEY):
raise HTTPException(status_code=401, detail="Invalid API key")
Protected endpoints in main.py: GET /jobs/{id}/findings, GET /jobs/{id}/verify, GET /trends, GET /cwe-distribution, GET /dependency-diff, GET /leaderboard, POST /leaderboard/update, POST /api/scans/org, GET /api/scans/org/{id}/status.
Frontend never sends auth headers:
frontend/src/app/lib/api.ts — all ~25 fetch calls are bare:
const response = await fetch(`${API_BASE}/jobs/${jobId}/findings`); // No auth header
frontend/src/app/hooks/useSingleScan.ts (line 39):
const res = await fetch(`/jobs/${jobId}/findings`); // No auth header
.env — no API key variable exists:
VITE_API_BASE_URL=http://localhost:8000
Impact
When PATCHPILOT_API_KEY is set in production:
- All protected endpoints return HTTP 401
- Findings pages show nothing, dashboard charts are empty, leaderboard fails
- Org scans cannot start
- The app becomes a blank shell with no error messages (401s are silently swallowed)
- Meanwhile, unprotected endpoints (
/scan, /fix, /verify, /evidence-pack, etc.) remain accessible to abuse
Expected Behavior
The frontend must support API key configuration and attach it to all authenticated requests.
Proposed Fix
.env: Add VITE_PATCHPILOT_API_KEY environment variable
api.ts: Create a centralized authFetch wrapper that attaches the Authorization: Bearer header when the API key is configured
- All API functions: Replace bare
fetch calls with authFetch
useSingleScan.ts: Update the raw fetch call to use authFetch
- Add a UI indicator when API key is not configured but backend requires it (show 401 errors instead of silent failures)
Description
When
PATCHPILOT_API_KEYis set in the backend environment,verify_api_keyrequires aBearertoken in theAuthorizationheader. However, the frontend has absolutely no mechanism to store an API key or attach it to fetch requests. Everyfetchcall inapi.tsis a barefetch(url)with no headers. The entire frontend becomes non-functional when authentication is enabled.Actual Behavior
Backend enforces auth on critical endpoints:
backend/app/security.py(lines 10-41):Protected endpoints in
main.py:GET /jobs/{id}/findings,GET /jobs/{id}/verify,GET /trends,GET /cwe-distribution,GET /dependency-diff,GET /leaderboard,POST /leaderboard/update,POST /api/scans/org,GET /api/scans/org/{id}/status.Frontend never sends auth headers:
frontend/src/app/lib/api.ts— all ~25 fetch calls are bare:frontend/src/app/hooks/useSingleScan.ts(line 39):.env— no API key variable exists:Impact
When
PATCHPILOT_API_KEYis set in production:/scan,/fix,/verify,/evidence-pack, etc.) remain accessible to abuseExpected Behavior
The frontend must support API key configuration and attach it to all authenticated requests.
Proposed Fix
.env: AddVITE_PATCHPILOT_API_KEYenvironment variableapi.ts: Create a centralizedauthFetchwrapper that attaches theAuthorization: Bearerheader when the API key is configuredfetchcalls withauthFetchuseSingleScan.ts: Update the rawfetchcall to useauthFetch