The average company now runs 93 SaaS applications, according to the Okta Businesses at Work 2024 report, and every one of those apps has to model the same hard problem: keeping one customer's users, roles, and identity providers cleanly separated from the next. Multi-tenant identity management is how a single SaaS codebase serves thousands of customer organizations while giving each one its own login experience, its own identity provider, and its own role model. Get the tenancy boundary right and you can onboard an enterprise customer in an afternoon; get it wrong and you ship a cross-tenant data leak that ends up in a breach disclosure.
Multi-tenant identity management: the architecture pattern by which a single SaaS application authenticates and authorizes users across many isolated customer organizations (tenants), routing each tenant to its own identity provider, enforcing per-tenant role boundaries, and guaranteeing that no user, token, or role from one tenant can ever resolve to another.
About this article:
- Researched and written: June 2026. Last fact-checked: 2026-06-01.
- Author hands-on experience: partial. I'm a founder building multi-tenant identity infrastructure, so the architecture patterns here come from shipping per-tenant SSO and SCIM routing, not from a survey deck.
- AI assistance: used for drafting, reviewed and edited by the named author.
- Conflicts of interest: none. SSOJet is referenced as one option among the build-vs-buy tradeoffs.
- Sponsorship: none.
Key Takeaways
- The three tenant isolation models are silo (one identity store per tenant), pool (all tenants share a store with a tenant_id discriminator), and bridge (a hybrid that silos sensitive tenants while pooling the rest). Most B2B SaaS starts pool and silos its largest customers.
- Per-tenant authentication means each tenant can bring its own IdP: one customer logs in with Okta SAML 2.0, the next with Microsoft Entra ID OIDC, a third with Google Workspace, all against the same app.
- Tenant discovery (resolving which IdP a user belongs to before authentication) is usually solved by email-domain mapping, a tenant-specific subdomain or path, or a tenant picker, then enforced with the SAML AudienceRestriction and OIDC audience claims.
- SCIM 2.0 provisioning must be scoped per tenant: each tenant gets its own bearer token and its own /Users and /Groups endpoints so a deprovision event from one customer never touches another.
- The most common multi-tenant identity failure is a missing tenant check in an authorization path, where a valid token for tenant A is accepted against tenant B's data. NIST SP 800-63B requires session binding that makes this kind of confusion detectable.
What Is Multi-Tenant Identity Management?
Multi-tenant identity management is the set of architectural decisions that let one SaaS application serve many customer organizations while keeping each organization's identities, sessions, and roles fully isolated. A tenant is one customer account: a company, a workspace, a team. Within a tenant you have users, groups, roles, and one or more configured authentication methods. The job of the identity layer is to make sure a request always resolves to exactly one tenant and that authorization decisions are scoped to that tenant.
This is the part of B2B SaaS that quietly gets harder every time you close a bigger deal. A 20-seat startup customer is happy with email and password. A 5,000-seat enterprise customer wants SAML against their own Okta tenant, SCIM-driven provisioning, and proof that their users can't see anyone else's data. The same login box has to serve both. If you're mapping the broader landscape first, our guide to enterprise identity management for SaaS covers where tenancy fits among SSO, SCIM, and audit logging.
What Are the Tenant Isolation Models: Silo, Pool, and Bridge?
There are three isolation models, and the choice drives your data layout, your blast radius, and your per-tenant cost. The silo model gives each tenant its own identity store (its own database or its own schema). The pool model puts all tenants in a shared store and separates them with a tenant_id column on every identity row. The bridge model is a hybrid: pool the long tail of small tenants, silo the few large or regulated ones.
Pool is the default for most B2B SaaS because it's cheap and operationally simple: one schema, one set of migrations, one connection pool. The risk is that isolation now depends entirely on application code. Every query needs a WHERE tenant_id = ? predicate, and one missing predicate is a cross-tenant leak. Postgres row-level security (RLS) is the standard mitigation, pushing the tenant filter into the database so a forgotten clause fails closed instead of leaking.
Silo trades cost for blast radius. A noisy or breached tenant is contained in its own store, and you can give a paranoid enterprise customer a literal dedicated database. The cost is operational: schema migrations now fan out across hundreds of stores, and per-tenant connection overhead grows. Bridge is where mature platforms land, and it maps cleanly onto pricing tiers: your enterprise SKU buys a siloed identity store, your self-serve tier shares the pool.
The three models break down like this:
- Silo: one identity store per tenant. Blast radius is a single tenant. Best for regulated or large enterprise tenants that demand hard isolation.
- Pool: a shared store with a tenant_id discriminator on every row. Blast radius is all tenants if a query forgets its filter. Best for self-serve and SMB scale.
- Bridge: pool most tenants, silo the selected few. Blast radius is tiered. Best for B2B SaaS spanning SMB to enterprise on a single platform.
How Should You Model Tenants, Organizations, and Users?
Your data model needs a tenant (or organization) as a first-class entity that owns users, roles, and authentication connections, with a membership join table linking users to tenants. The mistake teams make early is treating user and tenant as a one-to-one relationship. The moment a consultant belongs to two customer orgs, or a user moves from one company to another, a one-to-one model forces you to duplicate the user and split their identity.
Model it as many-to-many from day one. A users table holds the global identity (the email, the credential), a tenants table holds the organization, and a memberships table carries the user-to-tenant link plus that user's role within that specific tenant. This is what lets the same human hold an admin role in tenant A and a read-only role in tenant B without two accounts. It also makes tenant discovery tractable, because you can look up which tenants an email is a member of before you decide how to authenticate them. For the deeper definitions, the SaaS identity management glossary breaks down the tenant, organization, and membership terms.
How Do You Support a Different IdP per Tenant?
Per-tenant authentication means each tenant configures its own identity provider, and your app routes each login to the right one. One tenant authenticates with Okta over SAML 2.0, another with Microsoft Entra ID over OIDC, a third with Google Workspace, and a long tail still uses your built-in email and password. The connection config (the SAML metadata, the entityID, the signing certificate, or the OIDC client_id and issuer) is stored against the tenant, not globally.
The protocol routing is where most teams underestimate the work. For SAML, each tenant needs its own Assertion Consumer Service handling, and you validate the inbound SAMLResponse against that tenant's certificate, check the AudienceRestriction matches your SP entityID, verify NotOnOrAfter and the InResponseTo for SP-initiated flows, and carry tenant context through RelayState so the callback lands in the right tenant. For OIDC, you validate the issuer and audience claims against the tenant's registered client. Get the AudienceRestriction or audience check wrong and you've built a confused-deputy bug where tenant B's IdP can mint a session your app accepts. The SAML glossary is a useful reference for the assertion fields that carry tenant binding.
This per-IdP, per-tenant routing is the piece SSOJet exists to absorb. Instead of building SAML and OIDC connection management, certificate rotation, and tenant routing yourself, you point each tenant at a connection and let the broker normalize Okta, Entra ID, and Google into one callback. Our SSO for B2B SaaS layer is specifically the per-tenant IdP routing problem, so engineering teams don't own xmlsec and per-IdP edge cases. That's an honest build-vs-buy call: the routing logic is buildable, it's just deceptively expensive to maintain across dozens of IdP quirks.
How Does Tenant Discovery Work Before Authentication?
Tenant discovery is the step that decides which tenant (and therefore which IdP) a login belongs to, and it has to happen before you can authenticate. You can't validate a SAML assertion until you know whose certificate to check it against. There are three common patterns, and many platforms combine them.
Email-domain mapping is the most seamless: a user types jordan@acme.com, you look up that acme.com is claimed by the Acme tenant, and you redirect straight to Acme's Okta. Subdomain or path routing uses acme.yourapp.com or yourapp.com/acme to carry the tenant identity in the URL, which is explicit and cache-friendly. The tenant picker is the fallback: when a user belongs to multiple tenants or their domain is ambiguous (a gmail.com address can't be domain-mapped), you show them a chooser. Whichever you use, the resolved tenant must be carried into the auth request and re-verified on the callback, because a discovery hint from the browser is not a trust boundary.
RBAC vs Per-Tenant Roles: How Should Authorization Work?
Authorization in a multi-tenant system is always two questions answered in order: which tenant is this request scoped to, and what role does this user hold within that tenant. RBAC (role-based access control) defines roles like admin, member, and viewer, but in multi-tenancy a user's role is a property of the membership, not of the global user. The same person can be an admin in one tenant and a viewer in another, so the role lookup must always be keyed by (user, tenant).
A clean pattern is a small set of system roles you define globally, plus optional per-tenant custom roles for enterprise customers who want their own role names and permission sets. Permission checks then resolve in two layers: confirm the request's tenant matches the user's active membership, then evaluate the role's permissions within that tenant. The cross-tenant authorization bug, accepting a token valid for tenant A against tenant B's resources, is the single most dangerous failure in this space, and it's why every authorization middleware should fail closed when the token's tenant claim doesn't match the resource's tenant. This is also why session binding matters: NIST SP 800-63B specifies that sessions be bound such that tokens can't be silently reused out of context, which in practice means stamping the tenant into the session and re-checking it on every request.
How Do You Run SCIM Provisioning per Tenant?
SCIM 2.0 provisioning has to be scoped per tenant: each customer's IdP gets its own bearer token and its own set of /Users and /Groups endpoints, so a deprovision from one tenant can never deactivate a user in another. When an enterprise customer's Okta pushes a SCIM request to your /Users endpoint, the bearer token on that request is what identifies the tenant. That token-to-tenant mapping is the entire security boundary, so token issuance, storage, and rotation are per-tenant operations.
Pair SCIM with JIT (just-in-time) provisioning for the gaps. SCIM handles the lifecycle authoritatively (create on hire, update on role change, deactivate on offboard), while JIT creates a user on first SSO login for tenants that haven't wired up SCIM. The two have to agree on the same tenant membership model, or you get duplicate users when a JIT-created account later collides with a SCIM push. For the provisioning side specifically, our directory sync for B2B SaaS product runs the per-tenant SCIM endpoints and token scoping so you don't build the deprovisioning blast-radius controls yourself. If you want the migration angle on retrofitting this, the walkthrough on adding enterprise SSO to multi-tenant SaaS covers wiring tenancy into an app that didn't start with it.
How Do You Scale Identity Across Thousands of Tenants?
Scaling identity across thousands of tenants is mostly about making per-tenant configuration fast to read and cheap to change, because authentication is on the hot path of every request. Connection metadata, signing certificates, role definitions, and domain mappings all get read on login, so they need to be cached with per-tenant invalidation. A certificate rotation for one tenant should not require flushing the whole cache.
Three things break first at scale. Certificate and secret rotation becomes an operational program once you have thousands of SAML connections, because every IdP cert has an expiry and a silent expiry is an outage for that tenant. Tenant onboarding becomes a self-serve flow rather than a support ticket, which means admins need a way to upload their own metadata and test it (an OIDC playground style validator helps here). And the noisy-neighbor problem shows up in your token-validation path, where one tenant's traffic spike can starve others unless you isolate or rate-limit per tenant. Pooling is efficient until one tenant's behavior becomes everyone's problem, which is exactly the moment the bridge model earns its cost.
What Are the Common Multi-Tenant Identity Architecture Pitfalls?
The pitfalls are consistent across teams, and almost all of them are tenant-context bugs rather than crypto bugs. The classics: a missing tenant predicate in a query, a token whose tenant claim is never checked against the resource, a JIT flow that creates users without binding them to the discovered tenant, and a tenant picker that's treated as authoritative instead of a hint.
The subtler ones bite later. Sharing a single SCIM bearer token across tenants collapses your provisioning isolation. Caching IdP metadata without per-tenant invalidation means a cert rotation silently breaks logins. Storing roles on the user instead of the membership makes the same account behave identically in every tenant, which is wrong the first time someone belongs to two. And treating tenant discovery as a security boundary, instead of re-verifying the resolved tenant on the authenticated callback, is how confused-deputy bugs ship. The fix for all of these is the same discipline: tenant is a claim that gets verified at every boundary, never assumed from the last hop.
Frequently Asked Questions
What is the difference between multi-tenant and single-tenant identity management?
Single-tenant identity management serves one organization with one identity store, one set of roles, and usually one identity provider. Multi-tenant identity management serves many isolated customer organizations from a shared application, routing each tenant to its own IdP and scoping every role and authorization check to a specific tenant. The defining requirement of multi-tenancy is that no user, token, or role from one tenant can resolve to another.
Should I use the silo, pool, or bridge isolation model?
Start with the pool model if you're early-stage B2B SaaS, because a shared store with a tenant_id discriminator is cheapest to build and operate, ideally with database row-level security enforcing the tenant filter. Move to the bridge model as you close larger deals, siloing your biggest or most regulated tenants into dedicated stores while keeping the long tail pooled. Pure silo is justified mainly when contracts or regulations require physically separated data per customer.
How do I let each tenant use its own identity provider?
Store the IdP connection config (SAML metadata and certificate, or OIDC client_id and issuer) against the tenant rather than globally, then resolve the tenant during discovery before you authenticate. On the callback, validate the assertion against that specific tenant's certificate and confirm the SAML AudienceRestriction or OIDC audience claim matches before issuing a session. A broker like SSOJet handles this per-tenant routing across Okta, Microsoft Entra ID, and Google Workspace so you don't maintain per-IdP code.
How does SCIM provisioning work in a multi-tenant SaaS?
Each tenant's identity provider gets its own SCIM 2.0 bearer token and its own /Users and /Groups endpoints, and that token is what identifies the tenant on every provisioning request. This per-tenant token scoping is the security boundary that guarantees a deprovision event from one customer can never deactivate a user in another tenant. Pair SCIM with JIT provisioning so users who log in via SSO before SCIM is configured still get created and bound to the correct tenant.
What is the most dangerous bug in multi-tenant identity management?
The most dangerous bug is cross-tenant authorization, where a valid token for one tenant is accepted against another tenant's resources because an authorization path failed to check that the token's tenant matches the resource's tenant. It leaks one customer's data to another and typically becomes a reportable breach. The defense is to treat tenant as a claim verified at every boundary and to make authorization middleware fail closed whenever the tenant claim and the resource tenant disagree.
Final Thoughts
Multi-tenant identity management comes down to one invariant: every request resolves to exactly one tenant, and that tenant is verified, never assumed, at every boundary. Pick an isolation model that matches your customer mix, store IdP config per tenant, scope SCIM tokens per tenant, and key every role off membership rather than the global user. The routing and protocol plumbing is buildable, but it's the kind of surface area that's far cheaper to broker than to own across every IdP quirk.
Sources
- Okta Businesses at Work 2024 report, average of 93 SaaS apps per company: https://www.okta.com/newsroom/articles/businesses-at-work-2024/ (verified 2026-06-01)
- NIST SP 800-63B, Digital Identity Guidelines (session binding and management): https://pages.nist.gov/800-63-3/sp800-63b.html (verified 2026-06-01)
Top comments (0)