In a multi-tenant SaaS platform, one missing tenant check can expose every customer's data at once, and authentication alone does nothing to prevent it. Shared infrastructure is what makes SaaS economical, but it means the boundary between customers is enforced by code, policy and configuration rather than by separate machines. AWS describes crossing that boundary as a significant and potentially unrecoverable event for a SaaS business. This guide covers tenancy models, tenant context and identity, data isolation (including PostgreSQL row-level security), caches and queues, noisy neighbours and quotas, tenant lifecycle, multi-tenant AI and RAG, logging and testing. It is written for SaaS architects, platform and application security engineers, and the buyers who need to ask SaaS vendors how isolation actually works.
Key takeaways
- Isolation is separate from authentication and authorisation. A user can be fully authenticated and hold the right roles and still reach another tenant's data if nothing checks tenant ownership.
- Tenant context must come from verified identity. Treat any tenant ID in a URL, header or body as a selector only, and confirm the caller's membership of that tenant on every request.
- Choose isolation per tier, not once for the whole stack. Shared web tiers with per-tenant databases, or pooled data with dedicated deployments for regulated customers, are normal and must each be documented and tested.
- Every shared component needs a tenant dimension. Database queries, cache keys, object storage prefixes, queues, rate limits, logs, vector indexes and backups all leak if one of them ignores tenancy.
- Prove isolation with negative tests. Cross-tenant tests through the production connection path, coverage checks on every tenant table, and single-tenant restore tests catch what code review misses.
Tenancy models and isolation trade-offs
Microsoft's Azure Architecture Center describes isolation as a continuum from shared nothing to shared everything, and notes that it can vary by tier. A deployment (also called a stamp) is one set of infrastructure; tenants map to deployments one-to-one or many-to-one, and a tenant mapping layer routes each request to the deployment that holds the tenant's data. AWS SaaS guidance commonly calls the same ideas silo (dedicated resources), pool (shared resources) and bridge (a mix).
| Model | What is shared | Isolation enforced by | Security strengths | Security risks |
|---|---|---|---|---|
| Automated single-tenant (silo) | Nothing except the control plane and pipeline | Separate accounts, networks and stacks | Strong data isolation, no noisy neighbour, blast radius of an outage or bug limited to one tenant | Cost scales linearly; configuration drift across many stacks; shared deployment pipeline is still a cross-tenant path |
| Fully multitenant (pool) | All tiers | Application code, tenant IDs in data, fine-grained policies | One configuration to harden and patch | A single authorisation or query bug exposes everyone; noisy neighbours; one bad update affects all tenants |
| Horizontally partitioned | Some tiers (for example the application tier), others per tenant (for example databases) | Mix of code and per-tenant resources | Data isolation where it matters most, contained database load | Shared tier still needs strict tenant checks and credentials per tenant database |
| Vertically partitioned (bridge by tier) | Shared deployment for most tenants, dedicated deployments for some | Varies by tenant | Premium or regulated tenants can buy stronger isolation | Codebase must support both models; tenant migration between deployments is risky |
AWS's SaaS architecture whitepaper makes the policy granularity point explicit: dedicated stacks can be isolated with coarse network or account policies, while pooled resources (such as items in one DynamoDB table) need fine-grained policies.
Choosing a model
- Many small tenants, low data sensitivity: pooled, with strong application and database-level isolation, is usually the only economical option.
- Regulated or high-value tenants: dedicated databases or full stacks, often sold as a higher tier, with separate encryption keys per tenant.
- Heavy and variable workloads: horizontal partitioning of the hot tier, usually storage, to contain noisy neighbours.
Tenant context and identity
Tenant context is the verified answer to "which tenant is this request acting in?". The OWASP Multi-Tenant Security Cheat Sheet sets the rules:
- Establish it early: in middleware or an interceptor, before any business logic runs, and store it in request-local storage that is reset when the request ends.
- Selector, not proof: a client-supplied tenant ID only selects a tenant. The server must confirm that the authenticated principal is a current member of that tenant, or that the calling service is authorised for it. Missing context returns 401, denied context returns 403.
- Propagate verified context: pass it downstream in a form other services can validate, and stop components from replacing it with unverified input. See the Microservices Security Guide.
Tenant claims in tokens
Microsoft's multitenant identity guidance describes two approaches. In the first, the identity provider embeds a tenant identifier claim (and optionally the user's role in that tenant) in the token, the application validates it on every request, and a user who belongs to several tenants gets a new token when switching tenant. In the second, the identity system stays tenant-agnostic and the application checks a tenant membership store. OWASP adds that a token claim can select the tenant, but authorisation still depends on what the issuer guarantees or on a live membership check, which matters when membership is revoked before the token expires.
| Approach | Strengths | Weaknesses | Mitigation |
|---|---|---|---|
| Tenant claim in the access token | Fast, no lookup per request, works across services | Stale until expiry if membership changes; issuer becomes critical | Short token lifetimes, re-check membership for sensitive actions |
| Application membership lookup | Always current, tenant-managed roles stay in the app | Extra dependency and latency per request | Cache with tenant-scoped keys and short TTLs |
Where identity fits
- Per-tenant federation: B2B tenants usually want their own identity provider through SAML or OpenID Connect. Your sign-in flow must know which tenant the user is signing in to so that the right federation and policies apply, and check how many federations your identity platform supports. Federation can be offered as a tier. See the Customer IAM (CIAM) Guide.
- User and tenant are not the same thing: Microsoft lists conflating them as an antipattern. One user can belong to many tenants, and one tenant contains many users.
- Tenant-managed roles: in most SaaS products the customer assigns roles within its tenant. Keep tenant-level admin rights strictly separate from platform-level rights. See the Authorisation Models Guide.
- Support impersonation: when staff act as a customer user to troubleshoot, logs must record both the impersonator's and the impersonated user's identifiers, and the access should be time-limited and approved.
- Workload identities per tenant: in silo or bridge models, give each tenant's workloads their own role or service account, so a compromised tenant stack cannot reach another tenant's resources. In pooled AWS designs a common pattern is to scope an assumed role with a tenant session tag and use it in IAM policy conditions. See the Cloud Workload Identity Guide.
- Customer-facing API keys: OWASP recommends generating them with a cryptographically secure generator (at least 128 bits of entropy), showing them once and storing only a hash. Bind each key to one tenant.
Data isolation in shared databases
OWASP compares four database isolation options:
| Option | Boundary | Requires |
|---|---|---|
| Separate database per tenant | Strongest, if credentials, network access, admin paths and backups are also separate | Automation for provisioning, migration and patching at scale |
| Separate schema per tenant | Namespace and role boundary | Disciplined grants, role separation, search_path handling, migration control |
| Shared tables with row-level security | Policy and row boundary | Tenant ownership on every row, policy coverage for every tenant table, constrained request roles, negative tests |
| Hybrid | Varies by workload or data class | A documented, tested boundary for each data class |
PostgreSQL row-level security done properly
- Know who bypasses it: per the PostgreSQL documentation, superusers and roles with
BYPASSRLSalways bypass row security, and table owners bypass it unlessALTER TABLE ... FORCE ROW LEVEL SECURITYis set. The application's request role must be neither superuser norBYPASSRLS, and should not own the tables. Check the deployed role'srolsuperandrolbypassrlsinpg_roles, not just the configuration in source control. - Default deny is your friend: once RLS is enabled with no policy, no rows are visible or modifiable.
- Use both clauses:
USINGfilters existing rows that can be read, updated or deleted;WITH CHECKcontrols new and modified rows, which is what stops a tenant writing a row tagged with another tenant's ID. - Restrictive policies for mandatory conditions: permissive policies combine with OR;
AS RESTRICTIVEpolicies combine with AND, so a tenant condition declared restrictive cannot be widened by another permissive policy. - Scope the tenant setting to the transaction: OWASP warns that session-scoped settings leak across pooled connections. Use
SET LOCALorset_config(..., true), set the tenant again for every transaction, fail closed if it is missing, and commit or roll back before the connection returns to the pool.
See the Database Security Guide.
Objects, files and identifiers
- Cross-tenant IDOR: on every request, confirm the principal may act in the resource's tenant, include the tenant in lookups (for example a composite key of tenant and resource ID), and return 404 for other tenants' resources so existence is not revealed. This is OWASP API1:2023 Broken Object Level Authorization applied across tenants. See the Top 10 API Security Risks.
- Object storage: authorise the exact object before signing a URL, scope signed URLs narrowly, and use tenant-aware key prefixes with a delimiter, so tenant
acmecannot match objects underacme-corp/. - Encryption keys: per-tenant keys in a KMS allow crypto-shredding at offboarding and give dedicated-tier tenants a provable boundary. Destroy a tenant's key only after every encrypted copy, including backups, has aged out.
Caches, queues and background jobs
- Classify every cached value: global, tenant-scoped or user-scoped. Put the tenant ID in every key whose value or authorisation varies by tenant, plus user, locale or permission version where those vary. Give intentionally shared data an explicit global namespace, and still authorise before returning a protected cached value.
- Derive tenant context from the producer: for asynchronous work, take the tenant from the authenticated producer, not from an editable message field. Re-authenticate and re-authorise at the consumer, and re-check membership when a job runs long after it was queued.
- No fake tenants: cross-tenant or global jobs (billing runs, reindexing) run under an explicit platform identity with its own permissions and audit trail, never by pretending to be a tenant.
Noisy neighbours, quotas and abuse
A noisy neighbour is a tenant whose usage degrades service for others on shared resources.
- Add tenant as a rate-limit dimension: alongside global, endpoint, user and IP limits, and return HTTP 429 with retry guidance. See the Rate Limiting and API Abuse Guide.
- Protect the real bottlenecks: OWASP notes that HTTP limits alone do not protect concurrency, queue depth, database connections, fan-out, CPU or memory. Apply tenant-aware limits to each, and keep global safety limits.
- Isolate high-risk tenants: separate worker pools, or for Kubernetes-hosted platforms, per-tenant namespaces with ResourceQuota and LimitRange objects, dedicated node pools or sandboxed runtimes for untrusted code. Namespaces alone are not a hard security boundary. See the Kubernetes Security Guide.
Multi-tenant AI, RAG and vector stores
AI features add new shared components where tenant data mixes. OWASP LLM08:2025 Vector and Embedding Weaknesses describes cross-context information leaks when multiple classes of users or applications share the same vector database, with embeddings from one group retrieved for another group's queries.
- Treat models as tenant data: Microsoft's guidance treats a model trained on tenant data as being about as sensitive as the raw training data, and distinguishes tenant-specific models, shared models and shared base models tuned per tenant. Tenants must understand and agree to how their data is used, and you need a way to exclude a tenant's data, which can mean retraining.
- Tenant filters on retrieval, server side: derive the tenant filter from verified tenant context, never from the prompt or request body, and apply document permissions within the tenant as well. Per-tenant indexes or namespaces are stronger than a shared index with a filter. See the Permission-Aware RAG Guide.
- Scope prompt caches, conversation history and logs by tenant: the same cache rules apply to AI responses and retrieved chunks.
Tenant lifecycle: onboarding, offboarding and restore
| Stage | Security requirement (OWASP Multi-Tenant Security Cheat Sheet) |
|---|---|
| Onboarding | Provision all-or-nothing, roll back partial resources on failure, create per-tenant keys where required, audit success and failure |
| Credential issue | API keys with at least 128 bits of entropy, shown once, stored as a hash |
| Offboarding | Block new operations first, then revoke sessions, API keys and other tenant credentials, then delete data across stores, caches, object versions, replicas, exports and backups per retention policy |
| Restore | Restore one tenant into a separate resource and copy only that tenant's records after ownership checks; never restore a shared snapshot over live data; record source, target, reason and outcome |
| Platform administration | Cross-tenant operations need explicit platform permissions and auditing; a tenant admin does not inherit platform rights |
Integrations are part of the lifecycle too. When a tenant connects third-party apps by OAuth, those tokens must be stored per tenant, scoped narrowly and revoked at offboarding. See the SaaS and OAuth App Governance Guide.
Logging, monitoring and detection
- Verified tenant context in every tenant-scoped security and audit event: taken from the verified context, not the request.
- Append-only audit: enforce at the database level and use tamper-evident or WORM storage where needed.
- Tenant-scoped audit reads: tenants may review their own logs; cross-tenant reads need explicit platform permission. Microsoft lists missing identity audit logs as an antipattern.
- Alert on denied cross-tenant attempts: repeated 403 or 404 responses on other tenants' resources are a strong signal of enumeration.
Useful ATT&CK techniques for detection content: T1078.004 Cloud Accounts and T1550.001 Application Access Token (abuse of valid tenant credentials and tokens), T1530 Data from Cloud Storage and T1213 Data from Information Repositories (bulk collection), and T1499 Endpoint Denial of Service for resource exhaustion.
Metrics
- RLS coverage: percentage of tenant-scoped tables with RLS enabled, forced and with policies (target 100%, enforced in CI).
- Cross-tenant test pass rate: automated cross-tenant negative tests per release, with zero tolerated failures.
- Cross-tenant denials: count per day and per principal, with alerting on spikes.
- Per-tenant quota breaches: number of 429 responses and throttling events by tenant.
- Offboarding completion time: days from contract end to verified revocation and deletion.
- Privileged cross-tenant access: number of platform admin and impersonation sessions, all with a ticket.
How to implement: a phased approach
- Classify: list every data store, cache, queue, bucket, index and log stream, and mark each as tenant-scoped, global or user-scoped. Record the isolation model for each tier.
- Centralise tenant context: one middleware that derives tenant context from the verified token and membership, with request-local storage and a decorator or guard that refuses to run tenant logic without it.
- Database enforcement: enable RLS in a staging environment with policies using
USINGandWITH CHECK, switch the application to a non-owner, non-BYPASSRLSrole, and run the full test suite. Roll back by restoring the previous role grant, never by disabling RLS in production. - Add CI gates: fail the build on any new table that is not classified, any tenant table without enabled and forced RLS or without policies (compare against
pg_classandpg_policies), and any request role that is superuser orBYPASSRLS. - Extend to other stores: tenant-prefixed cache keys, storage prefixes with delimiters, tenant-scoped queues and vector index filters.
- Quotas: introduce tenant-aware rate limits in report-only mode, measure, then enforce per tier.
- Lifecycle and restore: script onboarding and offboarding, and run a restore test that recovers one tenant from a two-tenant backup and confirms the other tenant's data is absent.
- Test continuously: run two tenants over reused pooled connections in the production path and confirm no context carries over, and include cross-tenant abuse cases in every penetration test.
Smaller SaaS providers will usually stay pooled and should invest first in steps 2 to 4, which give the most isolation per engineering hour. Larger providers selling to regulated sectors typically add a dedicated tier and need fleet-wide configuration management so hundreds of silo stacks do not drift.
Common failure patterns
- Trusting the tenant ID in the request: an API reads
tenant_idfrom the path or body and queries with it, so changing one value returns another customer's data. - Accepting tokens without checking which tenant issued them: the Entra ID Actor Token flaw (CVE-2025-55241) is the clearest example: the legacy Azure AD Graph API did not validate the tenant an impersonation token originated from, so a token created in an attacker's own tenant would have been accepted in any other tenant. Microsoft fixed it globally in July 2025 and reported no evidence of abuse.
- RLS that silently does nothing: the application connects as the table owner or a
BYPASSRLSrole, so every policy is ignored and tests run as a privileged user never notice. - Session-scoped tenant settings with connection pooling: one request's tenant setting carries into the next request on the same connection.
- Shared caches without tenant keys: a cached response or permission decision for one tenant is served to another.
- Concentrating every tenant's integration tokens in one place: in the Salesloft Drift breach, OAuth tokens for all customers' Salesforce integrations were held in one vendor environment, so a single compromise reached hundreds of customer tenants. Encrypt stored tenant tokens with per-tenant keys and monitor bulk use.
Framework mapping
| Control area | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | OWASP |
|---|---|---|---|
| Tenant-aware authorisation | AC-3 Access Enforcement; AC-6 Least Privilege | PR.AA-05 | API1:2023 Broken Object Level Authorization |
| Data isolation in shared resources | SC-4 Information in Shared System Resources; SC-39 Process Isolation | PR.DS-01 | Multi-Tenant Security Cheat Sheet |
| Separation of platform and tenant administration | SC-2 Separation of System and User Functionality; AC-6 | PR.AA-05 | n/a |
| Segmentation of tenant deployments | SC-7 Boundary Protection; AC-4 Information Flow Enforcement | PR.IR-01 | n/a |
| Per-tenant keys | SC-12 Cryptographic Key Establishment and Management | PR.DS-01 | n/a |
| Quotas and noisy neighbours | SC-5 Denial-of-service Protection | PR.IR-01 | API4:2023 Unrestricted Resource Consumption; LLM10:2025 Unbounded Consumption |
| Tenant-scoped audit logging | AU-2 Event Logging; AU-12 Audit Record Generation | PR.PS-04; DE.CM-01 | n/a |
| Isolation testing | CA-8 Penetration Testing; SA-8 Security and Privacy Engineering Principles | n/a | LLM08:2025 Vector and Embedding Weaknesses (for RAG) |
In ISO/IEC 27001:2022 Annex A, the closest controls are A.8.3 Information access restriction, A.8.22 Segregation of networks, A.8.27 Secure system architecture and engineering principles, A.8.24 Use of cryptography and A.8.15 Logging. In CIS Controls v8.1, Control 3 (Data Protection), Control 6 (Access Control Management) and Control 16 (Application Software Security) apply.
Practitioner checklist
- Every data store, cache, queue, bucket and index is classified as tenant-scoped, global or user-scoped, with the isolation model documented per tier.
- Tenant context is derived in one middleware from verified identity and current membership; client-supplied tenant IDs are selectors only.
- Tenant tables have RLS enabled and forced, with
USINGandWITH CHECKpolicies, and the request role is not owner, superuser orBYPASSRLS. - Tenant settings are transaction-scoped, and connection reuse across tenants is tested.
- Cache keys, storage prefixes, queue state and vector index filters all carry the tenant.
- Rate limits and resource quotas include a tenant dimension, with global safety limits kept.
- Platform admin, support impersonation and cross-tenant jobs use explicit identities, approvals and dual-identifier audit logs.
- Offboarding revokes sessions, API keys and integration tokens before deleting data, and restore is tested per tenant.
- CI blocks unclassified tables, missing RLS policies and privileged request roles.
- Penetration tests include cross-tenant IDOR, token tenant-mismatch and cache leakage cases.
Standards and references
- OWASP: Multi-Tenant Security Cheat Sheet
- AWS: SaaS Lens, Tenant Isolation
- AWS: SaaS Architecture Fundamentals, Tenant Isolation
- Microsoft: Tenancy Models for a Multitenant Solution
- Microsoft: Architectural Approaches for Identity in Multitenant Solutions
- Microsoft: Architectural Approaches for AI and Machine Learning in Multitenant Solutions
- PostgreSQL: Row Security Policies
- OWASP: Top 10 for LLM Applications 2025
Related NHI Mgmt Group resources: API Security Guide · Cloud Workload Identity Guide · Kubernetes Security Guide · Authorisation Models Guide · Top 10 SaaS Security Risks