Detection rules
9 rules ship today. This page is generated from the running catalog, so it is exhaustive — anything not listed here is not detected.
Catalog rules
Run against a connected project, reading pg_catalog and storage.buckets metadata only.
Any table reachable through PostgREST with RLS disabled is world-readable to anyone holding the anon key — which ships in your client bundle and is public by design. Every row is exposed.
RLS_DISABLEDWith RLS on and zero policies, Postgres denies every row to non-owner roles. Data is safe but the table is functionally unreachable from the client, which usually means the setup was left half-finished.
RLS_NO_POLICIESA permissive policy whose expression is a constant true grants the whole table to every role it targets. RLS is enabled, so the dashboard reports the table as protected while it is wide open.
RLS_TAUTOLOGYAn INSERT policy with no WITH CHECK clause does not constrain the rows being written, so a caller can insert rows attributed to other users. On UPDATE and ALL, Postgres uses the USING expression as the write check when WITH CHECK is omitted, and that fallback is not itself an ownership bypass. This rule reports an INSERT that omits WITH CHECK, and an UPDATE or ALL policy only when it also has no USING expression to fall back on.
MISSING_WITH_CHECKRLS predicates run on every candidate row. When the predicate column has no index, each query degrades into a sequential scan — the single most common cause of Supabase bills growing faster than traffic.
UNINDEXED_RLS_PREDICATEObjects in a public bucket are served to anyone with the URL, with no auth check. Object paths are frequently guessable, so "public" means "published" for anything stored there.
PUBLIC_BUCKET_EXPOSUREA bare auth.uid() inside a policy is re-evaluated once per candidate row. Wrapping it as (SELECT auth.uid()) lets the planner hoist it into an InitPlan evaluated once per statement — routinely a 10-100x speedup on large tables, with identical semantics.
RLS_UNWRAPPED_AUTH_CALLProbe rules
Run against a public URL with no credential, using the same access an attacker has.
The service_role key bypasses RLS entirely. Once it is in a client bundle it is public, and every policy in the project is decorative. Rotate the key immediately and move the calls that need it behind a server route.
SERVICE_ROLE_KEY_EXPOSEDThis table returned rows to an unauthenticated request carrying only the public anon key. Anything visible here is visible to the internet.
ANON_TABLE_READABLENot covered
SECURITY DEFINER views, anon-callable SECURITY DEFINER functions and function search_path mutability are not analysed. The Supabase Security Advisor covers those; the queries to check them by hand are documented.