VibeWeek
Home/Grow/SSO and Enterprise Auth: Unblock the Mid-Market Deal

SSO and Enterprise Auth: Unblock the Mid-Market Deal

⬅️ Growth Overview

SSO and Enterprise Auth for Your New SaaS

Goal: Ship enterprise-grade authentication (SAML SSO, OIDC, SCIM provisioning, enforced 2FA, role-based access control) so that the deal that depends on "your IT requires SSO" can close. Avoid the failure mode where the founder spends 4 weeks building bespoke SAML and the integration breaks every time a new IDP joins.

Process: Follow this chat pattern with your AI coding tool such as Claude or v0.app. Pay attention to the notes in [brackets] and replace the bracketed text with your own content.

Timeframe: Decision on build vs buy in 1 day. SSO via auth provider in 1 week. SCIM in week 2. Enforced 2FA + RBAC + audit-log integration in weeks 3-4. First enterprise customer onboarded by month 2.


Why Most Founder Enterprise-Auth Builds Are a Trap

Three failure modes hit founders the same way:

  • The "we'll roll our own SAML" plan. Founder reads the SAML 2.0 spec, builds a SAML responder, ships v1 to the first enterprise prospect. The prospect's IDP (Okta) works fine; the second customer (Azure AD) breaks because of certificate-handling nuance. The third (PingFederate) breaks because of attribute-mapping differences. Six months in, the founder is the SAML-debugging engineer instead of building product. SAML / OIDC / SCIM are well-defined specs that should be a vendor purchase, not in-house engineering.
  • Adding SSO to free / mid-tier as a "nice to have." Customer pain is real ("we need SSO to use this"); product manager drops it into the standard plan to remove friction. Enterprise budgets evaporate because procurement-grade buyers will not pay enterprise prices for features they get on the standard tier. SSO must be on the enterprise tier specifically because that's what unlocks the procurement-driven pricing model.
  • SSO without SCIM. Customer's IT enforces SSO for login; users still get manually provisioned in your product. When an employee leaves, SSO blocks login but the user record persists with active permissions. This is a security audit failure waiting to happen. SSO + SCIM (automated provisioning + de-provisioning) belong together.

