Testland
Browse all skills & agents

tenant-isolation-models-reference

Pure-reference catalog of tenant-isolation models for B2B SaaS. Defines the isolation continuum from full-isolation (separate compute + data + network per tenant) to fully-shared (one deployment, tenant_id discriminator), names the canonical models (Microsoft's automated-single-tenant / fully-multitenant / vertically-partitioned / horizontally-partitioned; AWS Well-Architected's silo / pool / bridge framing; deployment-stamps / supertenants terminology), enumerates the trade-offs (cost, blast radius, noisy neighbor, compliance, scale limits), and lists the test surfaces each model creates (cross-tenant data leak, tenant-id propagation, deployment-routing). Use as the model-selection reference when designing or auditing tenant isolation. Consumed by tenant-leak-test-author, cross-tenant-data-leak-tests.

Install with skills.sh (any agent)

npx skills add testland/qa --skill tenant-isolation-models-reference
View source

tenant-isolation-models-reference

Overview

Tenant isolation is the foundational concern of every B2B SaaS architecture: the AWS Well-Architected SaaS Lens calls it essential and treats crossing a tenant boundary as a significant, potentially unrecoverable event for a SaaS business. Isolation is a continuum, not a binary - Microsoft's Azure Architecture Center frames it as a spectrum from shared-nothing to everything-shared, with architectures often picking different points per tier (UI shared, app shared, data isolated). This skill is a pure reference consumed by the per-model test authors and the tenant-leak critic; it executes nothing.

When to use

  • Designing the tenant-isolation model for a new B2B SaaS product or feature.
  • Auditing an existing model - does the testing surface match the declared isolation level?
  • Choosing what to test: each model creates a distinct set of failure modes the test suite must cover.
  • PR review of architecture changes that move components along the isolation continuum.

Tenant vs deployment

A tenant is a logical customer boundary; a deployment (also called a stamp or supertenant) is a physical set of infrastructure. One deployment can host many tenants (shared model), or each tenant can have its own deployment (silo). The tenant-to-deployment mapping is durable state: a routing table must exist somewhere so requests reach the right deployment.

The four canonical models

ModelComputeDataNetworkCost/tenantBlast radiusNoisy neighbor
Automated single-tenant (silo)DedicatedDedicatedDedicatedHighestOne tenantNone
Fully multitenant (pool)SharedShared (tenant_id discriminator)SharedLowestAll tenantsHigh
Horizontally partitioned (bridge)SharedDedicated per tenantSharedMediumData isolatedData tier: none
Vertically partitionedMixMixMixMixedPer-tierPer-tier

Per-model when-to-choose guidance, the sourced Microsoft framing, and each model's test surface are in references/models.md.

Isolation enforcement primitives

Tenant isolation is implemented by combining:

  • Identity context - tenant_id in JWT claims (auth.jwt() in Supabase per supabase.com/docs/guides/database/postgres/row-level-security (opens in new window)) or AWS Cognito ID token; the source of truth for "who is this request for".
  • Authorisation policy - Postgres Row-Level Security per row-level-security-postgres-reference, AWS IAM dynamic policies generated per tenant, application-level authorisation middleware.
  • Resource ABAC tags - tag each tenant resource with tenant-id=<x>, then enforce via IAM condition keys.
  • Network segmentation - per-tenant VPCs / subnets / security groups (silo only).
  • Encryption keys - per-tenant KMS keys (silo / bridge); useful for crypto-shredding on tenant offboarding.

Anti-patterns

Anti-patternWhy it failsFix
tenant_id filter only in application codeOne missed query path = cross-tenant leakPush the filter to the database (RLS) or row-attribute IAM
tenant_id from request header / bodySpoofable; tenant A can claim to be tenant BAlways derive tenant_id from authenticated JWT/session, never from request payload
Trust the JWT raw_user_meta_data for tenant claimsUser-modifiable per Supabase docsUse raw_app_meta_data (server-set) or a server-side claim store
Single connection pool for all tenantsOne slow tenant query blocks allPer-tenant pools, or quota-aware pools
Shared object-storage bucket without prefix isolationObject enumeration leaks across tenantsPer-tenant prefix + IAM condition on the prefix
No isolation tests in CIModels drift over timeCross-tenant leak tests in every PR per cross-tenant-data-leak-tests
Migration scripts run without tenant contextSchema changes touch all tenants at once; high blast radiusStamp pattern with progressive rollout

Test surface

The required test categories per model, plus the per-tier isolation mapping, are in references/test-surfaces.md. The cross-tenant data leak suite is the universal floor: even silo deployments share some surface (account-management APIs, billing, identity providers) where pool-like leaks are possible.

