What do your Supabase policies really allow?
AI tools write Row Level Security policies that look right and let everyone in. Paste yours and read each one in plain English, with the mistakes flagged.
- Plain English for every policy
- Catches using (true), user_metadata and RLS turned off
- Runs in your browser, nothing is sent
Get all your policies from Supabase in one go
Open the SQL editor in your Supabase dashboard, run this read-only query, and paste the results above. It prints every policy and whether RLS is on for each table.
select format('alter table %I.%I %s row level security;', n.nspname, c.relname, case when c.relrowsecurity then 'enable' else 'disable' end) as statement from pg_class c join pg_namespace n on n.oid = c.relnamespace where n.nspname = 'public' and c.relkind = 'r' union all select format('create policy %I on %I.%I as %s for %s to %s%s%s;', policyname, schemaname, tablename, permissive, cmd, array_to_string(roles, ', '), coalesce(' using (' || qual || ')', ''), coalesce(' with check (' || with_check || ')', '')) from pg_policies where schemaname = 'public';
Runs in your browser. Nothing you paste is sent anywhere.
The policy mistakes AI tools make
using (true) means "every row". On a table of personal data, that is a leak with extra steps. AI tools write it to make a permission error go away.
auth.role() = 'authenticated' lets every signed-in user through, so anyone who signs up can read everyone's rows. Ownership needs auth.uid() = user_id.
user_metadata is editable by the user it belongs to. A policy that checks it for an admin role lets anyone make themselves admin. Use app_metadata or your own roles table.
with check (true) on an update lets users save any values, including moving a row to another account.
A safe pattern for personal data
- Turn on Row Level Security for the table.
- Add a select policy
to authenticated using ((select auth.uid()) = user_id). - Add insert, update and delete policies with the same check, using
with checkfor insert and update. - Paste them here: each should read “only rows where user_id is their own user id”.
Questions
- Where do I find my policies?
- In your Supabase dashboard under each table's policies, or in your migration files. Easiest: run the read-only query on this page in the SQL editor; it prints every policy and every table's RLS setting, ready to paste.
- Is it safe to paste my policies here?
- Yes. Policies contain no keys or data, and the checker runs entirely in your browser: nothing you paste leaves your computer.
- If the checker finds nothing, am I safe?
- It reads the policies you paste and flags known mistakes; it cannot know what each table should allow. Read every plain-English line and ask: is that what this data needs? Then confirm from outside with the Supabase RLS checker.