Workflow-driven skill that plans and implements the cross-tenant leak-test suite - from surface inventory to the runtime CI gate a multi-tenant codebase must pass on every PR. The planning section inventories tenant-bearing surfaces (tables, APIs, object storage, search, queues, caches), classifies each by isolation model (silo / pool / bridge, per references/isolation-models.md), and derives the OWASP WSTG-ATHZ-02 coverage matrix. The battery 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 404-vs-403 disclosure trade-off, the Postgres-RLS-direct patterns, and the CI integration (non-superuser non-BYPASSRLS role, fail the build on any leak). Use when designing or implementing a tenant-isolation test suite, adding the CI gate to an existing project, or investigating a leak finding.
90
90%
Does it follow best practices?
Impact
94%
1.05xAverage score across 3 eval scenarios
High
Do not use without reviewing
Companion reference for cross-tenant-data-leak-tests. The isolation model
in use (silo / pool / bridge / vertically-partitioned) decides which test
surfaces the planning section must cover.
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 is a pure reference consumed by the leak-test planning section and the tenant-leak critic; it executes nothing.
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.
| Model | Compute | Data | Network | Cost/tenant | Blast radius | Noisy neighbor |
|---|---|---|---|---|---|---|
| Automated single-tenant (silo) | Dedicated | Dedicated | Dedicated | Highest | One tenant | None |
| Fully multitenant (pool) | Shared | Shared (tenant_id discriminator) | Shared | Lowest | All tenants | High |
| Horizontally partitioned (bridge) | Shared | Dedicated per tenant | Shared | Medium | Data isolated | Data tier: none |
| Vertically partitioned | Mix | Mix | Mix | Mixed | Per-tier | Per-tier |
Per-model when-to-choose guidance, the sourced Microsoft framing, and each model's test surface are in models.md.
Tenant isolation is implemented by combining:
auth.jwt() in
Supabase per
supabase.com/docs/guides/database/postgres/row-level-security)
or AWS Cognito ID token; the source of truth for "who is this request
for".rls-reference, AWS IAM dynamic policies
generated per tenant, application-level authorisation middleware.tenant-id=<x>, then enforce via IAM condition keys.| Anti-pattern | Why it fails | Fix |
|---|---|---|
tenant_id filter only in application code | One missed query path = cross-tenant leak | Push the filter to the database (RLS) or row-attribute IAM |
tenant_id from request header / body | Spoofable; tenant A can claim to be tenant B | Always derive tenant_id from authenticated JWT/session, never from request payload |
Trust the JWT raw_user_meta_data for tenant claims | User-modifiable per Supabase docs | Use raw_app_meta_data (server-set) or a server-side claim store |
| Single connection pool for all tenants | One slow tenant query blocks all | Per-tenant pools, or quota-aware pools |
| Shared object-storage bucket without prefix isolation | Object enumeration leaks across tenants | Per-tenant prefix + IAM condition on the prefix |
| No isolation tests in CI | Models drift over time | Cross-tenant leak tests in every PR per cross-tenant-data-leak-tests |
| Migration scripts run without tenant context | Schema changes touch all tenants at once; high blast radius | Stamp pattern with progressive rollout |
The required test categories per model, plus the per-tier isolation mapping, are in 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.
rls-reference):
supabase.com/docs/guides/database/postgres/row-level-security.cross-tenant-data-leak-tests (host skill).