Explain Supabase RLS code
Paste Supabase row level security SQL and Vibe explains who can read and change which rows: what using and with check each test, what auth.uid() is, and what happens to a request no policy covers.
Up to 1,500 characters (about 60 lines). Your code is sent to Unvibe and Anthropic to write the explanation. Don't paste keys or passwords. Common key formats are refused.
Vibe22 lines selected
Press Explain it for the sample, or paste your own code first.
What this Supabase RLS sample shows
- enabling RLS
enable row level securitymakes every query from theanonandauthenticatedroles see only the rows a policy allows. Without that line the policies did nothing: Ana and a signed-out visitor both read every todo, hers and Sam's. With it on and no policies at all, Ana read 0 rows, and adding a todo failed withnew row violates row-level security policy.- using and with check
usingdecides which existing rows a query can see or touch, andwith checkdecides what a new or changed row may look like. Ana read her 2 todos and Sam read his 1. Ana adding a todo with Sam'suser_idfailed thewith checktest. Her update to Sam's todo changed 0 rows, with no error, becauseusinghid it from her.- auth.uid() and roles
auth.uid()returns the id of the signed-in user making the request, read from their login token.to authenticatedlimits a policy to signed-in requests, so a signed-out visitor, theanonrole, read 0 rows and couldn't add one. Supabase's docs recommend(select auth.uid())over a bareauth.uid()so Postgres works it out once per query, not once per row.- missing policies
- There is no
deletepolicy, so nobody signed in can delete: Ana deleting her own todo changed 0 rows. The update policy also leans on the select policy: with the select policy taken out, Ana could still add a todo with a plain insert but read 0 rows, and marking it done changed 0 rows.
Good to know
- Run on PostgreSQL 18.6 through PGlite 0.5.15, with a small stand-in for Supabase's
authschema and itsanonandauthenticatedroles, andauth.uid()copied from Supabase's own source. Each request set the role and the login token's claims in a transaction, the way Supabase's Data API does. - The table's owner skips these policies, and in this run
postgres, which owns the table and is a superuser, read all 3 todos. Supabase'sservice_rolekey skips them too, so it belongs on a server, never in the browser. - Taking out the update policy's
with checkline didn't open a hole: Postgres then tests the changed row withusing, so Ana giving all her todos to Sam failed. Withwith check (true)instead, the same update went through and the todo became Sam's.
Watch out: A view can quietly skip every policy. A view over todos, created by the table owner and granted to signed-in users, showed Sam his own todo and Ana's. After alter view ... set (security_invoker = true), which needs Postgres 15 or later, the view applied the policies and Sam saw only his own.
Explain Supabase RLS code beside your editor
Unvibe is a free app for Mac and Windows. In the app there is no pasting: select code in any app and press Control+U (Ctrl+Alt+U on Windows).
Install on Mac
curl -fsSL https://unvibe.site/install.sh | bashPaste into Terminal. Unvibe isn't notarized by Apple yet, so this is the smooth path.
Or download the .dmg · Intel Mac build · SHA-256 checksums
Opening the .dmg the first time
- Open the .dmg and drag Unvibe to Applications.
- Open it once; macOS says it can't verify it. Click Done.

Real screen, macOS 15 - System Settings › Privacy & Security › Open Anyway. Confirm, then enter your Mac password. The button shows for about an hour after you try to open Unvibe.

Real screen, macOS 15
The Terminal line checks the download against the published SHA-256 and Unvibe's self-signed signature before it installs anything. More help with the first open