Limitations

  • No model is leak-proof by construction. Silo defends against most cross-tenant leaks but inherits leak risk in any shared management surface (admin UI, billing). RLS defends the DB but not application caches.
  • Cost vs isolation is a real trade-off. Per Microsoft, if a single tenant requires a given infrastructure cost, 100 tenants in pure silo require roughly 100 times that cost.
  • Compliance scope. Some regulators (e.g., FedRAMP High, certain healthcare regimes) effectively mandate silo for certain data classifications. Check counsel-of-record before assuming pool is acceptable.
  • Azure subscription / AWS account limits. Shared infrastructure reaches account-level scale limits faster than silo.

References

The four canonical tenant-isolation models

View source (opens in new window)

The four canonical tenant-isolation models

Naming across frameworks: Microsoft's automated-single-tenant / fully-multitenant / horizontally-partitioned / vertically-partitioned; AWS Well-Architected's silo / pool / bridge. Deployments are also called stamps or supertenants.

1. Automated single-tenant (silo / fully-isolated)

PropertyValue
ComputeDedicated per tenant
DataDedicated per tenant
NetworkDedicated per tenant
Cost per tenantHighest
Blast radiusOne tenant
Noisy neighborNone

Microsoft's framing: deploying a dedicated set of infrastructure per tenant isolates each tenant's data and reduces the risk of accidental leakage.

When to choose: regulated industries with strong isolation mandates (healthcare HIPAA, financial services, government); a small number of high-value enterprise customers; per-tenant configuration is part of the value proposition.

Test surface: deployment automation (the Deployment Stamps pattern); cross-deployment operations like reporting; tenant-to-deployment routing.

2. Fully multitenant (pool / fully-shared)

PropertyValue
ComputeShared
DataShared (single DB with tenant_id discriminator)
NetworkShared
Cost per tenantLowest
Blast radiusAll tenants
Noisy neighborHigh

Microsoft's risk framing: separate each tenant's data and don't leak across tenants; a large tenant running a heavy query or operation might affect other tenants.

When to choose: a large number of low-margin customers; high operational efficiency required; tenants accept shared infrastructure.

Test surface: cross-tenant data leak (the canonical risk), tenant_id propagation through every code path, noisy-neighbor behaviour, resource quotas per tenant.

3. Horizontally partitioned (bridge)

PropertyValue
ComputeShared
DataDedicated per tenant
NetworkShared
Cost per tenantMedium
Blast radiusApp-tier shared, data isolated
Noisy neighborApp-tier yes, data tier no

Microsoft's framing: a single application tier with an individual database per tenant, which mitigates the noisy-neighbor problem in the data tier.

When to choose: data isolation matters for compliance, but shared compute is acceptable; data-tier noisy neighbors are the dominant failure mode (heavy queries, large indexes).

Test surface: correct database routing per tenant; connection-pool exhaustion under tenant concurrency; cross-DB query attempts must fail.

4. Vertically partitioned

PropertyValue
ComputeMix (some tenants dedicated, others shared)
DataMix
NetworkMix
Cost per tenantMixed
Blast radiusPer-tier decision
Noisy neighborPer-tier

Microsoft's framing: a combination of single-tenant and multitenant deployments - most customers' data and application tiers on multitenant infrastructure, with single-tenant infrastructure for customers who require higher performance or data isolation. Includes geographic partitioning (one deployment per region, tenants mapped to the nearest region).

When to choose: the majority of customers fit the shared model, but a minority need silo (enterprise tier); geographic data-residency requirements.

Test surface: every test from the shared model plus every test from the silo model; tenant migration between tiers; pricing tier enforcement.

Source: Microsoft Azure Architecture Center - Tenancy Models learn.microsoft.com/en-us/azure/architecture/guide/multitenant/considerations/tenancy-models (opens in new window).

Test surface by tenant-isolation model

View source (opens in new window)

Test surface by tenant-isolation model

Isolation tier mapping

A common pattern is independent isolation per architecture tier:

TierCommon choice
UIShared host name (fully multitenant)
API gatewayShared, with tenant claim in JWT
Application servicesShared, tenant context in every request
Async queues / topicsShared topic with tenant_id message attribute, or per-tenant queue
DataOften partitioned: tables with tenant_id (pool); schemas per tenant (bridge); databases per tenant (silo)
Object storagePer-tenant prefix in bucket (pool); bucket per tenant (silo)
Search indexPer-tenant routing key (pool); index per tenant (silo)

The test surface depends on the lowest isolation level in the stack. A fully isolated UI but shared database still requires the full cross-tenant data-leak test battery against the database.

