PostgreSQL Security Invoker Views Change Who Enforces RLS
PostgreSQL Security Invoker Views Change Who Enforces RLS A PostgreSQL view is a saved query, not a fixed materialized result. That distinction matters when the view sits in front of tenant tables protected by row-leve
PostgreSQL Security Invoker Views Change Who Enforces RLS
A PostgreSQL view is a saved query, not a fixed materialized result. That distinction matters when the view sits in front of tenant tables protected by row-level security. The default view behavior applies the policies of the view owner and checks access to underlying relations with the owner's permissions. A view created to simplify a query can therefore become an authorization boundary that the application never intended to delegate.
PostgreSQL's security_invoker option changes the check to the user of the view. If the option is enabled, the underlying base relations are checked against the invoking user's privileges. The documentation also recommends considering security_barrier when a view is intended to provide row-level security. These are related controls, but they are not interchangeable. The invoker option changes whose privileges are checked; the barrier option changes how predicates and functions may be optimized.
The migration question
An application may have introduced a tenant-filtered view under one role and granted SELECT on the view to many users. If the view runs with the owner's rights, a caller can read rows that the owner can see unless the view query itself filters by the caller. The query may use current_user or a session setting, but that logic must be reviewed as an authorization rule. A view that was copied from a reporting schema may have no such filter at all.
The reverse mistake is also possible. Adding security_invoker=true to a view used by an internal reporting role can break the report because that role lacks direct access to the base tables. The fix should be a deliberate grant or a separate reporting role, not a blanket switch back to owner rights.
Inventory every view that exposes tenant-owned tables, authentication data, billing records, audit trails, or owner identifiers. Record the view owner, grants, security_invoker setting, security_barrier setting, and the row-level security status of each referenced relation. Include views owned by migration roles and application superusers; those are the ones most likely to bypass the policy that a service role would enforce.
Functions require their own review
The view setting does not rewrite the security mode of every function called by the view. A function may be SECURITY INVOKER or SECURITY DEFINER, and a definer function can still execute with privileges that the view invoker does not have. Review functions that query other relations, evaluate policies, or return dynamic SQL. A leakproof declaration also needs scrutiny because row-level security optimization depends on the function's actual behavior.
Write tests with two users from different tenants and a third user with only view access. Query the view directly, through an application role, and through an ORM connection pool. Check EXPLAIN to see whether predicates are pushed into the view or the barrier forces an evaluation order. Do not rely on a test that uses a superuser, because superusers can bypass row-level security and will hide the defect.
Operational rule
Make the security mode explicit in migrations. A tenant-scoped view should state whether it is an invoker view and whether it needs a barrier. If the application uses database roles as its primary tenant boundary, the default owner-rights behavior should be treated as an exception with a documented reason.
Review after upgrades and schema changes. A newly added base relation or function can change the effective policy even when the view SQL appears unchanged. The question is not whether the view is convenient. It is whether the caller, the view owner, and every function in the path exercise the same authorization rules.
References
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes â full credit and traffic to the original publisher.