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.