Vibe Engines
YouTube
System Design

Design Enterprise SSO

Step 1 / 9

Learn system design by building the identity layer enterprise deals actually stall on.

The numbers to beatper tenantprotocol + configsign the assertionnot just the wrapperpin the certand calendar it

The whole design, in writing

Learn system design by building the identity layer enterprise deals actually stall on. An interactive guide covering multi-tenant SAML and OIDC federation, a stable immutable user key, SCIM provisioning where deactivation is a PATCH rather than a DELETE, group-to-role mapping that survives a reorg, session and token revocation within the promised window, and the audit evidence a security reviewer asks for.

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

Why identity blocks the deal

Nobody has ever lost an enterprise deployment because the model scored two points lower on an eval. They lose it because a security reviewer asked “what happens to access when someone leaves?” and the honest answer was “you email us”.

Build the identity layer properly: federate per tenant, key users on something immutable, provision over SCIM with deactivation handled correctly, map groups to roles through a layer their admin controls, revoke inside the promised window, and log everything a reviewer will ask for.

Step 1 · The skeleton

Let the right people in

The naive version: your own username and password, per user, in your own database. Every enterprise buyer refuses this within one meeting — it means their leavers keep working accounts, their password policy does not apply, and their multi-factor requirement is unenforceable.

Userthe customer’s employeeAuth Servicemulti-tenant
New in this step: User, Auth Service.

Stand up an Auth Service that issues a session after the customer’s own identity system vouches for the user. You are a relying party, never a source of truth. Everything that follows makes that relationship multi-tenant, correct and revocable.

What the new pieces do

Userclient
Signs in with their work account and expects never to see a password prompt from you. They belong to the customer’s directory, not to yours — which is the fact that shapes the entire design.
Auth Servicebackend
Resolves which tenant a sign-in belongs to, then validates the assertion or token against that tenant’s configuration. One deployment, many trust relationships, no shared state between them.

Step 2 · Federate

SAML or OIDC — and the customer decides

One deployment, many customers, each with a different identity provider, a different protocol preference and a different set of attribute names. Hard-coding one of them means the next customer is a fork.

UserIdentity ProviderAuth ServiceSAML / OIDC
New in this step: Identity Provider, SAML / OIDC. · swipe to pan the diagram

A large regulated customer insists on SAML 2.0. OIDC is technically better. What do you do?

  1. All true, and irrelevant. Their federation service and their security team decided years ago. Arguing spends goodwill you need for the questions where you can actually change the outcome.

  2. Protocol is tenant configuration, not an architectural commitment. Large regulated estates hand you SAML with no alternative, and being able to say yes immediately is worth more than the technical argument.

  3. That closes the door on newer estates, mobile flows and machine-to-machine cases, and it commits you to XML signature validation as your only path — which is the easiest thing in this whole design to get subtly wrong.

Make protocol a per-tenant configuration: issuer, certificate, protocol, attribute mapping, all resolved at sign-in. Validate the assertion’s own signature, audience, recipient and time bounds — and pin the certificate with its expiry in a calendar.

  • per tenantprotocol + config
  • sign the assertionnot just the wrapper
  • pin the certand calendar it

What the new pieces do

Identity Providerclient
The customer’s own identity system. It decides who exists, who they are, and — through SCIM — when they stop being an employee. You are a relying party, never the source of truth.
SAML / OIDCservice
Signature on the assertion (not just the response wrapper), audience, recipient, time bounds and in-response-to. Certificate pinned, and its expiry in a calendar — rotation is the classic 12-to-24-month outage.

Back of the envelope

support both, lead with OIDC
the customer decides
validate assertion signature
audience, recipient, time bounds
reject unsigned assertions
no fall-back branch
certificate expiry tracked
the classic 12–24 month outage

Step 3 · Key it correctly

The identifier that does not change