Required test categories per model

ModelRequired test categories
Silo / single-tenantTenant-to-deployment routing; per-deployment health; deployment automation
Pool / fully-sharedCross-tenant data leak (highest priority); tenant_id propagation; noisy-neighbor mitigation; quota enforcement
Bridge / horizontalPool tests + database routing per tenant; cross-database query rejection
VerticalPool + silo tests + tier-migration tests

The cross-tenant data leak suite is the universal floor: even silo deployments share some surface (account-management APIs, billing, identity providers) where pool-like leaks are possible.

Related skills

cross-tenant-data-leak-tests

Workflow-driven skill that emits the runtime CI gate of cross-tenant leak tests - the actual battery a multi-tenant codebase must pass on every PR. Defines the canonical test patterns (read-other-tenant-by-id, list-leak, spoofed-tenant-id-in-body, JWT-replay, FK-cross-tenant, unique-collision side channel, object-storage IDOR, search-index-direct-query, async-job-context-reload, cache-key-collision), the expected response codes per pattern (404 vs 403 disclosure trade-off), the Postgres-RLS-direct test patterns, and the CI integration (run with non-superuser non-BYPASSRLS role, fail the build on any leak). Use when implementing the actual leak-test suite (after tenant-leak-test-author produces the plan), when adding the CI gate to an existing project, or when investigating a leak finding.

multi-engine-row-level-security-reference

Pure-reference catalog of row/tenant isolation mechanisms across four database engines: MySQL and MariaDB (no native RLS - views with SQL SECURITY INVOKER plus app-layer enforcement), CockroachDB (native RLS via ALTER TABLE ENABLE ROW LEVEL SECURITY and CREATE POLICY, matching Postgres semantics), Vitess (keyspace sharding + vindexes route tenant writes to dedicated shards without a policy layer), and SQL Server (CREATE SECURITY POLICY with inline table-valued function filter/block predicates). Covers the isolation mechanism, tenant-context pattern, bypass risks, and test patterns for each engine. Use when designing or auditing tenant isolation on MySQL, MariaDB, CockroachDB, Vitess, or SQL Server.

row-level-security-postgres-reference

Pure-reference catalog of Postgres Row-Level Security (RLS) for tenant isolation. Covers enabling RLS (ALTER TABLE ... ENABLE ROW LEVEL SECURITY, default-deny semantics), CREATE POLICY syntax (USING vs WITH CHECK clauses, FOR SELECT/INSERT/UPDATE/DELETE/ALL, permissive vs restrictive, TO role_name), bypassing RLS (superuser / BYPASSRLS / table owner / FORCE ROW LEVEL SECURITY), tenant context patterns (current_user, current_setting, JWT claims via Supabase auth.uid() / auth.jwt()), performance discipline (wrapping auth functions in SELECT, index on policy-referenced columns), and anti-patterns. Use as the RLS-pattern reference for Postgres-backed tenant isolation. Consumed by tenant-leak-test-author, cross-tenant-data-leak-tests.

tenant-leak-test-author

Workflow-driven skill that builds a tenant-leak test plan from an inventory of tenant-bearing surfaces (database tables, APIs, object storage, search indices, async messages) and the isolation model in use. Walks through identifying tenant-bearing surfaces, enumerating the attack patterns per OWASP WSTG-ATHZ-02 (horizontal escalation, vertical escalation, IDOR / BOLA), generating test cases that exercise each pattern against each surface, and emitting the test suite skeleton (pytest / Jest / JUnit / Go test) with explicit cross-tenant probes. Use when designing a multi-tenant test suite for a new feature, when auditing test coverage for an existing tenant boundary, or when reviewing PRs that add tenant-bearing surfaces. Distinct from cross-tenant-data-leak-tests which is the runtime gate; this skill produces the plan.

tenant-onboarding-test-author

Workflow-driven skill that authors a test suite for tenant provisioning and offboarding: account creation, isolation at creation (no cross-tenant bleed from a new tenant's first API call), default resource quotas, billing record linkage, seed and default data correctness, idempotent re-provisioning, and teardown with full data deletion. Walks through mapping provisioning surfaces, generating test cases per surface, emitting the test suite skeleton (pytest / Jest / JUnit / Go test), and producing a coverage matrix. Use when a new tenant onboarding flow is introduced or changed, when the offboarding pipeline is modified, or when auditing provisioning coverage before a compliance review. Distinct from tenant-leak-test-author (runtime cross-tenant access) and cross-tenant-data-leak-tests (CI gate): this skill covers the provisioning lifecycle, not steady-state access control.