Align authentication mechanism between API and web client #193

Closed
opened 2026-02-02 17:26:14 +00:00 by jason.woltje · 0 comments
Owner

Problem

API AuthGuard only accepts Bearer tokens, but web client sends cookies (credentials: "include") without attaching a bearer token. This causes 401 errors on all guarded routes.

Locations

  • apps/api/src/auth/auth.guard.ts:11 - Requires Authorization header
  • apps/web/lib/client.ts:31 - Sends credentials: "include"

Mismatch

// API expects
Authorization: Bearer <token>

// Web sends
Cookie: session=xxx

Impact

  • All authenticated API calls fail with 401
  • Web client cannot access protected resources
  • Mixed auth mechanisms create confusion
  • Missing CSRF protection if using cookies

Decision Required

Choose ONE auth mechanism:

  1. Option A: Bearer tokens (recommended for API)
  2. Option B: Session cookies (requires CSRF protection)

Acceptance Criteria

  • DECISION: Choose auth mechanism (Bearer or Cookies)
  • Update AuthGuard to accept chosen mechanism
  • Update web client to send correct auth
  • Add CSRF protection if using cookies
  • Update authentication documentation
  • Add tests for both API and web client auth
  • Verify all protected routes work
// Web client
const token = await getAccessToken();
fetch(url, {
  headers: {
    'Authorization': `Bearer ${token}`,
  },
});

// API guard already supports this

Option B: Session Cookies

// API AuthGuard
const sessionId = req.cookies['session'];
if (!sessionId) throw new UnauthorizedException();

// Web client (no change needed)
fetch(url, { credentials: 'include' });

// MUST add CSRF protection

Testing

  • Test login flow end-to-end
  • Test protected routes accessible
  • Test token/session refresh
  • Test logout clears auth
  • Test concurrent sessions

References

External security review findings (2026-02-02)

## Problem API AuthGuard only accepts Bearer tokens, but web client sends cookies (credentials: "include") without attaching a bearer token. This causes 401 errors on all guarded routes. ## Locations - apps/api/src/auth/auth.guard.ts:11 - Requires Authorization header - apps/web/lib/client.ts:31 - Sends credentials: "include" ## Mismatch ```typescript // API expects Authorization: Bearer <token> // Web sends Cookie: session=xxx ``` ## Impact - All authenticated API calls fail with 401 - Web client cannot access protected resources - Mixed auth mechanisms create confusion - Missing CSRF protection if using cookies ## Decision Required Choose ONE auth mechanism: 1. **Option A: Bearer tokens** (recommended for API) 2. **Option B: Session cookies** (requires CSRF protection) ## Acceptance Criteria - [ ] **DECISION**: Choose auth mechanism (Bearer or Cookies) - [ ] Update AuthGuard to accept chosen mechanism - [ ] Update web client to send correct auth - [ ] Add CSRF protection if using cookies - [ ] Update authentication documentation - [ ] Add tests for both API and web client auth - [ ] Verify all protected routes work ## Option A: Bearer Tokens (Recommended) ```typescript // Web client const token = await getAccessToken(); fetch(url, { headers: { 'Authorization': `Bearer ${token}`, }, }); // API guard already supports this ``` ## Option B: Session Cookies ```typescript // API AuthGuard const sessionId = req.cookies['session']; if (!sessionId) throw new UnauthorizedException(); // Web client (no change needed) fetch(url, { credentials: 'include' }); // MUST add CSRF protection ``` ## Testing - [ ] Test login flow end-to-end - [ ] Test protected routes accessible - [ ] Test token/session refresh - [ ] Test logout clears auth - [ ] Test concurrent sessions ## References External security review findings (2026-02-02)
jason.woltje added the webauthapiapip1 labels 2026-02-02 17:26:14 +00:00
jason.woltje added this to the M7.1-Remediation (0.0.8) milestone 2026-02-03 22:31:44 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaic/stack#193