You keyed users on email, and it worked perfectly until the customer was acquired and every address changed on one weekend. Now every user is a stranger, their history is orphaned, and the fix is a data-repair project nobody budgeted for.

SAML / OIDCvalidate the assertionUser Recordimmutable subject id
New in this step: User Record.

Store the User Record under the provider’s immutable subject identifieroid in Entra, a persistent-format NameID in SAML — and treat email as a display attribute that is allowed to change.

  • immutable subject idthe key
  • emaildisplay only
  • retrofit costa data migration

What the new pieces do

User Recordservice
Keyed on the provider’s immutable subject identifier, with email as a display attribute. This one decision is what survives a marriage, a rebrand and an acquisition without a data-repair project.

Back of the envelope

keyed on immutable subject identifier
oid / persistent NameID
email is a mutable attribute
not an identity
attribute mapping explicit per tenant
names differ everywhere

Step 4 · The question that decides

SCIM, and the PATCH nobody implements

Single sign-on answers who is this. It does not answer should this person still have an account. A user removed from the directory cannot sign in — and their account, their API tokens and their scheduled exports all still exist.

Identity ProviderAuth ServiceUser RecordSCIM Endpoint
New in this step: SCIM Endpoint. · swipe to pan the diagram

You implemented SCIM DELETE. The customer offboards someone. What happens?

  1. Only if their identity provider calls DELETE — and most do not. Entra and Okta typically deactivate rather than delete, precisely so that history and audit trails survive the offboarding.

  2. There is no reconciliation sweep in this design, so nothing is delayed. Nothing happens at all, and no error is raised.

  3. The integration reports success, the dashboard stays green, and the departed employee keeps their access. It is the most common enterprise SSO defect there is, and it is exactly what gets tested.

Implement the SCIM Endpoint properly: idempotent creates, filtered lookups, pagination, and PATCH active=false as the primary deactivation path. If you cannot ship SCIM in time, offer a documented daily reconciliation as a compensating control with a date — reviewers accept that far more often than people expect.

  • PATCH active=falsethe real path
  • idempotentproviders retry
  • paginatetenants have thousands

What the new pieces do

SCIM Endpointservice
Idempotent, paginated, and correct about the one operation that matters: deactivation arrives as PATCH active=false far more often than as DELETE.

Back of the envelope

PATCH active=false handled first
DELETE is the rare case
idempotent creates
IdPs replay operations
409 on duplicate userName
correct status codes matter
every operation logged
this is audit evidence

Step 5 · Survive the reorg

Groups map to roles through a layer they control

You mapped their directory groups straight to permissions. It works for a month. Then a reorg renames FIN-AP-ANALYSTS, forty people lose access on a Monday, and you are paged for a change nobody told you about.

SAML / OIDCvalidate the assertionUser Recordimmutable subject idGroup → Rolecustomer-editable
New in this step: Group → Role.

Put a Group → Role table in between, editable by their admin in a screen. Their groups map to your small fixed role set — three is usually enough at go-live — which maps to permissions. Keep data scoping on a separate axis.

  • 3 rolesat go-live
  • their admin editsnot you
  • unmapped→ deny, loudly

What the new pieces do

Group → Roledata
Their directory groups map to your small fixed role set through a table their own admin edits. Data scoping — "approver for EMEA only" — stays on a separate axis, or the role list explodes.

Back of the envelope

customer-editable mapping table
every change logged and attributed
small fixed role set
roles are your product, groups are theirs
data scoping on a separate axis
or the role list explodes
unmapped user denied with a message
never a silent default

Step 6 · Make revocation true

Sessions and tokens die with the account

Deactivation blocks new sign-ins. The user’s current session is still valid, their API token still works, and their nightly export still runs. You committed to revoking access within four hours and you have revoked nothing.

Auth ServiceSAML / OIDCUser RecordSCIM EndpointGroup → RoleSessions + Tokens
New in this step: Sessions + Tokens. · swipe to pan the diagram

