Building Identity Right (From Someone Who Built an Identity Company)
Lessons Paid For in Scars
I founded LoginRadius in 2012. Over the next decade, we built a Customer Identity and Access Management (CIAM) platform that served over a billion users across hundreds of enterprises. We processed billions of authentications, handled thousands of security incidents, and learned - often the hard way - what works and what doesn't when it comes to identity.
This chapter is the advice I wish someone had given me before I started. It's based on patterns I've seen across hundreds of SaaS companies - the decisions that led to success and the ones that led to painful, expensive rework.
The Identity Stack: What You Actually Need
When founders think about "identity," they usually think about a login page. The reality is much broader. Here's the complete identity stack for a B2B SaaS product:
+-------------------------------------------------------+
| LAYER 5 |
| Identity Analytics |
| (Login patterns, anomaly detection, security alerts) |
+-------------------------------------------------------+
| LAYER 4 |
| Authorization & Access Control |
| (RBAC, ABAC, permissions, entitlements) |
+-------------------------------------------------------+
| LAYER 3 |
| Enterprise Integration |
| (SSO, SCIM, directory sync, JIT provisioning) |
+-------------------------------------------------------+
| LAYER 2 |
| Multi-Factor Authentication |
| (TOTP, SMS, email, push, hardware keys) |
+-------------------------------------------------------+
| LAYER 1 |
| Core Authentication |
| (Registration, login, password management, |
| session management, password reset) |
+-------------------------------------------------------+
Most startups only build Layer 1 and a basic version of Layer 4. Then they spend the next two years retrofitting Layers 2, 3, and 5 when enterprise customers demand them.
What to Build, Buy, and Avoid
After watching hundreds of companies navigate this decision, here's my recommendation matrix:
Build (In-House)
Your authorization model. This is your business logic - who can do what within your application. Nobody else can build this for you because it's unique to your product. Build it from the start with flexibility in mind.
What a flexible authorization model looks like:
# Inflexible (you'll regret this):
if user.role == "admin":
allow()
elif user.role == "member":
deny()
# Flexible (build this instead):
permissions = get_permissions(user, resource, action)
if "documents.edit" in permissions:
allow()
The difference is that the flexible model lets you add roles, change permissions, and implement feature-based access control without rewriting your authorization logic.
Tenant management. How organizations are created, managed, and isolated in your system. This is core to your multi-tenant architecture and shouldn't be outsourced.
Account linking and migration. The logic that connects users across identity providers, handles domain verification for organizations, and migrates users between authentication methods.
Buy (From an Identity Provider)
Core authentication. Login, registration, password hashing, session management, password reset, email verification. This is commodity infrastructure. Every authentication provider does it well. You won't do it better, and the security risk of getting it wrong is enormous.
MFA. TOTP, SMS, email OTP, push notifications, WebAuthn/passkeys. The protocol implementations are complex, the hardware ecosystem is fragmented, and keeping up with new authenticator types is a full-time job.
SSO integration. SAML and OIDC integration with enterprise identity providers. The protocol specifications are dense, enterprise IdPs have quirks, and every customer's setup is slightly different. SSO vendors have handled thousands of these integrations - you shouldn't build that expertise in-house.
Directory sync (SCIM). Automated user provisioning and deprovisioning from enterprise directories. SCIM implementations are surprisingly complex, and the spec is interpreted differently by every identity provider.
Avoid (Common Anti-Patterns)
Don't build your own JWT library. Use a well-maintained, widely-used library for your language. JWT handling has enough subtleties that custom implementations regularly have vulnerabilities.
Don't store sessions in your application database. Use a dedicated session store (Redis, Memcached) or let your auth platform handle sessions. Mixing session data with application data creates performance and security issues.
Don't implement "Remember Me" with long-lived tokens. Use a persistent session with a refresh mechanism. Long-lived tokens that never expire are credentials that never rotate.
Don't build social login from scratch. OAuth/OIDC integrations with Google, GitHub, Microsoft, etc. are provided by every auth platform. Each social provider has its own quirks, deprecation cycles, and API changes. Let someone else handle the maintenance.
Don't build passwordless auth from scratch. Magic links, passkeys, and WebAuthn have complex security requirements. Use a provider that specializes in this.
The general rule: build what's unique to your product (authorization, tenant management). Buy what's commodity infrastructure (authentication, MFA, SSO). Avoid building what looks simple but has deep security complexity (JWT handling, OAuth flows, passwordless auth).
The Auth Stack Decision Tree
Here's a practical decision tree for choosing your identity approach:
What's your stage?
|
+--> Pre-product / MVP
| |
| +--> Use: Firebase Auth or Supabase Auth
| Why: Free/cheap, fast to integrate, sufficient for MVP
| Migrate when: You close your first enterprise deal
|
+--> Post-product, pre-enterprise
| |
| +--> Are you selling to enterprises that need SSO?
| |
| +--> NO: Use Auth0 / Clerk / Stytch
| | Why: Good DX, scales well, has SSO when you need it
| |
| +--> YES: Use WorkOS / Auth0 / Frontegg
| Why: Enterprise SSO is their core feature
|
+--> Enterprise-ready
|
+--> Evaluate: Auth0, Okta CIC, WorkOS, or custom on Keycloak
Why: Full enterprise feature set, compliance-ready
Consider custom only if: you have 2+ dedicated auth engineers
Mistakes I've Seen (And Made)
Mistake 1: The Monolithic User Table
Early-stage companies create a single users table with every field crammed in: name, email, password hash, role, organization, subscription tier, last login, profile picture URL, preferences, and whatever else seems relevant.
This works until it doesn't. The problems:
- Adding organization-level features requires restructuring the entire user model
- Performance degrades as the table grows
- Authorization logic gets tangled with user data
- Multi-tenancy becomes an afterthought bolted onto a single-tenant design
The fix: Separate identity (who the user is) from authorization (what the user can do) from profile (what the user looks like) from the start.
Better structure:
users organizations memberships
------ ------ ------
id (UUID) id (UUID) user_id
email name org_id
password_hash domain role
created_at plan permissions[]
settings created_at
Mistake 2: Email as Primary Identifier
Using email as the primary user identifier seems natural. Everyone has an email. Emails are unique. What could go wrong?
A lot:
- Users change email addresses (job change, marriage, company domain change)
- Email case sensitivity creates bugs (User@Email.com vs user@email.com)
- Some systems don't require verified email, leading to account takeover
- B2B users with multiple organizations may want different emails per org
- Email recycling by providers can give new users access to old accounts
The fix: Use a system-generated UUID as the primary identifier. Email is an attribute, not an identity.
Mistake 3: Rolling Your Own Password Reset
Password reset is one of those features that looks simple and is actually a security minefield.
Common mistakes in homegrown password reset:
- Reset tokens that don't expire (or expire after a week)
- Reset tokens generated with predictable values
- Reset tokens that aren't single-use
- Reset flow that confirms whether an email exists in the system
- Reset link sent over HTTP instead of HTTPS
- No rate limiting on reset requests
The fix: Use your auth platform's password reset. If you must build it yourself, use a cryptographically random token with a 15-minute expiration, single use, and rate-limit requests to 3 per email per hour.
Mistake 4: Ignoring Account Takeover Scenarios
Account takeover (ATO) is the most common attack against SaaS applications. Attackers use credentials leaked from other breaches to try logging into your system (credential stuffing).
Signs you're not prepared:
- No rate limiting on login attempts
- No detection of login from new devices/locations
- No support for MFA
- No breach detection (checking passwords against known breach databases)
- No alerting on unusual login patterns
The fix: Implement credential stuffing protection from day one. Rate limit login attempts (5 per minute per IP, 10 per minute per account). Add new device detection. Support MFA and encourage (or require) its use for admin accounts.
Mistake 5: Hardcoding Roles
# This will haunt you:
if user.role == "admin":
# do admin things
elif user.role == "editor":
# do editor things
elif user.role == "viewer":
# do viewer things
This code is scattered across your codebase. When a customer needs a "billing_admin" role that can manage invoices but not users, you need to change every authorization check.
The fix: Permission-based authorization from day one.
# This scales:
if user.has_permission("users.manage"):
# manage users
if user.has_permission("billing.manage"):
# manage billing
Roles become bundles of permissions that can be created and modified without code changes.
Token Lifecycle Management
One area that trips up every SaaS company eventually is token lifecycle management - how you handle the creation, rotation, revocation, and expiration of the tokens that power your API and integrations.
The Token Lifecycle
Token Created --> Token Active --> Token Rotated --> Token Expired
| |
| v
+--> Token Revoked ----------> Token Dead
Every token in your system needs answers to these questions:
- Who created it? Track the human or system that generated the token for audit purposes.
- When does it expire? Every token should have a maximum lifetime. For API keys, 90-365 days. For session tokens, hours. For OAuth access tokens, minutes.
- How is it rotated? Support overlapping validity periods so customers can rotate without downtime. Issue the new token before the old one expires.
- How is it revoked? Immediate revocation must work. If a customer reports a compromised key, you need to invalidate it in seconds, not minutes.
- What happens to dependent systems? When a token is revoked, what breaks? Make sure your token revocation propagates to all systems that cache or depend on the token.
Common Token Mistakes
Tokens that survive password changes. When a user changes their password, all their active sessions and API tokens should be invalidated. Many SaaS products miss this, leaving active tokens that an attacker with the old password can continue to use.
No token inventory. Users and admins should be able to see all active tokens associated with their account and revoke any of them. If you can't list active tokens, you can't manage them.
Refresh tokens stored insecurely. Refresh tokens are the keys to the kingdom - they generate new access tokens. Store them with the same care as passwords (encrypted at rest, transmitted only over TLS, never logged).
The Identity Maturity Model
Where does your SaaS fall on the identity maturity spectrum?
| Level | Capabilities | Typical Stage |
|---|---|---|
| Level 1: Basic | Email/password login, basic session management | Pre-seed to Seed |
| Level 2: Secure | MFA support, proper password hashing, session security, RBAC | Seed to Series A |
| Level 3: Enterprise-ready | SSO (SAML/OIDC), SCIM, audit logging, fine-grained permissions | Series A to B |
| Level 4: Mature | Adaptive authentication, risk-based access, compliance automation, identity analytics | Series B+ |
| Level 5: Advanced | Passwordless, zero trust, machine identity management, decentralized identity | Market leaders |
Most SaaS companies need to reach Level 3 before they can consistently close enterprise deals. The good news is that buying an auth platform gets you from Level 1 to Level 3 in weeks instead of months.
Don't try to jump from Level 1 to Level 4. Each level builds on the previous one. Companies that skip levels end up with fragile identity systems built on shaky foundations.
The Migration Problem
If you've already built identity in-house and it's causing problems, you face the migration challenge. Here's the honest truth about auth migrations:
They're harder than you think. Every edge case in your identity system is encoded in code scattered across your application. Finding and updating all of it takes longer than expected.
They're riskier than you think. A bug in your auth migration locks users out or, worse, lets the wrong users in. Auth migrations need more testing than any other migration type.
They're more expensive than you think. Plan for 2-4x your initial estimate in engineering time. Plan for customer support volume to increase during the transition.
But they're worth it. The engineering time you recover by not maintaining custom auth infrastructure pays for the migration within 6-12 months.
Migration Strategy
Phase 1: Run in parallel
- New auth system handles new signups
- Existing users continue on old system
- Both systems trusted by application
Phase 2: Gradual migration
- On next login, transparently migrate user to new system
- Verify password with old system, create account in new system
- User experience is seamless
Phase 3: Cleanup
- After 90 days, force-migrate remaining users
- Those who haven't logged in get a password reset email
- Decommission old auth system
For a comprehensive technical guide on authentication implementation patterns and security considerations, see Deepak Gupta's article on authentication implementation for modern applications.
Planning for Scale
Identity systems have a way of becoming bottlenecks at scale. Here are the scaling challenges to plan for early:
Login storms. When your customer base includes companies with thousands of employees who all start work at 9 AM, you get login storms - thousands of authentication requests in a narrow time window. Your auth system needs to handle these spikes without degrading the experience.
Token validation at scale. If your services validate tokens by calling a central auth service on every request, that auth service becomes a single point of failure. Use JWT validation (local cryptographic verification) for high-throughput services, with periodic checks against a revocation list.
Multi-region deployment. When you expand to serve customers in different regions, your identity system needs to follow. Session data, user profiles, and authentication state need to be available in every region with low latency. This is one of the strongest arguments for buying an auth platform - they've already solved multi-region identity.
Data residency. Some customers (especially in the EU) require their identity data to be stored in specific geographic regions. Build your user data model with tenant-level region configuration from the start, even if all your data lives in one region today.
The Bottom Line
Identity is the foundation of your SaaS product's security, user experience, and enterprise readiness. Getting it right doesn't mean building everything yourself - it means making smart decisions about what to build, what to buy, and what to avoid.
The pattern is consistent across every successful SaaS company I've worked with: buy commodity authentication, build custom authorization, avoid reinventing security primitives. This approach lets you ship faster, stay secure, and be enterprise-ready when your first big customer shows up with that 347-question security questionnaire.
Start with the right foundation, and identity becomes a competitive advantage. Start wrong, and you'll be doing a painful migration while your competitors are closing deals.