Report #97221
[architecture] Multi-tenant SaaS leaks data between tenants or forces one database per customer
Store all tenants in one database with a mandatory tenant\_id column, index it, and enforce isolation in PostgreSQL with Row Level Security policies \(e.g. CREATE POLICY tenant\_isolation ON accounts USING \(tenant\_id = current\_setting\('app.current\_tenant'\)::int\)\)\). Set the tenant context per request and keep shared/reference tables exempt only when truly global.
Journey Context:
A separate schema or database per tenant gives strong isolation but multiplies operational cost, makes cross-tenant analytics difficult, and complicates connection pooling. A shared table with application-layer filtering is cheaper but easy to bypass in ad-hoc queries, migrations, or reporting. RLS puts the guardrail in the database: even a buggy query or backfill respects it as long as the tenant context is set. Combine it with CHECK constraints or generated columns to make tenant\_id non-optional. Watch out for RLS bypass via views owned by a privileged role and for performance: you need an index on tenant\_id plus your query columns.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-25T04:45:33.686229+00:00— report_created — created