Propagate deactivation to Sessions and Tokens: short lifetimes plus a revocation check, so access ends inside the promised window rather than whenever the user next signs in — which may be never.

  • sessionsrevoked
  • API tokensrevoked
  • windowyou promised it

What the new pieces do

Sessions + Tokenscache
Short-lived tokens with a revocation check, so deactivation ends access inside the window you promised rather than at the user’s next sign-in — which may never come.

Back of the envelope

deactivation revokes sessions and tokens
not just new logins
short token lifetimes
bound the worst case
scheduled jobs re-check identity
exports outlive employment

Step 7 · Prove it

The evidence a reviewer asks for

The security review asks for a joiner–mover–leaver walkthrough, an audit log sample, and a break-glass procedure. You have all three behaviours and none of them written down, so the review takes three more weeks.

Auth ServiceUser RecordSCIM EndpointSessions + TokensAudit Log
New in this step: Audit Log. · swipe to pan the diagram

Log to an immutable Audit Log: every authentication, permission change, provisioning event and break-glass use — retained to their policy and exportable to their SIEM. Then package the artefacts: an identity architecture diagram, the JML walkthrough, ten real redacted log lines, the break-glass procedure, and a named gap list with dates.

  • 10 real linesbeat any assurance
  • break-glassthey always ask
  • gap listvolunteered

What the new pieces do

Audit Logdata
Every authentication, permission change, provisioning event and break-glass use — immutable, retained to their policy, exportable to their SIEM. Ten real lines end a review that assurances do not.

Back of the envelope

auth, permission, provisioning, break-glass
all logged immutably
exportable to their SIEM
their tooling, not yours
JML walkthrough written
the leaver paragraph is the one they read
named gaps with dates
volunteered, not discovered

You did it

You just designed enterprise SSO & provisioning.

UserIdentity ProviderAuth ServiceSAML / OIDCUser RecordSCIM EndpointGroup → RoleSessions + TokensAudit Log
The finished design, end to end. · swipe to pan the diagram

