ADR-001: Use Clerk for Authentication¶
Status¶
Accepted (2026-03-06)
Context¶
Reggie originally used Supabase Auth for authentication. This created several problems:
- Dev/prod mismatch: Local dev required 10 Supabase Docker containers (3GB+ images) just for auth + Postgres. Production used RDS with no Supabase, causing migration failures.
- Heavy local setup:
supabase starttook minutes and only Postgres and Auth were actually used. - Auth coupling blocked cleanup: Alembic migrations referenced
auth.users(Supabase-specific schema), forcingSKIP_MIGRATIONS=trueon RDS. - No pre-existing customers: Zero users existed, making this a clean swap with no data migration.
The project needed an auth provider that: - Works with both Next.js frontends and FastAPI backend - Supports networkless JWT verification (no round-trip to auth provider on every request) - Has built-in UI components to reduce frontend auth code - Simplifies local development
Decision¶
Replace Supabase Auth with Clerk across the entire stack.
Architecture after migration:
- Frontend: @clerk/nextjs with ClerkProvider and built-in components (UserButton, Show)
- Backend: RS256 JWT verification using Clerk's PEM public key (networkless -- no API calls to Clerk)
- User linking: profiles.clerk_id column maps Clerk users to Reggie profiles
- Local dev: Clerk keyless mode -- no Clerk account needed, auto-generates temporary keys
What changed:
| Component | From | To |
|-----------|------|----|
| Frontend auth | @supabase/ssr + custom middleware | @clerk/nextjs + clerkMiddleware() |
| Backend JWT | Supabase JWKS/HS256 | Clerk RS256 with PEM key |
| Local database | supabase start (10 containers) | Docker Postgres (1 container) |
| User management | Supabase Dashboard | Clerk Dashboard |
Consequences¶
Easier: - Local dev starts in seconds (1 Docker container vs 10) - No Supabase dependency in production -- clean RDS + ECS architecture - Built-in UI components reduce frontend auth code significantly - Networkless JWT verification means no auth latency on API calls
Harder: - Clerk is a paid service (free tier covers current scale) - Clerk keyless mode is dev-only -- production requires a Clerk account - All existing documentation referencing Supabase Auth needed updating
Related: plans/clerk-auth-migration.md (full implementation plan)