The worst time to find a broken RLS policy is after launch. You can test policies in the SQL editor by acting as a specific user, with no app code involved.
1. Act as an authenticated user
Run this inside a transaction so nothing is left changed:
begin;
set local role authenticated;
set local request.jwt.claims = '{"sub": "00000000-0000-0000-0000-000000000001"}';
select * from notes; -- should return only this user's rows
rollback;Replace the UUID with a real user id. If you see rows that belong to someone else, the policy is wrong.
2. Test the anonymous case
begin;
set local role anon;
select * from notes; -- should return nothing
rollback;3. Test writes, not just reads
Try an insert with another user's id, and an update or delete on a row you do not own. Each should fail or affect zero rows:
begin;
set local role authenticated;
set local request.jwt.claims = '{"sub": "00000000-0000-0000-0000-000000000001"}';
insert into notes (user_id, body)
values ('00000000-0000-0000-0000-000000000002', 'not mine');
rollback;4. Check which tables have RLS off
select schemaname, tablename
from pg_tables
where schemaname = 'public' and rowsecurity = false;Every table in the exposed schema should be in the list of tables you meant to leave open, which is usually empty.
Free cheat sheet
Get the main RLS checks on one page: Supabase RLS Cheat Sheet (free PDF).
Want the full set?
The guide Supabase RLS Policies: Copy-Paste Examples has 31 patterns (ownership, teams, roles, sharing, invites, soft delete) and a testing section. If you are building on Next.js and Supabase, start with the Start here collection. All purchases come with a 14-day money-back guarantee.