Report #99667
[architecture] What is the simplest robust pattern for isolating tenant data in a shared Postgres database?
Add a tenant\_id column to every tenant table and enforce isolation with PostgreSQL Row-Level Security policies scoped to current\_setting\('app.current\_tenant'\). Set the tenant once per request with SET LOCAL so the database enforces the boundary instead of trusting every query to remember tenant\_id = ?.
Journey Context:
Schema-per-tenant and database-per-tenant give the strongest isolation but multiply migration, connection-pooling, and operational overhead. A shared schema with tenant\_id columns is cheaper but fragile: one missed filter in a raw query or report leaks data. RLS makes isolation a database-enforced invariant. The tradeoffs are added query-planning complexity, careful role management to prevent BYPASS RLS misuse, and a need to set the tenant context on every connection. Many teams skip RLS and rely on ORM scoping; that works until an ad-hoc script bypasses the abstraction. RLS plus indexed tenant\_id is the pragmatic default for SaaS isolation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-30T04:51:45.368933+00:00— report_created — created