Skip to content

Auth Architecture Decisions You Can't Undo

The Decisions That Compound

When you're building a SaaS product, some technical decisions are easy to change later. You can swap databases, refactor APIs, rebuild your UI. Other decisions become load-bearing walls - embedded so deeply into your system that changing them later means rebuilding everything that depends on them.

Authentication architecture is a load-bearing wall.

The choices you make about password storage, session management, token design, and identity architecture in your first six months will affect your product for years. Get them right, and scaling to enterprise customers is straightforward. Get them wrong, and you'll spend months on painful migrations that produce no new features and no revenue.

I've seen this play out hundreds of times - at LoginRadius, we helped organizations manage identity for over a billion users. The patterns of success and failure are remarkably consistent.

Password Storage: Get This Wrong and You're in the News

Let's start with the most fundamental decision: how you store passwords.

The Only Acceptable Approach

User Password --> Bcrypt/Argon2 (with unique salt) --> Hashed Value --> Database

NEVER:
  User Password --> MD5/SHA-256 --> Database
  User Password --> AES Encrypt --> Database
  User Password --> Database (plaintext)

Use bcrypt or argon2id. That's it. These are adaptive hashing algorithms designed specifically for password storage. They're slow by design (making brute force attacks impractical), they handle salting automatically, and they have work factors that can be increased as hardware gets faster.

