Auth Without Building Auth
Do not build your own authentication system. This is not a suggestion. It is a rule.
Every startup engineer thinks auth is simple. Email, password, session, done. Then they discover password reset flows. Then email verification. Then rate limiting on login attempts. Then session invalidation across devices. Then MFA. Then OAuth. Then magic links. Then account lockout policies. Then token rotation.
Auth is an iceberg. The login form is the tip. Underneath is a sprawling mess of security edge cases, each one a potential vulnerability. You will get it wrong. Not because you are a bad engineer, but because auth is a specialized domain and you have a product to build.
Why Engineers Build Auth Anyway
The reasons are always the same, and they are always wrong.
Common justifications for building auth:
- "It's just a login form" -> It is never just a login form
- "I don't want vendor lock-in" -> Switching auth providers is easier than maintaining your own
- "Third-party auth is expensive" -> Free tiers cover most startups for years
- "I need custom flows" -> Every provider supports custom flows
- "I want to understand how it works" -> Read about it. Don't ship it.
- "Our use case is unique" -> It almost certainly is not
The real reason is often ego. Engineers like solving hard problems. Auth feels like a hard problem they can solve over a weekend. It is not. It is a hard problem that will consume weeks and still have vulnerabilities.
The Auth Providers
Four providers cover the vast majority of startup needs. Each has a generous free tier and handles the hard parts.
Auth Provider Comparison:
Auth0 (by Okta):
- Free tier: 7,500 active users
- Strengths: mature, enterprise features, extensive docs
- Best for: B2B SaaS that will need SSO and RBAC
Clerk:
- Free tier: 10,000 monthly active users
- Strengths: beautiful pre-built components, modern DX
- Best for: Next.js apps, consumer products
Supabase Auth:
- Free tier: 50,000 monthly active users
- Strengths: integrated with Supabase database, simple
- Best for: apps already using Supabase
Firebase Auth:
- Free tier: unlimited for most auth methods
- Strengths: Google ecosystem, mobile SDKs
- Best for: mobile apps, Google Cloud users
All four handle email/password, OAuth (Google, GitHub, etc.), magic links, MFA, session management, and password resets. Out of the box. Tested by millions of users. Patched within hours when vulnerabilities are found.
What You Get for Free
When you use an auth provider, you are not just getting a login form. You are getting years of security engineering.
What an auth provider handles:
- Password hashing (bcrypt/argon2, properly configured)
- Session token generation (cryptographically secure)
- Session management (creation, validation, revocation)
- Password reset flows (time-limited, single-use tokens)
- Email verification
- Rate limiting on auth endpoints
- Brute force protection (account lockout, CAPTCHA)
- MFA (TOTP, SMS, email, passkeys)
- OAuth integration (Google, GitHub, Apple, etc.)
- JWT issuance and validation
- Token refresh and rotation
- CSRF protection
- XSS protection on auth forms
- Secure cookie configuration
- Account deduplication (same email, different providers)
Building all of this yourself would take months. Maintaining it would be a permanent tax on your engineering bandwidth. And you would still miss edge cases that a dedicated auth team catches.
Integration Patterns
Auth providers integrate with your app in one of two patterns: redirect-based or embedded.
Redirect-based sends users to the provider's hosted login page. This is the most secure option because your app never touches passwords.
Redirect-based flow:
1. User clicks "Sign In"
2. Redirect to provider's hosted login page
3. User authenticates with provider
4. Provider redirects back with token or code
5. Your app validates the token
6. Session established
Used by: Auth0 Universal Login, most OAuth flows
Pros: most secure, provider handles all UI
Cons: less control over the login experience
Embedded uses the provider's SDK to render auth components directly in your app. You get more control over the UI but take on more responsibility.
Embedded flow:
1. User enters credentials in your app
2. Your app sends credentials to provider's API
3. Provider validates and returns tokens
4. Your app stores tokens and establishes session
Used by: Clerk components, Firebase Auth SDK, Supabase Auth
Pros: seamless UI, feels native
Cons: more integration surface, must handle tokens carefully
Both patterns are secure when implemented correctly. For most startups, embedded components from Clerk or Supabase provide the best balance of control and safety.
Real-World Auth Disasters
Companies that built their own auth and regretted it.
Dropbox (2012): A Dropbox employee's password was reused from a LinkedIn breach. Attackers accessed a file containing user email addresses. Dropbox had built custom auth. The incident accelerated their move to more robust authentication practices and eventually adding U2F support.
Uber (2016): Attackers used credentials found in a private GitHub repo to access user data. The auth system did not have adequate access controls or audit logging. Building auth is not just the login form — it is the entire access control layer.
Adobe (2013): 153 million user records leaked. Passwords were encrypted (not hashed) with 3DES in ECB mode, and the encryption key was stored alongside the data. This is what happens when non-specialists implement auth cryptography.
The pattern is consistent: companies with massive engineering teams still get auth wrong. Your three-person startup will not do better.
The "But I Need Custom Flows" Objection
Every auth provider supports customization. The most common custom requirements are all handled.
Custom requirement -> Provider solution:
"I need custom signup fields"
-> All providers support custom user metadata at signup
"I need role-based access"
-> Auth0 has RBAC built in. Others support custom claims.
"I need to restrict signup to certain email domains"
-> All providers support email domain allowlists
"I need passwordless auth"
-> Magic links and passkeys supported by all major providers
"I need to integrate with our existing user database"
-> All providers support migration flows and custom DB connections
"I need custom email templates"
-> All providers allow customizing transactional emails
"I need SSO for enterprise customers"
-> Auth0 and Clerk have enterprise SSO. Critical for B2B.
If your custom requirement genuinely cannot be handled by any auth provider, you have an extremely unusual product and should still start with a provider and customize rather than building from scratch.
Session Management
Sessions are where most custom auth implementations break down. The session lifecycle has more states than engineers expect.
Session states to handle:
- Creation (after successful auth)
- Validation (every protected request)
- Refresh (before token expiration)
- Revocation (logout, password change, suspicious activity)
- Expiration (absolute and idle timeouts)
- Multi-device (user logged in on phone and laptop)
- Cross-tab (multiple browser tabs)
Auth providers handle all of these. They also handle the subtle issues: what happens when a user changes their password on one device, what happens when a session token is stolen, what happens when clock skew causes a token to appear expired.
These are not theoretical concerns. They are daily realities in production auth systems.
The Migration Path
You can always switch auth providers later. It is not fun, but it is not catastrophic either.
Auth provider migration steps:
1. Export user records (email, metadata, roles)
2. Set up new provider with same user schema
3. Import users (most providers have bulk import)
4. Users reset passwords on first login (unavoidable)
5. Update your app to use new provider's SDK
6. Run both providers in parallel during transition
7. Deprecate old provider
The "vendor lock-in" argument against auth providers is weak. Migrating auth providers takes a week or two. Building and maintaining your own auth system takes forever.
Notion migrated from a custom auth system to a provider-based one as they scaled. It was a deliberate decision to stop spending engineering time on a solved problem.
What To Do Right Now
If you are starting a new project, pick an auth provider before you write your first route.
Decision guide:
- Using Next.js? -> Clerk or Auth0
- Using Supabase for your database? -> Supabase Auth
- Building a mobile app? -> Firebase Auth
- Need enterprise SSO soon? -> Auth0
- Want the simplest integration? -> Clerk
- Want the cheapest option? -> Supabase Auth (most generous free tier)
- Not sure? -> Clerk. Best DX, generous free tier, easy to start.
Integration takes an afternoon. You will have signup, login, logout, password reset, OAuth, and session management working before dinner. Then you can go back to building your actual product.
Common Pitfalls
Building "temporary" auth. There is no such thing. That quick auth system you built for the prototype will be in production for years. Start with a provider from day one.
Rolling your own JWT validation. Even if you use a provider for authentication, you might be tempted to manually validate JWTs. Use the provider's SDK or a well-tested library. JWT validation has subtle pitfalls (algorithm confusion, key confusion, clock skew).
Storing tokens in localStorage. Use httpOnly cookies instead. localStorage is accessible to any JavaScript on the page, making it vulnerable to XSS attacks. Auth providers' SDKs handle token storage correctly.
Ignoring the logout flow. Login gets all the attention. But proper logout — invalidating sessions on the server, clearing tokens on the client, handling multi-device logout — is equally important and easy to get wrong.
Not setting up MFA. Your auth provider supports MFA out of the box. Enable it, at least as an option for users. For admin accounts, make it mandatory. This single feature prevents the majority of account takeover attacks.
Key Takeaways
- Authentication is a solved problem. Use a solution. Do not build one.
- Auth0, Clerk, Supabase Auth, and Firebase Auth all have generous free tiers that cover most startups for years.
- You are not just getting a login form. You are getting session management, MFA, OAuth, password resets, brute force protection, and years of security patches.
- Custom requirements are almost always supported by auth providers through configuration, custom claims, or hooks.
- The cost of building your own auth is not the initial implementation. It is the permanent maintenance burden and the vulnerabilities you will inevitably miss.
- Pick a provider, integrate it in an afternoon, and spend your time building the thing that makes your startup unique.