System Design · step by step

Design Enterprise SSO

Step 1 / 9
The numbers to beatper tenantprotocol + configsign the assertionnot just the wrapperpin the certand calendar it

In the interview room

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.

Functional requirements

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.

Non-functional requirements

The qualities that shape the whole design — 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 idover 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 pathover 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 editsover 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 tokensover 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 OIDCover 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

Design Enterprise SSO & Provisioning — read the full walkthrough as text

the same steps, decisions & trade-offs, for reading, reference & search

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.

How to read this: We add one piece at a time, problem then fix, and the diagram grows. Hit Begin.

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.

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.

You are never the source of truth: The customer’s directory decides who exists and who has left. Every design decision here follows from accepting that and building around it rather than mirroring it.

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.

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

The call: Support both. Lead with OIDC, expect SAML, and configure the protocol per tenant. — 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.

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.

Certificate rotation is the 18-month outage: An IdP certificate expiring is the single most common cause of "nobody can log in this morning" a year or two after a successful go-live. Calendar it at handover, and tell the customer’s team it is theirs to renew.

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.

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.

Never trust a display name as an identity: Names and addresses are for humans. Identity is a stable opaque string, and the cost of getting this wrong is paid years later by someone who was not in the room when it was decided.

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.

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

The call: Nothing happens, and no error is raised — the provider sent PATCH active=false, which you ignored. — 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.

Deactivation is a PATCH, not a DELETE: Write it on the wall. A DELETE-only implementation fails silently, which is the worst possible failure mode for a control whose entire purpose is being verifiable.

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.

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.

Default to deny, and make the empty state loud: A user who authenticates but matches no mapping gets no access and a clear message naming who to ask. Silently granting a default role is how data reaches the wrong department without anyone noticing.

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.

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.

The clock starts at the event, not at next login: Every access-revocation commitment in a contract is measured from the moment the directory changed. Design to that number, and know it before it is written down for you.

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.

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.

Volunteer the gap list: Naming what you do not support yet, with dates, is the strongest credibility signal available in a security review — because finding what you did not mention is precisely the reviewer’s job.

You did it

You just designed enterprise SSO & provisioning.

  • 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.
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.