Do not use:

  • MD5 (broken, fast to crack)
  • SHA-256 (not designed for passwords, too fast)
  • AES encryption (encrypted passwords can be decrypted - hashed passwords can't)
  • Custom hashing schemes (if you're not a cryptographer, you'll get this wrong)
  • Plaintext storage (this still happens, and it still makes the news)

The Configuration That Matters

Bcrypt:
  Work factor: 12 (minimum, increase over time)
  Salt: automatic (built into bcrypt)
  Target hash time: 250-500ms per hash

Argon2id:
  Memory: 64MB minimum
  Iterations: 3
  Parallelism: 1
  Salt length: 16 bytes
  Output length: 32 bytes
Warning

This is a one-way door. If you store passwords with MD5 today and want to switch to bcrypt later, you have two options: (1) force every user to reset their password, or (2) implement a migration scheme that wraps the old hash inside the new one, which adds permanent complexity. Start with bcrypt or argon2 on day one.

Session Management: More Complex Than You Think

Sessions are how your application remembers that a user is authenticated. The session management decisions you make affect security, scalability, and user experience.

Server-Side Sessions vs. JWTs

This is the biggest architectural decision in session management, and the industry has been arguing about it for a decade.

Factor Server-Side Sessions JWTs
Revocation Immediate (delete from store) Difficult (must wait for expiry or maintain blacklist)
Scalability Requires shared session store Stateless - no shared store needed
Storage Server stores session data Client stores token (cookie or localStorage)
Size Small session ID in cookie Larger token (can be several KB)
Complexity Simpler to implement correctly More footguns, harder to get right
Best for Traditional web apps APIs, microservices, mobile apps

My recommendation for most SaaS startups: Use server-side sessions for your web application and JWTs for your API. This gives you the best of both worlds - easy revocation for user sessions and stateless authentication for API clients.

JWT Pitfalls

If you use JWTs, avoid these common mistakes:

Storing sensitive data in the payload. JWTs are base64-encoded, not encrypted. Anyone can decode them. Don't put anything in a JWT that you wouldn't put on a public website.

Using the none algorithm. Some JWT libraries accept tokens with the algorithm set to none - meaning no signature verification. Always explicitly configure your accepted algorithms and reject unsigned tokens.

Excessive token lifetime. I've seen JWTs with 30-day lifetimes. If a token is stolen, the attacker has access for 30 days. Use short-lived access tokens (15-60 minutes) with longer-lived refresh tokens (hours to days).

Not validating all claims. Always validate iss (issuer), aud (audience), exp (expiration), and iat (issued at). Missing validation on any of these opens attack vectors.

Session Configuration Checklist

Regardless of your approach, get these right:

  • Session IDs generated with cryptographically secure random number generator
  • Session cookies set with Secure, HttpOnly, and SameSite=Strict (or Lax)
  • Session timeout: idle timeout (30 minutes) and absolute timeout (8-24 hours)
  • Session regeneration on authentication (prevent session fixation)
  • Session invalidation on password change and logout
  • Concurrent session control (limit active sessions per user)

Token Design: Your API's Identity System

If your SaaS has an API (it should), your token design becomes part of your product's identity system.

API Key Design

Good API Key:
  sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

  Prefix: "sk_live_" (identifies key type and environment)
  Entropy: 32+ random bytes (base62 encoded)
  Storage: Hash the key, store only the hash
  Display: Show only last 4 characters after creation

Bad API Key:
  12345
  user_1_api_key
  base64(username:password)

Key design decisions:

Decision Recommendation Why
Key format Prefixed with type identifier Allows quick identification of key type, environment, and age
Key storage Store only the hash (SHA-256 is fine for this) If your database is breached, keys aren't exposed
Key display Show once on creation, then only last 4 chars Prevents key exposure through UI screenshots or over-the-shoulder viewing
Key rotation Support multiple active keys per account Enables zero-downtime rotation
Key scoping Allow per-key permission scopes Customers can create keys with minimal permissions
Key expiration Optional but encouraged Reduces risk from forgotten or leaked keys

OAuth 2.0 Implementation

If your customers need to integrate your API into their applications (rather than just calling it directly), you'll need OAuth 2.0. The minimum viable OAuth implementation for a B2B SaaS:

  1. Authorization Code flow (for web applications)
  2. Client Credentials flow (for server-to-server integration)
  3. Token introspection (so resource servers can validate tokens)
  4. Token revocation (so customers can invalidate tokens)

Skip the Implicit flow (deprecated and insecure) and the Resource Owner Password flow (anti-pattern for third-party access).

Tip

Don't implement OAuth 2.0 from scratch. Use a battle-tested library or service. The specification has enough nuance that custom implementations almost always have security flaws. Auth0, Keycloak, or language-specific OAuth libraries (like oauthlib for Python or passport for Node.js) are safer starting points.

The Build vs. Buy Decision

This is the most consequential auth architecture decision you'll make. Let's be honest about the tradeoffs.

When to Build Your Own Auth

Build your own authentication if:

  • Auth is your core product (you're building an identity company)
  • You have unique requirements that no existing solution handles
  • You have experienced security engineers on your team
  • You're willing to maintain it forever

When to Buy

Buy an auth solution if:

  • You're building a SaaS product where auth is a feature, not the product
  • You want to ship faster and focus on your core value proposition
  • You don't have dedicated security engineering capacity
  • You need enterprise features (SSO, SCIM, MFA) faster than you could build them

The Real Costs

Building Auth In-House:
  Initial build:          2-4 months of senior engineering time
  Password management:    Ongoing
  MFA support:            1-2 months additional
  SSO (SAML/OIDC):        2-3 months additional
  SCIM provisioning:      1-2 months additional
  Security maintenance:   Ongoing (CVE monitoring, library updates)
  Compliance evidence:    Manual documentation and audit prep
  Total Year 1:           6-12 months of engineering time
  Total Year 1 Cost:      $150K-$400K (engineering time)

Buying Auth (Auth0, Clerk, WorkOS, etc.):
  Integration:            1-2 weeks
  SSO/SCIM:               Configuration, not development
  Maintenance:            Minimal (vendor handles updates)
  Compliance:             Vendor provides SOC 2, audit evidence
  Total Year 1:           2-4 weeks of engineering time
  Total Year 1 Cost:      $10K-$100K (depending on users/features)

For most SaaS startups, buying makes overwhelming sense. The engineering time you save can go toward building features your customers will pay for.

The Hybrid Approach

Many successful SaaS companies use a hybrid: buy an auth platform for the core identity infrastructure (login, registration, password management, MFA) but build custom authorization logic on top of it.

+-----------------------------------+
|          Your Application          |
+-----------------------------------+
|      Custom Authorization          |  <-- You build this
|   (roles, permissions, policies)   |      (it's your business logic)
+-----------------------------------+
|      Auth Platform (Bought)        |  <-- You buy this
|   (login, MFA, SSO, session mgmt) |      (it's commodity infrastructure)
+-----------------------------------+

This is the approach I recommend for most B2B SaaS founders. You get the security and compliance benefits of a mature auth platform while maintaining full control over your application's authorization model.

Multi-Tenancy: The Architecture That Defines Everything

B2B SaaS means multi-tenancy - multiple customers sharing the same infrastructure. How you implement multi-tenancy in your auth system affects everything from data isolation to performance to compliance.

Tenancy Models

Shared database, shared schema: All tenants in the same tables, distinguished by a tenant_id column. Simplest to build, hardest to guarantee isolation. One missing WHERE clause leaks data between tenants.

Shared database, separate schemas: Each tenant gets their own database schema. Better isolation, more complex to manage. Schema migrations must run for every tenant.

Separate databases: Each tenant gets their own database. Best isolation, most complex infrastructure. Required for some compliance regimes (healthcare, government).

The right choice depends on your customer base:

Customer Type Recommended Model Why
SMB (thousands of customers) Shared schema Operational simplicity at scale
Mid-market (hundreds of customers) Separate schemas Balance of isolation and complexity
Enterprise (dozens of large customers) Separate databases Compliance requirements, data residency
Regulated industries Separate databases Legal and regulatory requirements

The Tenant Isolation Imperative

Regardless of your tenancy model, you must guarantee that one tenant's data is never visible to another tenant. This isn't just a security best practice - it's the fundamental promise of your product.

Implement tenant isolation at every layer:

  1. Application layer: Every database query includes tenant context. Use middleware or ORM-level enforcement.
  2. API layer: Every API request is validated against the authenticated tenant. Cross-tenant access returns 403, not 404 (returning 404 leaks the existence of the resource).
  3. Infrastructure layer: Network segmentation, separate encryption keys per tenant (if feasible), isolated compute for high-security tenants.
Warning

A single cross-tenant data leak will destroy customer trust faster than any other security incident. This is the one class of vulnerability where there is no acceptable frequency. Invest in automated testing that specifically checks for tenant isolation at every boundary.

Decisions You'll Wish You Made Earlier

Based on watching hundreds of SaaS companies grow from startup to enterprise, here are decisions that are cheap to make early and expensive to make later:

Use UUIDs for user IDs, not auto-incrementing integers. Sequential IDs leak information (how many users you have, approximately when they signed up) and make enumeration attacks trivial.

Separate authentication from authorization. Auth (who are you?) and authz (what can you do?) should be different systems. Companies that tangle them together spend months separating them later when they need fine-grained permissions.

Design your permission model before you need it. Even if your MVP has two roles (admin and user), design the underlying permission system to support arbitrary roles and permissions. Adding RBAC to a system designed for two hardcoded roles is a painful migration.

Log authentication events from day one. Login attempts (successful and failed), password changes, permission changes, session creation and destruction. You'll need these logs for SOC 2, for incident investigation, and for debugging customer issues.

Support multiple auth methods per user. Users should be able to have both a password and SSO. When you add SSO later (and you will - see Chapter 5), you'll need to link SSO identities to existing accounts without forcing password resets.

Plan for account recovery. What happens when a customer's admin loses access? What happens when a customer's domain changes? What happens when a customer is acquired and their identity provider changes? These scenarios are rare but catastrophic when unplanned.

Note

For a comprehensive guide to authentication implementation, including code-level patterns and security considerations, see Deepak Gupta's article on authentication implementation for modern applications.

Passwordless and Passkeys: The Future Is Already Here

Passkeys - based on the WebAuthn/FIDO2 standard - are replacing passwords. Apple, Google, and Microsoft have all shipped passkey support across their platforms. For SaaS founders, this matters because enterprise customers are increasingly asking about passwordless authentication.

What you need to know:

  • Passkeys are phishing-resistant. Unlike passwords or even TOTP codes, passkeys are bound to the specific website origin. They can't be phished.
  • User experience is superior. Users authenticate with biometrics (fingerprint, face) or device PIN. No password to remember, no code to type.
  • Implementation is available via auth platforms. Auth0, Clerk, and others support passkeys. You don't need to implement WebAuthn yourself.
  • Adoption is early but accelerating. Offer passkeys as an option alongside passwords. Don't make them mandatory yet - not all users are ready.

The practical advice: make sure your auth architecture doesn't assume passwords are the only authentication method. Design your user model to support multiple authentication methods per user (password + passkey, passkey + SSO, etc.). This flexibility will serve you well as the industry moves toward passwordless.

The Decision Tree

Here's a simplified decision tree for your auth architecture:

Start
  |
  +--> Is auth your core product?
  |     |
  |     +--> YES: Build everything. You are the auth company.
  |     |
  |     +--> NO: Continue
  |
  +--> Do you have 2+ senior security engineers?
  |     |
  |     +--> YES: Consider building, but evaluate buy options first
  |     |
  |     +--> NO: Buy an auth platform
  |
  +--> Do you need enterprise SSO within 6 months?
  |     |
  |     +--> YES: Buy with SSO included (WorkOS, Auth0, etc.)
  |     |
  |     +--> NO: Buy a simpler solution, add SSO later
  |
  +--> Multi-tenant authorization needed?
        |
        +--> YES: Build custom authz on top of bought auth
        |
        +--> NO: Bought platform's built-in roles may suffice

The key takeaway: auth architecture is a one-way door for most decisions. The cost of choosing wrong isn't just the rework - it's the months of engineering time that doesn't go toward building your product. Get the fundamentals right early, and auth becomes invisible infrastructure. Get them wrong, and auth becomes a constant source of engineering distraction, security incidents, and enterprise deal blockers.