The version that works is structured: pick an enterprise-auth vendor (don't build your own SAML), gate SSO + SCIM behind the enterprise tier, design the role-based permissions model deliberately, and instrument audit logging for every auth event.

This guide assumes you have already done Multi-Tenant Data Isolation (the auth model maps users to tenants), have shipped Audit Logs (auth events feed it), and have considered Pricing Strategy (SSO is an enterprise-tier feature).


When You Need Enterprise Auth

Add enterprise auth when:

  • A specific deal is blocked because the prospect's IT requires SSO
  • You're targeting accounts with 50+ employees where IT has approval authority
  • Your category positions toward mid-market+ buyers (not solo developers / indie hackers)
  • You can charge $1K+/month for the tier that includes it
  • You have at least 50 paying customers (validated PMF; not pre-PMF over-engineering)

Skip enterprise auth when:

  • Your buyer is a solo or small-team purchaser (no IT involvement)
  • You're pre-PMF or pre-revenue
  • Your ARPA is under $200/month with no annual plan (the math fails)
  • No prospect has actually asked for SSO in writing
  • Your auth provider already includes basic SSO at no extra cost (e.g., Clerk, Better Auth) — in which case, expose it on the right tier and skip the dedicated build

The biggest mistake: building enterprise auth speculatively. Wait until at least one named prospect has said "we'd buy if you had SSO." Then build for that prospect specifically.


1. The "Build vs Buy" Decision Is Buy

Almost always.

You're helping me decide on enterprise auth implementation for [your product] at [your-domain.com]. The product is [one-sentence description] with [N paying customers].

The decision tree:

**Option A: Use an enterprise-auth vendor (WorkOS, Stytch, Auth0, Okta CIAM, Frontegg, Descope)**
- Vendor handles SAML / OIDC / SCIM protocol implementation
- You handle the user-experience integration
- Typical cost: $1-3 per active enterprise user/month, often with a $99-$1000/mo platform floor
- Pros: ship in days, not months; vendor handles every IDP edge case; SOC 2 compliance inherited
- Cons: vendor lock-in; per-user fees scale with enterprise customer count

**Option B: Use your existing auth provider's enterprise tier (Clerk, Better Auth, Supabase Auth)**
- If you're already on a modern auth provider, check their enterprise feature set
- Pros: no new vendor, predictable pricing
- Cons: feature parity varies; some providers' enterprise tier is shallow

**Option C: Build it in-house**
- You implement SAML 2.0 + OIDC + SCIM protocols yourself
- Pros: no vendor cost, full control
- Cons: 6-12 weeks of engineering for the first version; ongoing maintenance burden as IDPs evolve; non-trivial security surface; you become the SAML expert on your team forever

For most indie SaaS in 2026: Option A or B. Build-in-house is almost never the right call unless you have specific compliance requirements that vendor solutions can't meet.

For each option, output:
1. The right pick for my stage and customer profile
2. The specific vendor recommendation if Option A (rationale below)
3. The specific feature set I need (SAML SSO + OIDC + SCIM minimum; optionally MFA enforcement, just-in-time provisioning, group sync)
4. The integration plan: which auth flows touch the new system (login, signup, role-management, deactivation)
5. The migration plan: existing users on standard auth → SSO-only auth for enterprise customers

Three principles I've watched founders re-learn:

  • SAML is solved infrastructure. Don't reinvent it. Vendors have spent years on the edge cases; ship via vendor in days.
  • The cost of building in-house compounds. Every new IDP your customers use brings a new edge case; the maintenance never stops.
  • Vendor lock-in is the wrong fear. The vendors that handle SAML are typically open about their data; migration between vendors (WorkOS → Stytch, etc.) is straightforward because the underlying spec is the same.

2. Pick the Right Vendor

The enterprise-auth vendor landscape in 2026 has converged on a few strong options.

Help me pick the enterprise-auth vendor for [your product]. My existing auth setup is [Clerk / Supabase Auth / Better Auth / NextAuth / custom / etc.].

Vendor options:

**WorkOS** — purpose-built for "add SSO to your SaaS"
- Strong SAML + OIDC + SCIM
- Per-active-user pricing; typical $1-3 per enterprise user/mo
- Generous free tier (1M MAU on free)
- Great developer experience; AdminPortal lets your customer's IT admin self-configure
- Indie default in 2026 for adding enterprise auth on top of any existing auth

**Stytch** — broader auth platform with strong enterprise tier
- Includes: SSO, OIDC, SCIM, magic links, passkeys, OAuth
- Replaces existing auth provider OR augments it
- Pricing similar to WorkOS

**Auth0 (Okta)** — the incumbent
- Most features, biggest ecosystem
- Pricing scales aggressively at enterprise tier ($240+/mo for B2B Essentials)
- Brand recognition with enterprise IT teams
- Heavier lift to integrate than WorkOS / Stytch

**Frontegg** — multi-tenant B2B auth platform
- B2B-shaped from day 1
- SSO + SCIM + audit + admin UI for tenants
- Per-tenant pricing model

**Descope** — newer, indie-friendly
- Drag-drop auth flows
- B2B + B2C
- Reasonable pricing

**Clerk** — primarily B2C/SaaS auth, but Enterprise tier includes SAML SSO
- If you're already on Clerk, check the Enterprise plan
- Bundle wins when you don't want a second auth vendor

**Supabase Auth** — primarily for Supabase customers
- SAML SSO available on Pro+
- Use if Supabase is already your stack

**Better Auth** — modern OSS auth library
- Pluggable SSO via vendor adapters; not a turn-key SAML solution
- Pair with WorkOS or Stytch for the SAML layer

For most indie SaaS in 2026 adding enterprise auth on top of an existing auth provider: **WorkOS**. It's purpose-built for this exact problem, has the best DX, and the AdminPortal feature is genuinely useful (customers self-configure SSO).

If you're choosing your primary auth provider and want enterprise built-in: **Stytch** or **Clerk** (Enterprise plan).

Output:
1. The vendor recommendation with rationale for my situation
2. The pricing estimate for my expected enterprise customer base
3. The integration plan: what code changes; what the user-facing UX looks like
4. The customer-onboarding flow: how does an enterprise IT admin configure SSO for their org

The pattern that wins for most indie SaaS: WorkOS layered on top of your existing auth (Clerk / Supabase / Better Auth). Standard customers continue using your existing auth; enterprise customers go through the WorkOS-fronted SSO flow. Both flows resolve to the same user model in your application.


3. Design the Auth Flow

Once the vendor is picked, design the actual login flow with care.

Help me design the auth flow for enterprise customers.

The flow:

**Standard tier**: existing auth (email + password, magic link, OAuth providers) per [your auth provider]

**Enterprise tier**: SSO-only login for that organization
- IT admin configures SSO via vendor's AdminPortal
- Configuration involves: IDP type (Okta / Azure AD / Google Workspace / etc.), metadata XML / OIDC discovery URL, attribute mappings (email, first name, last name, role)
- Once configured, all users in that organization MUST log in via SSO; non-SSO login attempts are rejected for that organization

**The login page logic**:

1. User enters their email
2. System looks up: is this email associated with an SSO-required organization?
3. If yes: redirect to SSO IDP for authentication (then back to your app via SAML response or OIDC callback)
4. If no: standard auth flow (password / magic link / OAuth)

**Edge cases**:

- **Mixed organization**: some employees have email accounts that match the SSO domain; others use external emails
  - Default: every user with the org's email domain is SSO-required
  - Optional: explicit "non-SSO users" allowlist for shared/contractor accounts
- **Organization not yet SSO-configured**: customer just signed up, IT hasn't set up SSO yet
  - Default: standard auth works until SSO is configured
  - Once SSO is enabled, existing standard-auth sessions remain valid until expiry; future logins must use SSO
- **Linking existing accounts**: a user who already has a standard-auth account joins an organization that enables SSO
  - Default: link by email match; existing user record persists
  - Critical: same user_id; different login mechanism

**Just-in-Time (JIT) provisioning**:
- When a user logs in via SSO for the first time, automatically create their user record in your application
- Pull profile data from SSO assertion (email, name, IDP-side groups if available)
- Default role: "member" of the workspace (or a configured default)
- Skip manual invitation flow for SSO-required organizations

Output:
1. The login-page code that handles email-lookup → SSO redirect or standard auth
2. The SSO callback handler that creates / matches user records
3. The JIT provisioning logic + default role assignment
4. The session management: SSO sessions vs standard sessions, expiry, logout behavior
5. The "this organization requires SSO" UX for users who try password login on an SSO-required org

Two principles:

  • Email-domain → SSO-required mapping is the simplest model. Configure once at the organization level; every email matching the org's verified domain follows SSO.
  • JIT provisioning is non-negotiable for enterprise. If users have to be manually invited before they can log in via SSO, IT teams reject your product.

4. Add SCIM (Automated Provisioning and De-Provisioning)

SCIM is the protocol IDPs use to push user lifecycle events to SaaS. SSO without SCIM is a security gap.

Design the SCIM implementation.

SCIM (System for Cross-domain Identity Management) is the standard for automated user provisioning. The IDP (Okta, Azure AD, etc.) tells your application:
- "Add user [email] to organization [X] with role [Y]"
- "Update user [email]'s role from [X] to [Y]"
- "Deactivate user [email] (they left the company)"

Without SCIM:
- Users are added via JIT provisioning (when they first log in)
- Users are NEVER auto-removed when they leave the company
- IT teams have to manually remove users from your app, which they will forget, which is a security audit failure

With SCIM:
- IDP pushes lifecycle events
- Your app processes them: create / update / deactivate users
- Audit-clean lifecycle management

Implementation via vendor:
- WorkOS / Stytch / Auth0 / Frontegg all expose SCIM endpoints; they handle the protocol
- Your application receives webhooks when SCIM events fire
- You implement the user-state changes (create user record, update role, soft-delete user, revoke sessions)

Critical SCIM events to handle:

1. **User.create**: new user added to organization in IDP
   - Create user record (or link existing one by email)
   - Add to workspace with default role
   - Send welcome email if appropriate (or skip for SCIM-provisioned users to reduce noise)

2. **User.update**: user attributes changed (name, email, role, group membership)
   - Update user record
   - If email changed: handle gracefully (link to existing or merge)
   - If role / group changed: update permissions

3. **User.deactivate (or User.delete)**: user removed from IDP
   - Revoke all active sessions for the user
   - Soft-delete the user record (don't lose audit trail)
   - Per [Audit Logs](audit-logs-chat.md): log the deactivation event

4. **Group.create / Group.update / Group.delete**: IDP group changes
   - Map IDP groups to your application's roles
   - Sync group membership to role assignments

Output:
1. The SCIM endpoint configuration (mostly handled by vendor)
2. The webhook handler code for each event type
3. The session-revocation logic for deactivated users
4. The audit-log integration: every SCIM event logged
5. The error-handling: SCIM events that fail to process need retry / alerting
6. The customer-facing documentation: how IT admin configures SCIM after SSO

Critical: deactivation must revoke active sessions IMMEDIATELY. A user who left the company at 5pm shouldn't be able to use a session token at 6pm.

The single most-overlooked SCIM detail: session revocation on deactivate. If your app issues long-lived JWT tokens that don't check user status on every request, a deactivated user can keep using the app for hours. Implement either short-lived tokens with refresh-on-the-fly or a session-active check on every request.


5. Build Role-Based Access Control (RBAC)

Enterprise customers expect granular roles. Design the model deliberately.

Help me design the RBAC model for enterprise customers.

Standard tier (B2B SaaS):
- Member: standard product user
- Admin: workspace admin (invite users, change settings, manage billing)

Enterprise tier (additional roles):
- **Owner**: workspace owner; can transfer ownership; subset of admin rights
- **Member**: standard user
- **Read-only / Viewer**: can view but not modify
- **Custom roles**: enterprise-tier feature; admin defines custom permission sets

Permission categories:
- **Account-level**: billing, member management, workspace settings, integrations
- **Resource-level**: per-record permissions (read, write, delete, share)
- **Audit-level**: who can view audit logs, who can manage SSO config

The implementation:

1. **Roles table**: pre-defined roles + customer-defined custom roles
2. **Permissions table**: granular permissions (e.g., "billing.read", "users.invite", "audit_log.view")
3. **Role_permissions join**: which permissions does each role have
4. **User_roles join**: which roles does each user have in each workspace

The middleware:
- Every request resolves the user's roles in the active workspace
- Permission check: does the user have permission [X] for resource [Y]?
- Cache the role → permission resolution; recompute on role change

Map IDP groups to roles via SCIM:
- Customer admin defines: "Okta group 'engineering-managers' → role 'admin'"
- SCIM events update user_roles based on group membership
- Group membership changes propagate within minutes

Output:
1. The roles + permissions schema
2. The default role definitions for standard + enterprise tiers
3. The custom-role builder UI (enterprise-tier feature)
4. The IDP-group-to-role mapping configuration
5. The permission-check middleware code
6. The audit-log integration: every role/permission change logged

Three principles:

  • Don't ship custom roles until enterprise tier explicitly demands them. The minimum viable model is admin/member/viewer. Custom roles add real complexity.
  • Permission-checks at the framework level, not in route handlers. Per Multi-Tenant Data Isolation: middleware enforces; routes inherit.
  • Group-to-role mapping configured by the customer's IT, not by you. They know their org chart; you don't.

6. Enforce MFA / 2FA for Enterprise

Many enterprise contracts require multi-factor auth.

Design the MFA enforcement for enterprise tier.

Standard tier: 2FA optional (user can enable in settings)

Enterprise tier:
- Workspace admin can enforce 2FA for all members
- Once enforced: every user must enroll 2FA before next login
- Supported methods: TOTP (Google Authenticator, 1Password, Authy), WebAuthn (hardware keys), SMS (less secure; some enterprises ban it)

If SSO is configured for the organization:
- 2FA happens at the IDP (Okta, Azure AD enforce it)
- Your app trusts the IDP's auth assertion
- You don't need to also enforce 2FA at app level (unless contract requires defense-in-depth)

If using direct enterprise auth (no SSO, but enforced 2FA):
- Your app handles 2FA enrollment and verification
- TOTP is the default; offer WebAuthn for higher-security environments
- Disable SMS for enterprise (carrier swap attacks)

The enforcement flow:
- User logs in
- System checks: does this organization require 2FA?
- If yes and user hasn't enrolled: redirect to enrollment page (force enrollment before continuing)
- If yes and user has enrolled: prompt for 2FA code
- If no: proceed with standard auth

Recovery:
- Recovery codes (one-time use, generated at enrollment)
- Admin-driven recovery (workspace admin can reset 2FA for a user, audit-logged)
- Password-reset flow incorporates 2FA recovery if applicable

Output:
1. The 2FA enrollment UX
2. The 2FA enforcement middleware
3. The recovery flow
4. The audit-log integration for 2FA events (enrolled, used, reset)
5. The customer-admin UI for enforcing 2FA workspace-wide

The single most-overlooked detail: disable SMS-based 2FA for enterprise tier. Carrier swap attacks have made SMS 2FA insufficient for enterprise contracts. Default to TOTP + WebAuthn.


7. Document for Buyers and Auditors

Enterprise procurement asks specific questions. Have the answers ready.

Generate the enterprise auth documentation. Lives at /trust/security-auth (linked from [Data Trust](data-trust-chat.md)).

Sections:

**1. Authentication options**
- Standard: email + password, magic link, OAuth (Google / Microsoft)
- Enterprise: SAML SSO, OIDC SSO, optional 2FA enforcement
- SCIM provisioning available on enterprise tier

**2. Identity provider compatibility**
- Tested IDPs: Okta, Azure AD / Microsoft Entra ID, Google Workspace, OneLogin, JumpCloud, PingFederate, ADFS, generic SAML 2.0
- Integration via [vendor — WorkOS / Stytch / etc.]
- Customer-self-service configuration via AdminPortal

**3. SCIM provisioning**
- Supported SCIM 2.0 events: User.create / update / deactivate, Group.create / update / delete
- Tested with: Okta SCIM, Azure AD SCIM, generic SCIM 2.0
- De-provisioning revokes sessions within [N] minutes

**4. RBAC**
- Standard roles: Owner, Admin, Member, Viewer
- Custom roles available on enterprise tier
- Group-to-role mapping configurable

**5. 2FA / MFA**
- Optional on standard tier
- Workspace-enforceable on enterprise tier
- Supported methods: TOTP, WebAuthn (FIDO2), Recovery codes
- SMS disabled on enterprise tier (security)

**6. Session management**
- Session length: [N] hours
- Idle timeout: [N] minutes
- Forced logout on deactivation
- Concurrent session limits configurable

**7. Audit logging**
- Per [Audit Logs](audit-logs-chat.md): every auth event logged
- Available to admins via UI; exportable to SIEM via webhook

**8. Compliance mappings**
- SOC 2 CC6.x (logical access controls)
- ISO 27001 A.9 (access control)
- NIST 800-53 AC controls
- HIPAA technical safeguards if applicable

**9. Known limitations**
- What we don't yet support (e.g., "Active Directory Federation via Kerberos", "PKI client certificate auth")
- Roadmap for upcoming additions

Output the documentation in the same voice as the rest of /trust.

The single most useful section: the IDP compatibility list. Procurement asks "do you work with Azure AD?" The answer "yes, tested" closes the question. The answer "we support generic SAML, you can probably make it work" doesn't.


What Done Looks Like

By end of week 4 of building enterprise auth:

  1. Auth vendor picked and integrated (WorkOS or equivalent)
  2. SAML SSO working for at least one test IDP (Okta most common)
  3. SCIM provisioning wired with create / update / deactivate handlers
  4. RBAC model with at least Owner / Admin / Member / Viewer
  5. Workspace-enforceable 2FA for enterprise customers
  6. Customer-facing AdminPortal for IT to self-configure SSO
  7. Audit-log integration for every auth event
  8. Documentation linked from /trust

Within 90 days:

  • 1+ enterprise customer onboarded via SSO + SCIM
  • Procurement security review completed citing the architecture
  • Zero "user couldn't log in" incidents related to SSO config
  • Post-deactivation session-revocation tested and working

Within 12 months:

  • Multiple enterprise customers using SSO + SCIM in production
  • Tested IDP list grown (Okta + Azure AD + Google Workspace + ...)
  • SOC 2 audit (if pursued) passes auth-related controls
  • Pricing-tier separation working: SSO-driven enterprise contracts at premium tier

Common Pitfalls

  • Building SAML in-house. Almost always wrong. Use a vendor.
  • Putting SSO on the standard tier. Erodes enterprise pricing power.
  • SSO without SCIM. Security audit failure waiting to happen.
  • Session revocation not immediate on deactivate. Departed employees keep access.
  • Custom roles in v1. Premature complexity. Owner / Admin / Member / Viewer first; custom roles later if explicitly requested.
  • No audit logs for auth events. Compliance audits require this.
  • SMS-only 2FA for enterprise. Carrier swap attacks; banned in many enterprise contracts.
  • No customer self-serve config. Forcing customer IT to email you for setup adds friction; AdminPortal-style self-service wins.
  • Forgetting JIT provisioning. SSO without JIT means users can't log in until you manually invite them. Friction kills the deal.
  • Building speculatively before any prospect asked. Wait for the named-prospect demand signal.

Where SSO / Enterprise Auth Plug Into the Rest of the Stack


What's Next

SSO is one of those features that sounds optional in year 1 and becomes a deal-blocker in year 2. The team that ships it deliberately when the first enterprise prospect demands it (not before, not after) unlocks a tier of revenue that's structurally different from self-serve. The team that builds it speculatively in month 4 wastes engineering on a feature nobody is paying for; the team that defers it past the first request loses the deal.

Build the discipline now: vendor-driven implementation, gated to enterprise tier, with SCIM and audit-log integration from day 1. The week you spend on it pays back as a 3-5x ARPA enterprise tier the rest of your year.


⬅️ Growth Overview