SEC.PRIV.ROLE_BYPASSRLS — Row-level security does not apply to this account
- Category: security
- Severity: high
- Level: 0
- Confidence: deterministic
- Downtime class: none — the finding is about an account, not about a statement
- Stability: stable
- Suites: audit
- Applies to: PostgreSQL 18
The audit of your policies comes back clean, and it is beside the point
Row-level security is what a multi-tenant application relies on to keep one tenant's rows away from
another's. An account with BYPASSRLS reads and writes every row of every table with a policy, and
nothing in the policy definitions says so — you can review every CREATE POLICY in the schema and
find nothing wrong.
Why high, when this rule cannot see your policies
The consequence depends on whether you use RLS, and this rule reads roles rather than policies — so the
first draft rated it medium. That is right about the consequence and wrong about the risk, for one
reason: nobody sets this by accident. BYPASSRLS is not a default, not a side effect of a
framework, and not something a managed provider hands out. An account has it because somebody typed it.
A finding that rare is exactly the shape a high should have. And where it does fire, the protection
you believe you have is not there.
The finding still states its limit rather than overclaiming: it says what to check, and never that a particular table is exposed.
Bad
ALTER ROLE reporting BYPASSRLS;
Good
ALTER ROLE reporting NOBYPASSRLS;
-- If a job legitimately reads across tenants, give it a policy that says so out loud.
CREATE POLICY reporting_all ON invoices FOR SELECT TO reporting USING (true);
A policy is reviewable; an attribute that silently disables every policy is not.
Related
A superuser bypasses RLS whether or not it carries the attribute. When that is the case SQLens reports
SEC.PRIV.ROLE_SUPERUSER instead — the larger finding, which this one follows from.