Secure authentication with HttpOnly cookies

✅ merged · #382 · open-legal-products/mike ← open-legal-products/mike · opened 14d ago by willchen96 · merged 14d ago by willchen96 · self · +4,613-2,089 across 106 files · ↗ on GitHub

From the PR description

Summary

Moves browser and Word add-in authentication behind the backend so Supabase access and refresh tokens are no longer exposed to application JavaScript. Closes #164.

What changed

  • Added backend-managed Supabase sessions using Secure, HttpOnly cookies, trusted-origin checks, runtime configuration validation, and authentication rate limits.
  • Added a short-lived encrypted one-time OAuth handoff for the Word add-in, together with the database migration and a same-origin production proxy.
  • Replaced direct frontend Supabase authentication and bearer-token handling with same-origin backend auth APIs.
  • Updated password, MFA, callback, download, MCP, test, deployment, Docker, and Word add-in flows for cookie authentication.
  • Allowed local Supabase OAuth callbacks under https://localhost:3200 so callback query parameters do not fall back to the web login page.

Why

Keeping long-lived authentication tokens in browser-accessible storage increases the impact of an XSS vulnerability. Backend-managed HttpOnly cookies prevent application JavaScript from reading those tokens and give the backend one place to enforce origin and session policy.

Testing performed

  • Backend: 747 tests passed, 25 skipped; TypeScript build passed.
  • Frontend: 618 tests passed; lint passed with 35 existing warnings and no errors.
  • Word add-in: application and E2E typechecks passed; production build passed; two server proxy tests passed.
  • Applied and verified the auth handoff migration against local Supabase.
  • Verified local Supabase retains the complete Word OAuth callback instead of falling back to localhost:3000.

Our analysis

Move authentication behind backend-managed cookies — read the full analysis →

Think the analysis missed something the PR description covers?

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-382.md from inside the repo you want the changes in.

⬇ Download capture-pull-382.md