Two silent bugs in Postgres Row Level Security that break multi-tenant isolation
Postgres Row Level Security (RLS) is a popular method for enforcing tenant data isolation at the database level, but two subtle misconfigurations can render its policies completely ineffective. First, if an application connects using a superuser or table-owner role, RLS policies are bypassed entirely, meaning all tenants' data remains exposed regardless of the policies defined. The fix requires creating a dedicated application role with NOBYPASSRLS and applying FORCE ROW LEVEL SECURITY to tables, separating migration credentials from runtime credentials. Second, when using connection pools, the session variable set via set_config with is_local=true resets to an empty string rather than NULL after a transaction ends, causing subsequent pooled connections without a tenant context to throw a UUID cast error. Wrapping the current_setting call with NULLIF resolves this by converting the empty string back to NULL, preventing accidental data leaks or crashes under concurrent load.
This is an AI-generated summary. ShortSingh links to the original source for the complete article.
Discussion (0)
Log in to join the discussion and vote.
Log in