Multi-Tenant SaaS Architecture
Design and verify tenant authorization, data isolation, provisioning, quotas, migrations, and deletion with explicit ownership and recovery evidence.
trigger="A SaaS platform is adding tenants, changing isolation models, or correcting lifecycle and cross-tenant risks." owner="The SaaS platform owner accountable for isolation, service behavior, and tenant lifecycle operations." participants={["Application lead", "Database owner", "Identity owner", "Security reviewer", "Data and privacy owner", "Support and operations owners"]} prerequisites={[ "A tenant and membership model with explicit object-level authorization rules.", "Classified data flows, contractual requirements, approved locations, and retention decisions.", "Test tenants, production-equivalent application roles and connection pooling, and an authorized recovery environment." ]} outputs={[ "An isolation and trust-boundary decision with denied-access test evidence.", "Idempotent provisioning, quota, migration, and deletion procedures with accountable owners.", "A tenant lifecycle record, incident containment plan, and release acceptance decision." ]} doneWhen={[ "Cross-tenant reads, writes, jobs, caches, exports, and support actions are denied under representative tests.", "Pooled connections cannot reuse another request's tenant context.", "Provisioning and migration failures resume safely without duplicate access or resources.", "Deletion and restore procedures honor the approved scope, exceptions, and evidence requirements." ]} />
Define the tenant and the authority to act for it
A tenant may be a company, workspace, or another contractual boundary. A user can belong to several tenants with different roles. Authentication identifies the caller; authorization determines which tenant and object the caller may act on.
Begin with a membership model and a resource ownership rule. A tenant ID in a request header, URL, token claim, or background message must be validated against the trusted identity and policy. Never grant access because an identifier has the expected format.
This guide covers implementation and operational gates. The multi-tenant SaaS architecture whitepaper provides a broader design discussion. Use the same tenant definition across both the product and its operating tools.
1. Select isolation from requirements and failure scope
The platform and data owners compare pooled, siloed, and mixed designs for each layer. Separate data isolation, compute contention, operational independence, and account or network boundaries.
| Model | Controls to verify | Operating consequences | | --- | --- | --- | | Shared tables with tenant keys | Object authorization, row policies where supported, tenant-aware constraints and queries | Shared capacity and schema-change effects | | Schema per tenant | Role and schema permissions, safe namespace selection, shared database limits | Per-schema migrations and growing object inventory | | Database per tenant | Connection and credential selection, restore access, shared host or cluster boundaries | Database fleet, migration, backup, and pool management | | Dedicated deployment or account | Identity, network, data, and support boundaries | Larger fleet and configuration-drift surface | | Mixed model | Rules for placing and moving tenants between models | More than one operating and recovery path |
A dedicated database is not necessarily dedicated hardware. A separate cluster is not automatically air-gapped. Neither deployment labels nor customer plan tiers establish compliance.
Record the reason for the selected model, rejected alternatives, and reassessment trigger. Test the specific isolation claim instead of publishing a percentage such as “100% isolation.”
Produce a tenant placement decision before provisioning
The platform owner creates a placement record for each supported tenant class. Start with data location, recovery objective, expected workload, permitted administrative access, and any independently reviewed contractual requirement. Then identify which boundaries the proposed deployment supplies and which remain shared. A tenant in its own database may still share a connection proxy, worker fleet, encryption-key administrator, or backup operator.
Consider an illustrative reporting product with ordinary tenants in pooled tables and one tenant requiring a separately restored database. The requirement does not automatically justify duplicating the entire application. The data owner can first evaluate dedicated storage behind the existing application boundary. That option remains acceptable only if routing, database credentials, recovery permissions, and shared compute behavior meet the requirement. If the contract also requires independent administration or deployment, dedicated storage alone fails the decision.
The output is a small decision record, not a ranked list of technologies: requirement, evidence source, selected boundary, remaining shared dependency, operational owner, rejection condition, and migration path. Obtain approval before the provisioning workflow chooses a destination. A sales-plan change must not silently move data into another region or isolation class.
2. Carry validated tenant context through the request
The identity owner defines tenant membership resolution, active-tenant selection, role changes, and session revocation. The application lead checks authorization for the requested action and object on every applicable entry point.
"type": "svg-architecture", "title": "Bind each data operation to an authorized tenant context", "nodes": [ ], "links": [ ], "caption": "This shows the allowed request path. Any failed identity, membership, or object check stops the request before data access. A database context variable does not authenticate the caller." }} />
For background work, preserve the initiating operation, tenant, allowed purpose, and required authority. Recheck relevant permissions when execution is delayed. Revoked access should not remain effective forever because a job was queued earlier.
Support and administrative tools need separate, scoped authorization and an audit reason. Avoid a hidden “all tenants” mode reachable through a normal client parameter.
3. Review PostgreSQL RLS with the actual application role
Where PostgreSQL row-level security is part of the design, the database owner reviews table policies and role privileges together. Superusers and roles with BYPASSRLS bypass RLS. Table owners normally bypass it unless FORCE ROW LEVEL SECURITY applies. Keep routine application access on a non-owner, nonprivileged role.
Specify policies for the required commands, including row visibility through USING and permitted inserted or updated rows through WITH CHECK. Review how multiple policies combine, privileged functions, views, and operations outside row-policy coverage. PostgreSQL documents these behaviors in Row Security Policies.
For a pool-backed application using a validated tenant setting, bind context inside the same transaction as the queries. PostgreSQL's SET documentation defines transaction-scoped SET LOCAL behavior. Session-wide settings can survive reuse; local scope also requires the connection and transaction to remain correctly bound.
Use a reviewed data-access wrapper: begin transaction, set the validated context, execute authorized work, and commit or roll back in all paths. Missing or invalid context must fail closed. Test cancellation, exceptions, retries, and connection reuse with alternating tenants.
The setting remains a trust boundary. Code or injected SQL that can choose an arbitrary tenant value can undermine policies based on that value. RLS is an additional control, not a substitute for parameterized queries, protected credentials, trusted context assignment, and application authorization.
Gate: tests run as the production-equivalent application role through the real pooling mode. Testing only as an administrator does not prove tenant isolation.
Build an adversarial test fixture with two tenants
The security reviewer creates synthetic tenants A and B, a member of A, a member of both with different roles, and a revoked member. Seed distinguishable objects, cache entries, queued jobs, and export files. The application owner supplies the supported routes and actions; the reviewer selects cross-boundary cases rather than relying on a happy-path screenshot.
| Test input | Expected observation | Evidence to retain | | --- | --- | --- | | A member requests B's known object identifier | No B data or unauthorized mutation | Request, identity scope, response, and unchanged target state | | A transaction fails before a pooled connection is reused for B | B sees only its authorized context | Transaction sequence and role/context observations | | A member's role changes while an export is queued | Execution follows the approved revocation policy | Membership revision, execution decision, and export access check | | An update attempts to move an object to another tenant | Ownership transition is denied unless explicitly supported | Write-policy result and persisted row ownership | | A support account opens an unrelated tenant | Scope and reason are required before access | Administrative decision and audit event |
Do not put live customer identifiers or records in the fixture. Verify positive cases too: a control that denies everything can pass a negative-only suite while breaking the product. Repeat the fixture through the actual API, background worker, pool, and administrative path. A unit test of the authorization helper does not exercise a query that bypasses that helper.
The database owner records role grants, policy definitions, and pool mode beside the test results. The release gate fails if the test cannot reproduce the production access path. If a denial leaks object existence through errors or timing, the security owner assesses that separate disclosure rather than declaring the main data-isolation check sufficient.
4. Provision tenants through a resumable workflow
The platform owner gives each provisioning request an idempotency identity and records its state. Reserve the tenant identifier, assign the approved placement and plan, create required resources, apply schema and configuration, and verify readiness before exposing access.
"type": "flow", "title": "Provision access only after tenant resources pass verification", "steps": [ ], "caption": "A failed step leaves a recoverable provisioning state. Retries reuse recorded resources and do not create extra administrators or send reusable credentials." }} />
Use SSO or a short-lived, single-use activation link that allows the intended person to establish credentials. Bind the invitation to the tenant, recipient, and permitted role. Reissuing or revoking an invitation must have explicit semantics. Never email a reusable password.
OWASP's password-recovery guidance describes secure, expiring, single-use tokens. Apply those token-handling principles to activation while separately reviewing the invitation and membership rules.
On failure, resume from recorded steps or remove only resources known to belong to that failed request under an approved cleanup plan. A pre-provisioned resource pool needs verified emptiness, isolation, assignment, and reset procedures before reuse. Measure its benefit instead of assuming a fixed onboarding speedup.
5. Control noisy neighbors with workload evidence
The service owner defines rate, concurrency, storage, queue, and expensive-operation limits from capacity and commercial policy. “Unlimited” product language still needs a safe internal admission policy and an escalation process.
Measure shared bottlenecks: database connections, hot partitions, worker slots, memory, storage throughput, and external API limits. A tenant using more than the median may be behaving within its contract. Throttle based on the agreed policy and system protection needs, not an arbitrary multiplier.
Make enforcement concurrency-safe and define what happens when the quota store is unavailable. Decide which operations may fail closed, defer, or use a bounded fallback. Return an understandable response and retry guidance where appropriate.
Test one tenant's heavy workload alongside another tenant's critical path. Record latency and completion impact, rejection behavior, and recovery after the heavy workload stops.
6. Make caches, storage, and telemetry tenant-aware
Cache identity should include the relevant tenant, authorization scope, input, and data version. Reauthorize reads when required; a tenant-prefixed key does not prove the caller may access it.
Apply object ownership checks before issuing storage links or exports. Preserve scope through search filters, analytics, background jobs, and downloaded artifacts. Test cross-tenant object references and stale permissions, not only an application's primary database query.
Collect tenant identifiers in telemetry only for an approved purpose. Set access, retention, redaction, and cardinality controls. Support staff should not gain broad customer-data access through a shared log search. OpenTelemetry's sensitive-data guidance emphasizes reviewing what instrumentation emits and minimizing collected data.
Keep high-cardinality investigation fields out of unrestricted metric labels. Use controlled logs or traces when those fields are needed, and budget their storage and query cost.
7. Migrate schemas and tenant placement safely
The database owner records schema version, migration status, failure reason, and recovery action per relevant tenant or shared database. Use backward-compatible application and schema transitions while versions coexist.
Choose canary tenants that exercise important workload and configuration differences. A fixed percentage may omit the largest tenant or the only customer using a critical feature. Test lock duration, resource contention, and retry behavior using tools supported by the selected database.
Moving a tenant between pooled and dedicated storage requires a writer-authority and synchronization plan. Copy at a consistent point, capture changes, reconcile data and permissions, transfer routing, and fence the old writer. Preserve caches, jobs, exports, and support-tool mappings.
If the target has accepted writes, routing back needs current, compatible data. State when reverse synchronization is tested and when repair-forward is required. Never treat a placement flag as a complete rollback plan.
Use a tenant-specific cutover record. The migration owner lists the source checkpoint, copy completion, change backlog, reconciled objects, permission revision, routing revision, and writer-fencing evidence. Include queued jobs and signed links that may still reference the old location. Define the period during which old and new application versions can operate on the target schema.
Before moving the next tenant, exercise a failed cutover with synthetic data. Stop target writes, establish the authoritative copy, and reconcile completed operations before reopening service. If the target has introduced data the old schema cannot represent, the approved response may be repair-forward or a bounded maintenance window. Document that limit before any production write crosses the boundary.
8. Separate cancellation, erasure, and breach procedures
The privacy owner distinguishes tenant cancellation from an individual's data-subject request. Verify requester authority, scope, applicable retention, and any exception before running destructive work.
Under GDPR Articles 12(3), 17, and 33, information about action on a rights request is generally due within one month, with conditional extensions. Erasure has grounds and exceptions and, where required, must occur without undue delay. The separate 72-hour rule concerns supervisory-authority breach notification, subject to Article 33's conditions. Obtain qualified advice for the actual request.
The engineering owner maps primary stores, replicas, caches, search, analytics, exports, processors, and backups. Record what is deleted, retained under an approved basis, or scheduled to expire. Do not promise immediate deletion from every immutable backup without a supported procedure.
Test a restore containing previously deleted records. Apply the approved suppression or deletion record before restored data becomes available. A deletion report should state scope, evidence, exceptions, and remaining expiry obligations; calling it a certificate does not establish legal compliance.
9. Exercise containment and recovery
| Test | Required result | Owner | | --- | --- | --- | | Tenant A requests tenant B's object | Denied across API, data, cache, search, and export paths | Security and application owners | | Connection is reused after an exception | No inherited tenant context or privileged role | Database owner | | Provisioning webhook repeats | One tenant and authorized membership set | Platform owner | | Heavy tenant exhausts a shared resource | Agreed protection and understandable rejection | Service owner | | Migration fails partway | Progress is recorded and compatible service continues | Migration owner | | Deleted data returns through restore | Approved suppression is applied before exposure | Data and privacy owners |
If a leak is suspected, activate incident response, contain the affected path, preserve evidence, and involve the designated privacy and security owners. Do not broadly delete logs or silently change policies before evidence and impact are assessed.
Reusable tenant control record
Record tenant identity and placement; membership authority; object ownership rules; application roles; isolation policies; pool behavior; quota policy; resource inventory; schema version; provisioning state; data locations; retention and deletion decisions; denied-access tests; support permissions; recovery evidence; and accountable approvals.
10. Accept tenant operations, not only request isolation
The support owner rehearses a tenant lifecycle using a synthetic account: invite a member, change their role, suspend access, resume service, export permitted data, and close the tenant under the approved retention policy. The data owner separately tests an individual request affecting data across several tenants. Those operations have different authority and scope, so one cancellation button should not stand in for both.
The platform owner verifies that a partially provisioned tenant remains unavailable, that retries do not duplicate memberships, and that quota changes take effect consistently across workers. On-call staff must be able to identify the tenant placement and current lifecycle state without receiving blanket access to its data. Record the approved emergency path, including expiry and later review of elevated access.
Accept the implementation when allowed and denied operations match the policy, recovery can restore the correct tenant without exposing another, and a second operator can perform the lifecycle procedures from the record. Missing legal or security approval remains a release condition; engineering test results do not replace it. For the next review, bring one completed placement record and its cross-tenant test evidence to SaaS platform engineering.
"Tenant identity is derived and authorized through a trusted membership model.", "Routine database access uses reviewed nonprivileged roles and explicit read/write controls.", "Transaction context is tested through the deployed pool, including failures and reuse.", "Activation avoids reusable credentials and provisioning retries are idempotent.", "Caches, jobs, storage, search, exports, and support tools preserve tenant authorization.", "Quota and migration tests cover shared-resource effects and partial failures.", "Deletion evidence and backup-restore handling follow the approved privacy decision." ]} />
Limitations
These controls require validation against the chosen database, identity provider, hosting model, and legal obligations. The examples do not certify isolation or compliance. Re-run denied-access and recovery tests after role, policy, pooling, schema, lifecycle, or tenant-placement changes.