Everything you assembled, in order

  • You are a relying party — the customer’s directory decides who exists and who has left.
  • Protocol is per-tenant configuration: support both, lead with OIDC, expect SAML.
  • Key users on the immutable subject identifier; email is a display attribute.
  • Deactivation arrives as PATCH active=false — a DELETE-only SCIM implementation fails silently.
  • Map their groups to your small fixed roles through a table their own admin edits.
  • Revocation must reach live sessions and API tokens inside the window you promised.
  • Package the evidence: diagram, JML walkthrough, real log lines, break-glass, and a volunteered gap list.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing. Answer each one out loud before you open it.

  1. Why is SCIM deactivation the question that decides enterprise deals?

    Because single sign-on answers who a user is and says nothing about whether they should still have an account. A person removed from the customer’s directory can no longer authenticate — but their user record, their issued API tokens, their scheduled exports and their integrations all continue to exist and, in many designs, continue to work. A security reviewer with a compliance obligation asks exactly one question about this, "what happens to access when someone leaves, and within how long?", and they test the answer. The specific trap is that most identity providers deactivate rather than delete, sending PATCH with active set to false so that history and audit trails survive the offboarding. An implementation that only handles DELETE returns success on every request, keeps a green dashboard, and offboards nobody — a control that fails silently, which is the worst possible failure mode for something whose entire value is being verifiable.

  2. Why key users on an immutable subject identifier rather than email?

    Because email addresses change and identities do not. People marry, companies rebrand, and an acquisition can rewrite every address in a directory over one weekend. If your user records are keyed on email, that event turns every existing user into a stranger: their permissions, their history and their audit trail are orphaned, and duplicate accounts appear as people sign in again. The fix afterwards is a data-repair migration that nobody budgeted for, run under time pressure, against a customer who is already unhappy. Keying on the provider’s immutable subject identifier — oid in Entra, a persistent-format NameID in SAML — costs nothing on day one and makes the whole class of problem disappear. Email is still worth storing, as a display attribute that is explicitly allowed to change.

  3. Why put a mapping table between their groups and your permissions?

    Because their group taxonomy is theirs to change and they will change it without telling you. Mapping directory groups straight to permissions works until a reorg renames FIN-AP-ANALYSTS to FIN-OPS-AP-TIER1, at which point forty people lose access on a Monday morning and you are paged for a directory edit you had no visibility into. An indirection layer — their groups map to your small fixed role set, which maps to permissions — turns that into a config change their own admin makes in a screen, with the change logged and attributed. Three roles is usually enough at go-live, and three roles the customer understands beats twelve only you can explain. Two rules make it safe: data-level scoping such as "approver for EMEA only" belongs on a separate axis or the role list explodes combinatorially, and a user who authenticates but matches no mapping must be denied loudly rather than granted a silent default.

  4. What does it actually take to revoke access within four hours?

    More than blocking new sign-ins, which is all that deactivation gives you by default. A user with a live session keeps working, an issued API token keeps working until it expires, and a scheduled export configured under their identity keeps running indefinitely — so a system that only checks status at authentication has revoked nothing measurable. Meeting a stated window means deactivation actively propagates: sessions invalidated, tokens revoked through a revocation check, and long-running jobs re-checking the identity they run as rather than trusting a credential captured at creation. Short token lifetimes bound the worst case so the check does not have to be perfectly synchronous. The clock in any contractual commitment starts at the directory event, not at the user’s next login attempt, which may never come — and that is the distinction most implementations miss until a reviewer asks them to demonstrate it.

  5. What evidence should you have ready before the security review starts?

    Five artefacts, and preparing them takes an afternoon while discovering you need them takes three weeks. A one-page identity architecture diagram showing the provider, the protocol, which claims flow, where the session lives and what talks to what with which identity — reviewers approve things they can picture. A joiner-mover-leaver walkthrough in three short paragraphs, where the leaver paragraph must contain a time bound. Ten real, redacted audit log lines showing authentication events, permission changes and data access, with the retention period stated, because "we log everything" is not evidence and ten lines are. A break-glass procedure describing what happens when their identity provider is down, which every reviewer asks about because the honest answer is often an undocumented local admin account. And a named gap list with dates — volunteering what you do not support yet is counter-intuitive and it is the strongest credibility signal available, because finding what you did not mention is the reviewer’s entire job.

Check yourself — the answers, and why

Eight steps in, these are the calls you should be able to make cold. Pick one, then read why.

  1. A customer insists on SAML 2.0 although OIDC is technically better. You should…

    • Make the technical case for OIDC
    • Support both — protocol is per-tenant configuration
    • Support SAML only

    Their federation service decided years ago. Lead with OIDC, expect SAML, configure per tenant.

  2. User records should be keyed on…

    • Email address
    • The provider’s immutable subject identifier
    • Display name

    Email changes on marriage, rebrand or acquisition; re-keying a live system afterwards is a data migration.

  3. In SCIM, offboarding usually arrives as…

    • DELETE /Users/{id}
    • PATCH active=false
    • A nightly CSV

    Most IdPs deactivate rather than delete. A DELETE-only implementation offboards nobody, silently.

  4. Directory groups should map to permissions…

    • Directly, for simplicity
    • Through a role table the customer’s admin can edit
    • Via a support ticket

    Their groups get renamed in reorgs. Indirection turns an incident into a config change they make themselves.

  5. Revoking access within a promised window requires…

    • Blocking the next sign-in
    • Revoking live sessions and issued API tokens too
    • Rotating the SAML certificate

    A live session or a valid token is still access. The clock starts at the directory event, not at next login.

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Federate: one deployment, many tenants, each with its own identity provider and its own trust configuration.
  • Key correctly: store users under the provider’s immutable subject identifier, never under email.
  • Provision: SCIM create, update and — the one that matters — deactivate, which arrives as a PATCH.
  • Authorise: their groups map to your small fixed role set through a table their admin can edit.
  • Revoke: deactivation kills sessions and API tokens inside the window you promised, not at next login.
  • Evidence: every authentication, permission change and provisioning event logged and exportable.

