Tenant isolation

Create matching record identifiers in two tenants

Similar records expose missing scope in queries and caches. Use two isolated test tenants and exercise the same operation through every supported path.

In this article

Make the records easy to distinguish

Create tenants A and B with records that share a local identifier where the schema permits it, such as invoice number INV-42. Give the records different synthetic marker text and amounts.

If primary identifiers are globally unique, keep them distinct and test cross-tenant references directly. Global uniqueness does not remove the need to verify that a caller may access the selected record.

Establish the expected response and target state for each tenant. The test should detect both disclosure and mutation, not only a successful status code.

Exercise direct and cached reads

Request tenant A's record, then request the corresponding record as tenant B. Repeat in the opposite order to expose a cache key that omits tenant scope.

Try changing the tenant label in the request while keeping the same authenticated user. The server should validate membership and target ownership rather than trusting the label.

Inspect error responses too. A denied request should not reveal restricted fields or unnecessary details about another tenant's record.

Run the background path

Queue exports or processing jobs for both tenants and execute them concurrently. Verify the worker loads each target within the correct scope and writes output to the correct tenant-owned location.

Reuse pooled connections and trigger a worker error between jobs. This tests whether tenant context leaks after an interrupted transaction or incomplete cleanup.

Pause a job, remove the requester's access and resume it under the documented authority policy. The expected outcome may differ for requester-owned and organisation-owned work, so keep the policy explicit in the fixture.

Inspect artifacts and administration

Open generated downloads, search results and support views using both identities. A correct API response does not prove a stored export or diagnostic endpoint is isolated.

Attempt the operation through supported administrative tools and record any deliberate cross-tenant authority. Those paths need stronger access and audit rules, not exemption from testing.

Keep marker-based assertions on the final content and database changes. The suite should demonstrate that each path preserves the tenant boundary even when identifiers, timing and cache state make an accidental unscoped lookup easy to miss.

Primary sources

OWASP: multitenant securityPostgreSQL: row security policies

References checked 11 September 2026.