Report #74676
[architecture] Row-Level Security performance degradation and bypass risks in multi-tenant apps
When using PostgreSQL RLS for multi-tenancy, always include \`tenant\_id\` as the leading column in all indexes and use \`SECURITY INVOKER\` views to prevent privilege escalation; if query patterns require frequent cross-tenant analytics, materialize a separate star schema rather than relying on RLS-filtered scans.
Journey Context:
RLS appears ideal for multi-tenant isolation \(automatic filtering via policy\), but it introduces major performance pitfalls. The optimizer often cannot push down predicates through RLS policies effectively, leading to sequential scans even when tenant-specific indexes exist. Policies must be written carefully to use immutable functions and proper index columns. More critically, RLS can be bypassed by table owners or superusers, and \`SECURITY DEFINER\` functions can inadvertently expose data if not carefully crafted. Schema-per-tenant provides better isolation and query plans at the cost of complex migrations \(running DDL across thousands of schemas\). The compromise is often RLS for simplicity but with strict indexing discipline and regular policy auditing, or schema-per-tenant for high-compliance scenarios.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T07:56:31.734922+00:00— report_created — created