Supabase RLS policy generator
Pick a table and who should be able to see and change its rows. You get SQL to paste into the Supabase SQL editor, with Row Level Security policies and the grants that tables created after 30 October 2026 need. Everything runs in your browser; nothing is sent to us.
Your SQL
What this does
How to use it
- Open your project in Supabase, then SQL Editor → New query.
- Paste the SQL and click Run. Do one table at a time.
- Check Authentication → Policies for older policies on the same table and delete any you don't want. Policies add up, so an old
using (true)policy still lets everyone in. - Test it: log out of your app and check the data is gone, then log in as a second user and check you can't see the first user's rows.
If your app was built with Lovable, Bolt or Cursor, you can copy the prompt version instead. It tells the AI not to "fix" any error by switching RLS off, which is the most common way these settings get undone.
Why the grants are there
From 30 October 2026, new tables in existing Supabase projects are no longer opened to the Data API automatically: they need a grant before your app can reach them. The SQL above grants only what each pattern needs, and removes access for logged-out visitors (anon) wherever they shouldn't have it. Tables you created before the change keep their old grants, so running this on them tightens access too. More on the 30 October change.
Check your live app too
Policies protect your tables, but leaks also come from elsewhere: a service_role key in the frontend, a public storage bucket, or a .env file your host serves. LeakPatrol's free scan checks your live app from the outside in about a minute.
Check your app in a minute
Free, read-only, no sign-up. Every problem comes with a plain-English fix and a prompt for your AI tool.
Get the 10-point checklist
Every check we run on AI-built apps, with how to do each one yourself. Straight to your inbox.
Plus an email when automatic re-checks launch, and the odd tip. Unsubscribe any time.
Questions
How do I write a Supabase RLS policy so users only see their own rows?
Enable row level security on the table, then create policies for select, insert, update and delete that compare the owner column with (select auth.uid()), for example using ((select auth.uid()) = user_id). Add with check on insert and update so users cannot create or move rows to someone else.
Why use (select auth.uid()) instead of auth.uid() in policies?
Wrapping auth.uid() in a select lets Postgres evaluate it once per query instead of once per row, which Supabase recommends for performance on larger tables. The result is the same.
How do I let anyone submit a form but not read the submissions in Supabase?
Enable RLS, grant only insert to anon and authenticated, and add an insert policy with check (true) and no select policy. In the app, insert without chaining .select(), because reading the row back is not allowed.
Do I need GRANT statements as well as RLS policies in Supabase?
For tables created after 30 October 2026 in existing projects, yes: new tables are not granted to anon and authenticated automatically, so the Data API cannot reach them until you grant access. RLS policies then decide which rows each user can see.