Tenant isolation
Do not trust the tenant label supplied by the client
A tenant identifier selects a context. The server must establish whether the authenticated caller may use it and whether the target belongs inside it.
In this article
Resolve membership on the server
A user may belong to several organisations and choose one in the interface. The selected tenant identifier is still an input to validate against trusted membership or delegation records.
Do not accept a header or body field as authority merely because the normal interface populates it correctly. Direct API callers can change those values.
Keep the resolved tenant in a trusted request context and pass it explicitly to data access and job creation. Avoid a default tenant fallback when context is missing.
Check the target within that scope
Load or mutate the target using both its identity and authorised scope where the data model requires it. A globally unique record identifier does not establish permission to use it.
Review nested resources. A request can contain a valid parent in tenant A and a child identifier from tenant B. The relationship needs validation, not only independent existence checks.
Apply the rule to bulk operations. One permitted record in a list should not authorise every other identifier submitted alongside it.
Keep infrastructure controls aligned
Database row policies and storage permissions can reinforce the application boundary, but their effectiveness depends on the runtime identity and context setup. Review owners, bypass roles and any privileged functions.
If the application sets tenant context on a pooled connection, test transaction scope and cleanup. A stale session value can undermine otherwise consistent query code.
Keep administrative cross-tenant access separate, authenticated and audited. It should not be available through an ordinary client flag or a hidden interface control alone.
Exercise the negative cases
Change the tenant label while keeping the same user, substitute another tenant's target and submit a mixed-tenant batch. Verify no restricted data is returned and no unintended record changes.
Repeat through exports, background jobs and direct file access. The initial request check must survive the rest of the workflow.
Record which source establishes membership and how revocation propagates. A dependable design can explain why this caller may act in this tenant now, rather than relying on a label the caller supplied or a permission captured indefinitely in an old session.
Primary sources
OWASP: multitenant securityPostgreSQL: row security policiesReferences checked 11 September 2026.