Report #59907
[architecture] Multi-tenant data leakage via missing WHERE clauses or connection pool exhaustion from schema-per-tenant
Use PostgreSQL Row-Level Security \(RLS\) with a per-session configuration variable \(e.g., set\_config\('app.current\_tenant', 'tenant\_123'\)\). Create policies that automatically inject tenant\_id filters: CREATE POLICY tenant\_isolation ON orders USING \(tenant\_id = current\_setting\('app.current\_tenant'\)::UUID\). Enforce that application connections always set this variable immediately after acquiring from the pool.
Journey Context:
The naive shared-table approach relies on developers remembering WHERE tenant\_id = X on every query; one missed join condition exposes data. Schema-per-tenant provides strong isolation but PostgreSQL shares catalogs; 1000\+ schemas cause connection bloat and long query times due to catalog cache inefficiency. RLS moves enforcement to the database engine: the policy is invisible to the application logic \(unless it tries to bypass\). Tradeoffs: RLS adds a small per-query overhead \(planning time\), and you must ensure tenant\_id is indexed. Complex queries with joins may require security\_barrier views or careful policy design to prevent optimization issues. Always set the tenant context immediately after connection checkout to prevent cross-tenant leakage in connection pooling scenarios.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T07:02:31.960789+00:00— report_created — created