HomeTenant-isolation guide
Tenant-isolation guide

How to test the boundary between SaaS customers.

Tenant isolation is the property that a valid action by one customer cannot read, create, change, or delete data owned by another customer unless an explicit sharing rule permits it.

Start with the authorization invariant

Authentication proves who a user is. Tenant isolation proves which customer resources that identity may reach. A test should therefore use two real tenant identities and ask what happens when tenant A supplies tenant B's identifiers.

  • SELECT must not reveal another tenant's rows
  • INSERT must not assign ownership to an unauthorized tenant
  • UPDATE must check both the existing row and the proposed tenant key
  • DELETE, RPC, storage, and background jobs must enforce the same boundary

Use three complementary test layers

Migration analysis catches risky policy state before deployment. Disposable-environment tests exercise real JWTs and database behavior. Application tests verify that API and user-interface paths do not bypass the intended database controls.

No single layer proves the entire system. The useful goal is repeatable evidence at every place the tenant boundary can change.

A minimum CI checklist

Run deterministic checks on every migration pull request, fail only on new non-waived findings, and make temporary exceptions owned and expiring.

  • Reconstruct final migration state rather than scanning isolated files
  • Keep authorization fixtures for at least two tenants
  • Test read and write paths independently
  • Treat SECURITY DEFINER and service-role code as privileged boundaries
  • Preserve the commit, evidence, disposition, owner, and expiry for each result

Know what a migration scanner cannot prove

Static migration analysis cannot exercise runtime claims, application joins, storage policies, generated SQL, or service code that bypasses RLS. BoundaryCI reports this scope explicitly and keeps active two-tenant execution as a separate capability.

Protect the boundary

Make tenant isolation a repeatable pull-request check.

Run the deterministic scanner locally without database credentials, then add Cloud only when your team needs shared history.

Add tenant-isolation checks Read the quickstart