Skip to main content

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.

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.