Part 7 · 1 chapters · ~8 min

Multi-Tenant Isolation

Where tenant identity comes from, scoping every query, Postgres row-level security as a safety net, separate schemas and databases for large tenants, per-tenant encryption keys and crypto-shredding, noisy neighbours, and testing for cross-tenant leaks.

15

Isolation in depth

code
-- Postgres row-level security as the last line of defence
ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;
ALTER TABLE accounts FORCE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON accounts USING (tenant_id = current_setting('app.tenant_id')::bigint);

-- per transaction (works with PgBouncer transaction pooling)
BEGIN; SET LOCAL app.tenant_id = '42'; SELECT * FROM accounts; COMMIT;

Test for leaks: integration tests that create two tenants and assert every endpoint returns nothing of tenant B when called as tenant A; and an RLS-enabled test database so a missing filter fails loudly.

TENANT ISOLATION, LAYER BY LAYER
from shared tables to separate databases, and where the check lives
applicationtenant id from the token, never from the request bodydata accessevery query scoped by tenant (repository layer)database row-level securityPostgres RLS policy on tenant_idseparate schemas or databasesper tenant, for the largest or regulatedencryption keysper-tenant keys (crypto-shredding)
swipe the figure sideways, or tap expand for full screen
1/5
identity
The tenant comes from the authenticated token or session, never from a header or body field the client controls.
tenant from the token onlynever from client input