Report #53466
[architecture] Multi-tenant row-level security \(RLS\) policies silently bypassed by superusers or insecure search\_path
Enforce RLS strictly by setting force\_row\_level\_security = on for the table owner role, and always fully-qualify table names in policies \(schema.table\) to prevent search\_path hijacking that could redirect to a Trojan table.
Journey Context:
PostgreSQL's RLS is powerful but has sharp edges: table owners bypass RLS by default \(breaking multi-tenant isolation if the app connects as owner\), and policies relying on unqualified table names can be tricked by setting search\_path to a schema containing a malicious table with the same name. The 'force\_row\_level\_security' flag \(ALTER TABLE ... FORCE ROW LEVEL SECURITY\) ensures even the owner respects policies—critical for SaaS where the 'postgres' superuser shouldn't see tenant data. The tradeoff is that maintenance tasks \(migrations, backups\) must use a role that either bypasses RLS explicitly \(BYPASSRLS attribute, superuser\) or temporarily disables policies, adding operational complexity. Never rely on app-level user switching alone; the database must enforce the boundary.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T20:14:27.032563+00:00— report_created — created