ADR-001: Use Clerk for Authentication
Status: Accepted Date: 2026-02
Context
Envara requires Google OAuth, Microsoft OAuth (including Azure AD for enterprise), magic link login, session management, multi-provider account linking, and eventually organisation/team support. Building this from scratch would take an estimated 2–3 weeks and introduce ongoing maintenance burden for security-critical code.
Decision
Use Clerk as the authentication provider. Store a local User record in PostgreSQL that links to Clerk's user ID via webhook sync. All application logic references the local User record, never Clerk directly.
Alternatives Considered
| Option | Pros | Cons |
|---|---|---|
| Clerk | Full-featured, Next.js native, org support built-in | Recurring cost (~£25-50/mo at scale), vendor lock-in |
| Better Auth | Open source, self-hosted, no vendor dependency | Newer project, less battle-tested, more setup work |
| NextAuth.js | Popular, free, flexible | DIY session management, no org support, more code to maintain |
| Custom (Passport.js) | Full control | 2–3 weeks build time, ongoing security maintenance |
Consequences
Positive:
- Authentication is production-grade on day one.
- Google OAuth, Microsoft OAuth, magic links, and session management work immediately.
- Organisation support available when needed (post-MVP).
- Clerk handles security patches, token rotation, and brute-force protection.
Negative:
- Monthly cost (acceptable at current scale).
- Vendor dependency — mitigated by the local User table abstraction. If Clerk is swapped, only the webhook sync layer changes.
Architectural constraint: All application code must reference the local User.id, never Clerk.userId. This is enforced by convention and code review.