The qualities that shape everything

Each one names the mechanism that buys it.

Many customers, one deployment
Per-tenant identity configuration resolved at sign-in — issuer, certificate, protocol, attribute mapping — with tenant isolation enforced below the auth layer, not by it.
Identity survives a domain migration
Users keyed on the provider’s immutable subject identifier, with email stored as a display attribute that may change without consequence.
Offboarding actually offboards
SCIM with PATCH active=false handled as the primary deactivation path, not only DELETE — most identity providers never call DELETE.
Authorisation survives a reorg
A customer-editable mapping table between their directory groups and your small fixed role set, so a renamed group is a config change rather than an incident.
Revocation inside the promised window
Deactivation propagates to live sessions and issued API tokens through a revocation check, bounded by short token lifetimes — not deferred to the next sign-in.
A security review that ends
Immutable logs of authentication, permission change, provisioning event and break-glass use, exportable to the customer’s SIEM.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

Keying users on the immutable subject id over keying on email address

Email changes — people marry, companies rebrand, an acquisition rewrites the whole directory. Re-keying a live system after a customer’s domain migration is a data-repair project nobody budgeted for, and it surfaces as duplicate accounts and lost history rather than as a clean error.

Handling SCIM PATCH active=false as the primary path over implementing DELETE only

Most identity providers deactivate rather than delete, so a DELETE-only implementation means offboarding silently does nothing while the integration reports success. It is the single most common enterprise SSO defect and the exact thing a security reviewer tests.

A group-to-role mapping table the customer edits over mapping directory groups straight to permissions

Their groups get renamed in reorgs you are not told about. An indirection layer turns that from a support incident into a config change their own admin makes, and it removes you from a loop that otherwise lasts the whole engagement.

Active revocation of sessions and tokens over checking status at next sign-in

A deactivated user with a live session or a valid API token still has access, so a "revocation" that waits for the next login does not meet any commitment you made. Short token lifetimes plus a revocation check is what makes a four-hour promise true.

Supporting SAML as well as OIDC over OIDC only, on technical merit

OIDC is the better protocol and the customer decides, not you. A large regulated enterprise with a mature federation service will hand you SAML with no alternative — arguing costs goodwill and does not change the outcome, so lead with OIDC and expect SAML.

What this teaches

Learn system design by building the identity layer enterprise deals actually stall on. An interactive guide covering multi-tenant SAML and OIDC federation, a stable immutable user key, SCIM provisioning where deactivation is a PATCH rather than a DELETE, group-to-role mapping that survives a reorg, session and token revocation within the promised window, and the audit evidence a security reviewer asks for.

Key takeaways

  • You are a relying party — the customer’s directory decides who exists and who has left.
  • Protocol is per-tenant configuration: support both, lead with OIDC, expect SAML.
  • Key users on the immutable subject identifier; email is a display attribute.
  • Deactivation arrives as PATCH active=false — a DELETE-only SCIM implementation fails silently.
  • Map their groups to your small fixed roles through a table their own admin edits.
  • Revocation must reach live sessions and API tokens inside the window you promised.
  • Package the evidence: diagram, JML walkthrough, real log lines, break-glass, and a volunteered gap list.

Concepts covered

  • Why identity blocks the deal
  • Let the right people in
  • SAML or OIDC — and the customer decides
  • The identifier that does not change
  • SCIM, and the PATCH nobody implements
  • Groups map to roles through a layer they control
  • Sessions and tokens die with the account
  • The evidence a reviewer asks for
built for the question that decides the deal — what happens to access when someone leaves?
Finished this one? 0 / 65 System Designs done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More System Designs