What is multi-tenant authorization?
Multi-tenant authorization determines whether a specific principal may perform a specific action on a specific resource within a specific tenant. A safe decision needs all five parts: principal, tenant, action, resource, and relevant context.
Authentication proves who the principal is. Tenant membership proves which customer organizations that principal belongs to. Authorization decides what the principal may do inside the active tenant. Tenant isolation prevents the request from reaching another tenant's resources, even when the person is otherwise authenticated and has a valid role.
Never authorize from a role alone. Authorize the tuple: principal + active tenant + action + resource + context. A user can be an administrator in Tenant A and a viewer in Tenant B.
For many B2B SaaS products, a practical starting point is tenant-scoped RBAC: store membership separately from the user, assign roles to that membership, resolve one active tenant per request, scope the resource to that tenant, deny by default, and check permissions in a shared policy layer. Add attributes or resource relationships only when the product has rules that roles cannot express cleanly.
This is a product model as much as a security model. Invitations, team administration, enterprise SSO, service accounts, API keys, plan entitlements, approvals, temporary access, support operations, and offboarding all depend on it.
This guide focuses on identity and access decisions. See the broader multi-tenant architecture guide for pool, silo, and bridge models, and the multi-tenant data architecture guide for database isolation, row-level security, restore, and tenant movement.
Related controls solve different problems
Authentication, authorization, and tenant isolation
A common design mistake is treating a successful login as sufficient protection. AWS explicitly separates these concepts: a person can be authenticated and authorized for an action while the system still applies that action to the wrong tenant.
Who are you?
Verify a human or workload identity through a session, federation, passkey, certificate, API credential, or another approved mechanism. The result is a stable principal, not permission to every resource.
What may you do here?
Evaluate the principal's membership, role, attributes, resource relationships, action, and contextual policy for the active tenant. The result should be an explicit allow or deny.
Is this the right tenant?
Bind the request, resource, data access, files, cache, jobs, and downstream calls to the resolved tenant. Isolation limits the blast radius of mistakes in any one layer.
These controls should reinforce one another. Authorization can reject a cross-tenant resource. Tenant-scoped repositories can make that resource impossible to load. Row-level security can reject the query again. Storage prefixes, queue payloads, cache keys, and audit records can preserve the same tenant boundary.
Resolve context before making the decision
Multi-tenant authorization architecture diagram
The policy decision should receive normalized application facts, not infer a tenant from an untrusted URL or accept a client-supplied role. The application verifies identity, resolves membership and the active tenant, loads the target resource through that tenant, and then requests a decision.
Authorization control plane
A policy engine can run as a library, a sidecar, a shared service, or a managed authorization system. The product does not need a separate service on day one. It does need one consistent decision contract and clear enforcement boundaries.
Users and tenants have a many-to-many relationship
Model identity, tenants, and memberships separately
A user is a global identity in the product. A tenant is a customer organization or workspace. A membership connects one user to one tenant and holds the status and authorization assignments that apply there.
id · identity_provider_subject · statusOne human can join multiple tenantsid · name · tier · statusThe customer security boundarytenant_id · user_id · status · joined_atUNIQUE (tenant_id, user_id)membership_id · role_id · scope_type · scope_idRoles belong to a tenant membershipDo not put one global role on the user when permissions vary by organization.
- 01
Use stable identity keys
Match federated identities by the issuer and immutable subject identifier, not by email address alone. Email addresses can change, aliases can collide, and an identity provider can verify the same address in a different security domain.
- 02
Make membership state explicit
Invited, active, suspended, and removed are different states. A pending invitation should not receive ordinary member access. Suspension should stop new sessions and sensitive operations without destroying the audit trail.
- 03
Delegate assignments deliberately
Most B2B products allow tenant administrators to manage their own members and roles. Protect the rules around owner transfer, last-owner removal, privileged role grants, domain claims, and enterprise provisioning.
- 04
Separate workforce and customer administration
A platform operator is not a tenant administrator. Internal support and operations need their own identities, policies, approval paths, audit events, and constrained tools.
- 05
Model workloads as principals
Service accounts, API clients, agents, integrations, and scheduled processes should receive their own tenant-scoped identities and permissions. Do not make automation impersonate a permanent superuser.
One identity can work in several organizations
Resolve and verify the active tenant
Microsoft's multitenant identity guidance describes two common approaches. The identity system can issue a token containing the selected tenant and role, or the application can keep tokens tenant-agnostic and look up memberships itself. Both can work when the trust boundary is explicit.
Select
After authentication, show only tenants with an active membership. A subdomain, route, or last-used tenant can suggest context, but the server must still verify membership.
Bind
Bind the active tenant to the server-side session or issue a tenant-specific token. Do not accept a tenant header as proof merely because the client supplied it.
Resolve
Load the membership and its current assignments. Decide how quickly role changes, suspensions, and tenant deletion must invalidate cached or tokenized state.
Scope
Load target resources through the active tenant. A globally loaded record followed by a late tenant check creates more room for leaks in errors, logs, serializers, or side effects.
Switch
Switching tenants should establish fresh context. Microsoft notes that a token containing tenant-specific claims might need to be reissued when a user changes the active tenant.
Clear
Logout, account switching, impersonation exit, and pooled execution contexts must clear the previous tenant. Stale context is a cross-tenant incident waiting to happen.
Make the active tenant visible in the interface, especially around destructive actions. Server enforcement is essential, but clear context also prevents a legitimate user from changing the wrong organization by mistake.
Use the simplest model that expresses the product
RBAC, ABAC, and relationship-based authorization
NIST defines RBAC around users, roles, permissions, operations, and objects. NIST defines ABAC as evaluating attributes of the subject, object, operation, and sometimes the environment against policy. Google's Zanzibar paper demonstrates a relationship-based model at enormous scale, but most SaaS products do not need Zanzibar's distributed architecture to use relationships as a policy input.
A useful progression is RBAC first, RBAC plus a few explicit resource checks second, and a policy engine or relationship model when repeated rules justify it. Avoid creating a new role for every combination of project, region, approval limit, and feature. That is attribute or relationship data disguised as roles.
Separate policy management, decisions, and enforcement
Design the authorization policy architecture
AWS describes three useful responsibilities: the policy administration point manages policy, the policy decision point evaluates a request, and policy enforcement points apply the decision. These are logical boundaries even when they begin in one application process.
Policy administration point
Stores role definitions, permission mappings, custom tenant roles, resource relationships, and policy versions. Its administrative API needs authorization too. A tenant admin should not edit another tenant's role or grant a permission the product does not allow them to delegate.
Policy decision point
Accepts normalized facts and returns a decision. Keep it deterministic, deny on missing required context, define timeout behavior, and make policy version and reason available for debugging without exposing sensitive internals to end users.
Policy enforcement point
Sits at the operation boundary and enforces the result before a side effect. API middleware can establish context, but the endpoint or domain operation still knows the resource and action being authorized.
Policy information
Membership status, resource ownership, tenant tier, approval limits, time, network, and other attributes must be current enough for the risk. Define the source of truth and cache invalidation rather than letting every service invent its own facts.
Shared policy store
A pooled store is efficient for many tenants with a common model. Every policy and relationship needs tenant scope, and the decision request must never mix principal, policy, or resource context across tenants.
Per-tenant policy store
A dedicated store can support unique enterprise policies and reduce the impact of policy mistakes. AWS notes that it strengthens isolation but increases tenant onboarding, deployment, and operational work.
Centralized policy does not mean every request must make a fragile network round trip. A library, sidecar, replicated policy bundle, or service can all preserve the same model. Choose based on latency, consistency, deployment, language, policy ownership, and failure requirements.
Protect operations, not just pages
Place authorization at every enforcement boundary
- 01
Map product verbs to explicit actions
Use stable actions such as project.read, member.invite, invoice.refund, or export.create. Avoid vague checks like is_admin? scattered through controllers, templates, and workers.
- 02
Authorize server-side on every request
OWASP recommends validating permissions on every request and denying by default. Hiding a button improves usability but does not protect the endpoint, GraphQL resolver, file URL, bulk action, or alternate client.
- 03
Load resources inside tenant scope
Prefer tenant.projects.find(id) to a global Project.find(id) followed by a check. Return a response that does not reveal whether an inaccessible cross-tenant resource exists.
- 04
Check before the first side effect
Authorize before writes, emails, webhooks, exports, billing calls, queue publication, or file generation. A later denial cannot undo information already sent or money already moved.
- 05
Recheck sensitive state at execution time
For delayed approvals, jobs, or downloads, do not assume the permission from when work was scheduled remains valid. Re-evaluate current membership, resource state, and policy when the operation executes.
- 06
Constrain list and search results
Authorization is not only a single-record check. Queries, counts, suggestions, search indexes, exports, notifications, and activity feeds must return only resources visible in the active tenant and scope.
- 07
Make bulk actions atomic in policy
Define whether access is all-or-nothing or item-by-item. Never authorize the first record and assume the rest share its tenant, owner, or classification.
Tokens carry claims, not eternal truth
Design tenant-aware sessions and access tokens
A token can carry the principal, issuer, audience, active tenant, role, scope, authentication method, and expiry. Each claim has a lifecycle. A long-lived role claim remains valid after an administrator removes that role unless the system rechecks state or invalidates the token.
Validate issuer and audience
Accept tokens only from the expected issuer and for the intended API. In systems that support several identity providers, prevent an identity from one issuer being confused with another.
Bind tenant context
If the token includes a tenant claim, verify that the principal still has an active membership and that the requested resource belongs to the same tenant. The claim is context, not a substitute for resource isolation.
Keep privilege short-lived
Use short access-token lifetimes for high-change authorization data, rotate or sender-constrain refresh tokens where appropriate, and define emergency revocation for removed members and compromised accounts.
Limit token privilege
RFC 9700 recommends restricting access token privileges to the minimum resources and actions needed. Separate audiences and narrow scopes reduce what a stolen token can reach.
Do not place every dynamic resource permission into a large token. It becomes stale, exposes internal structure, increases request size, and makes revocation difficult. Tokens are a good place for stable identity and coarse context; the application or policy system can resolve current fine-grained access.
Permissions change throughout the customer relationship
Plan the multi-tenant authorization lifecycle
Invite
Bind the invitation to one tenant, intended role, expiry, and single-use secret. Decide how to handle an existing identity, a changed email, revoked invitation, and enterprise domain policy.
Provision
Create memberships through admin action, approved domain discovery, just-in-time SSO, or a directory provisioning protocol. Define which identity source owns display data, status, groups, and removal.
Change access
Audit who changed which assignment, in which tenant, from what to what, and when. Protect privileged grants, owner transfer, custom role editing, and separation-of-duty rules.
Review
Give tenant administrators a comprehensible view of members, service accounts, roles, pending invitations, last activity, and high-risk access. Make unused and inherited permissions visible.
Suspend or remove
Stop new access, revoke sessions or credentials according to risk, cancel pending jobs where needed, remove group-derived access, and preserve the audit trail without leaving ownership ambiguous.
Delete the tenant
Disable identities, API keys, integrations, policy stores, invitations, exports, and support sessions as part of the tenant deletion workflow. Authorization state is tenant data too.
The web request is only one execution path
Authorize jobs, integrations, and support access
Carry explicit tenant context
Queue tenant ID, initiating principal, requested action, and resource reference. Resolve current state when the job runs, use a scoped service identity, and prevent retries from crossing tenants or repeating forbidden side effects.
Grant narrow workload access
Issue tenant-bound credentials with explicit scopes, owners, expiry or rotation, and last-used visibility. A webhook signing secret proves source authenticity; it does not decide which tenant resource an event may change.
Use controlled elevation
Require a reason, target tenant, limited duration, appropriate approval, visible customer context, and an immutable audit trail. Prefer purpose-built support operations over unrestricted database access.
Platform administration is intentionally cross-tenant, so its failure impact is larger. Keep it on a separate authorization path with stronger authentication, narrower tools, additional monitoring, and no accidental inheritance from customer roles.
Prove denial as rigorously as success
Test and observe multi-tenant access control
- 01
Write a permission matrix
List roles or attributes against product actions and resource scopes. Include ordinary members, tenant administrators, removed users, service accounts, internal support, and unauthenticated requests.
- 02
Generate cross-tenant negative tests
For every protected operation, create the same resource in Tenant A and Tenant B. Confirm that a principal from A cannot read, infer, mutate, export, link, search, or trigger work for B.
- 03
Test context changes
Switch tenants through the same browser session and execution pool. Remove a role while a session is active. Suspend a membership before a queued job runs. Verify that stale state fails safely.
- 04
Test every transport
Cover browser endpoints, public APIs, GraphQL, files, search, webhooks, imports, exports, mobile clients, internal tools, jobs, and service-to-service calls. The least-used path often has the weakest enforcement.
- 05
Log useful decision context
Record principal, tenant, action, resource type and safe identifier, outcome, policy version, enforcement point, and correlation ID. Avoid logging raw tokens or sensitive resource contents.
- 06
Alert on suspicious patterns
Watch repeated cross-tenant denials, privileged role grants, support elevation, new service credentials, policy changes, bulk exports, and sudden permission failures after deployment.
Unit-test policy semantics, integration-test enforcement, and end-to-end test the highest-risk customer journeys. A perfectly tested policy function does not help if an endpoint forgot to call it.
Where authorization boundaries quietly break
Ten multi-tenant authorization failures
Putting a global role on the user
The user becomes an administrator in every tenant instead of holding a tenant-specific role on each membership.
Trusting tenant IDs from the client
A header, parameter, subdomain, or token claim selects Tenant B without the server verifying the principal's active membership.
Loading globally before authorizing
The system fetches a record outside tenant scope and leaks its existence, attributes, logs, or side effects before a late policy check.
Checking roles only in the interface
The button is hidden, but the endpoint, file, resolver, bulk action, or API remains callable directly.
Allowing when policy context is missing
A new action, resource type, timeout, or malformed request falls through to access instead of denying by default.
Encoding every rule as a role
Project, region, feature, ownership, and approval-limit combinations produce role explosion that administrators cannot understand or audit.
Leaving stale privileges in tokens and caches
Removed or suspended members retain access until a long expiry because the system has no revocation or freshness strategy.
Authorizing only synchronous requests
Jobs, imports, webhooks, scripts, exports, and support tools bypass the product's normal policy and tenant context.
Giving support permanent superuser access
Convenient troubleshooting creates an unbounded cross-tenant path with weak approval, visibility, and accountability.
Logging decisions without enough context
An incident cannot be reconstructed because logs omit the tenant, action, resource, policy version, or identity that made the request.
Make tenant access a product capability
Build authorization customers can trust and operate.
Devyou helps founders design, build, and operate SaaS products with tenant-aware identity, permissions, data isolation, integrations, administrative workflows, testing, and production observability.
Common questions
Multi-tenant authorization FAQ
What is the difference between multi-tenant authentication and authorization?+
Authentication verifies the identity of a user or workload. Authorization determines what that principal may do within an active tenant. Tenant isolation separately ensures the operation cannot reach another tenant's resources.
Should roles be stored on the user or tenant membership?+
Store tenant-specific roles on the membership or an assignment linked to it. One user can belong to several tenants with different responsibilities, such as owner in one organization and viewer in another.
Is RBAC enough for multi-tenant SaaS?+
RBAC is often the best starting point when permissions follow stable jobs. Add attributes for contextual rules and relationships for nested ownership or sharing. Tenant scope and resource isolation remain necessary under every model.
Should the tenant ID be stored in the access token?+
It can be. A tenant-specific token makes active context explicit, while an application-managed membership lookup makes changes easier to reflect immediately. In either design, verify current membership and resource tenant instead of trusting the claim alone.
Do I need a separate authorization service?+
Not necessarily. A modular application can centralize policies and enforcement without a network service. Consider a dedicated engine when several services need the same policies, tenants need custom roles, relationships become complex, or independent policy administration and audit justify it.
How do you test multi-tenant authorization?+
Create equivalent resources in at least two tenants and test every protected operation from the wrong tenant. Cover reads, writes, lists, search, files, exports, jobs, APIs, support tools, tenant switching, role removal, and missing context.
Primary references
Sources and further reading
- AWS: Multi-tenant SaaS authorization and API access control
- AWS: Authorization design models for multi-tenant SaaS
- Microsoft Azure: Identity considerations for multitenant solutions
- Microsoft Azure: Architectural approaches for multitenant identity
- OWASP: Authorization Cheat Sheet
- IETF RFC 9700: OAuth 2.0 Security Best Current Practice
- OpenID Connect Core 1.0
- IETF RFC 7644: SCIM protocol
- NIST: Role-Based Access Control
- NIST SP 800-162: Attribute-Based Access Control
- Google Research: Zanzibar authorization system