Skip to main content
the auth layer

Multi-Tenant Isolation: Keeping Tenant A Out of Tenant B at the Token Level

3 min read Chapter 22 of 45

Multi-Tenant Isolation

In a single-tenant system, a valid token means access. In a multi-tenant system, a valid token means access to one tenant’s data. The difference is a single claim and the enforcement logic around it.

The multi-tenant SaaS platform serves hundreds of tenants from a shared infrastructure. Same application instances, same database (logical separation via tenant_id columns), same Redis cluster. Tenant isolation is not a feature. It is the invariant that, if violated, turns a SaaS platform into a data breach.

Isolation failures are not exotic. They are the most common class of multi-tenant vulnerability. They happen when:

  • A developer adds an endpoint and forgets the tenant check.
  • A URL path parameter determines the tenant instead of the token claim.
  • An admin API uses a different authorization path that skips tenant validation.
  • A JOIN query crosses tenant boundaries because the WHERE clause is incomplete.

The Confused Deputy

The confused deputy problem: a system with legitimate authority acts on behalf of the wrong principal because it trusted a client-provided identifier instead of a cryptographically verified one.

In the SaaS platform: User Alice belongs to tenant “acme-corp.” Her JWT contains "tenant_id": "acme-corp". She sends a request to GET /api/tenants/globex-inc/projects. The resource server has two choices:

  1. Use the path parameter (globex-inc) to determine which tenant’s data to serve. Alice sees Globex’s projects. Tenant isolation is broken.
  2. Use the token claim (acme-corp) to determine the tenant boundary. The path parameter globex-inc does not match the token’s tenant_id. The request is rejected with 403.

Option 1 is the confused deputy. The server trusts Alice’s request to specify the tenant. Alice (or an attacker with Alice’s token) can enumerate every tenant’s data by changing the path parameter.

Option 2 is the correct approach. The tenant context comes from the signed JWT, which was issued by the authorization server after verifying Alice’s tenant membership. The client cannot forge or modify the tenant claim without invalidating the signature.

Isolation Layers

Tenant isolation requires defense-in-depth. A single enforcement point is a single point of failure.

LayerMechanismWhat it catches
Tokentenant_id claim in JWTCross-tenant request with valid auth
SecurityFilterChainCustom AuthorizationManagerMissing endpoint-level tenant check
ServiceTenantContext validationBusiness logic accessing wrong tenant
RepositoryHibernate @FilterDeveloper forgot WHERE tenant_id = ?
DatabasePostgreSQL RLSDirect SQL injection bypassing ORM

Each layer assumes the layers above it have failed. The token layer catches 99% of cross-tenant attempts. The database layer catches the 1% that slip through application bugs. Together, they create a defense that requires failures at multiple levels to breach.

What This Chapter Covers

Section 1 implements token-level enforcement: extracting tenant from JWT claims, creating a TenantAwareAuthentication, and building a SecurityFilterChain that rejects cross-tenant requests before they reach any controller.

Section 2 implements database-level enforcement: Hibernate filters that automatically scope every query to the current tenant, Spring Data JPA integration, and PostgreSQL row-level security as the ultimate backstop.