Find the RLS holes before your users do.
The most common way an AI-built app leaks data is not a crash. It is quiet: row level security switched off on a table nobody remembered, or switched on while a policy lets everything through. This one SQL file finds those holes in about a minute.
Free. Read-only. No install, no account access, no keys shared.
One SQL file. You paste it and run it. It reads, it never writes.
You open your Supabase SQL editor, paste the file, and run it. It reads your database's own catalog and hands back a prioritized list of the security holes that matter, each with a plain-language explanation and a starting-point fix. It never reads your rows, changes a setting, or phones home, and it even runs inside a read-only transaction. Read the code and see for yourself.
Six mistakes, worst first.
RLS switched off
The number one leak. When the API roles hold grants on a table without row security, anyone holding your public key can read and write every row.
An insert policy that checks nothing
A policy whose check is simply true lets a user insert rows carrying someone else's id. With no TO clause, signed-out visitors can do it too.
RLS on, zero policies
Row security is on but no policy exists, so PostgreSQL refuses everything: reads come back empty and inserts fail with error 42501.
Policies that never run: no grant
Supabase stopped granting new tables to its API roles by default (new projects since May 30, 2026, existing projects from October 30, 2026). A table made in SQL can have perfect policies and still answer every request with permission denied for table. The auditor names the table and the missing privilege, and prints the GRANT that fixes it.
Any row open to update or delete
A policy whose condition is always true, on a table where other users' rows are readable, so one user can change or delete another's rows.
A view that skips your policies
A view runs with the rights of whoever created it unless you tell it otherwise, so it can hand back rows your row security would hide. Even one that filters by the signed-in user can let them write rows as someone else, if the view can be written through.
Plus three smaller checks: update policies that check nothing, tables readable by everyone, and insert policies that grant nothing. Every check is tested against a real PostgreSQL, both ways: policies known to be safe must produce no finding, and policies known to be dangerous must produce the right one.
The tables an AI builder makes for you do not get row security by default.
This is the part that catches people, and it is documented behaviour rather than a bug. Supabase turns row level security on automatically for a table you create through the dashboard. A table created in SQL does not get it. As Supabase's own documentation puts it: "Tables created through the Supabase Dashboard have RLS enabled by default. Enable RLS explicitly for tables created in the SQL Editor or through another tool."
AI builders write raw SQL. Lovable, Bolt, Replit and the rest create your schema through the SQL editor, not by hand in the Table Editor, so the one path that switches row security on for you is the path your app never took. That single detail explains most of what the auditor finds on an AI-built project.
The second most common finding is subtler, because the table looks protected. A policy decides which rows a user can read and, separately, which new rows it will accept. PostgreSQL is explicit about the split:
"Existing table rows are checked against the expression specified in USING, while new rows that would be created via INSERT or UPDATE are checked against the expression specified in WITH CHECK." PostgreSQL documentation, CREATE POLICY
Set that check to true, the way a one-line "signed-in users can insert"
policy does, and every signed-in user can insert rows carrying someone else's id. It passes
every test you run as yourself and is wrong in production. (A missing
WITH CHECK is not the problem it is often said to be: on an update policy,
PostgreSQL reuses USING as the check. We tested both on a real PostgreSQL.)
And when row security is on with no policy behind it, PostgreSQL refuses the write with
error code 42501, which its error appendix defines as
insufficient_privilege.
That error is not the problem. It is the symptom of a table whose policies were never
written, and it is the one people paste into a search box at two in the morning. We wrote up
all six causes of 42501 and their fixes.
Three steps, about a minute, nothing shared.
To check a Supabase project for row level security holes: open the SQL editor in your own
dashboard, run a read-only query against the Postgres catalog tables that store your policies,
and read off which tables have row security disabled, enabled with no policy behind it, or a
write policy with no WITH CHECK clause. You do not need to install anything or
give anyone access to do it.
Open your own SQL editor
In your Supabase dashboard, open the SQL editor. Everything happens inside your project. Nothing is pasted into anyone else's form.
Paste the auditor and run it
It queries the catalog only: which tables have row security on, which policies exist, what each policy actually checks, and which views run with their creator's rights.
Read the findings worst first
You get a severity-ordered list, each row naming the table, the specific hole, and the SQL that closes it. Fix the criticals before anything else ships.
Safe by design, so you never have to trust us with anything.
Most free RLS checkers are websites that ask you to paste your project URL and your anon key into someone else's form. This one never asks. It is a SQL file you run inside your own dashboard, and every finding comes with a starting-point fix, not just a warning.
No install
It is plain SQL. There is nothing to run on your machine and nothing to add to your project.
No account access
You never share your database password, your service key, or your project. You run it yourself, inside your own dashboard.
Read-only
It reads system catalogs only. It does not read your rows, write anything, or change a setting.
Works everywhere
Any Supabase project, nothing to configure.
Tested in public
Every check runs against a real PostgreSQL, with policies known to be safe and known to be dangerous. The source and the tests are on GitHub.
Run your preflight.
What is the auditor? One read-only SQL file. Download it, paste it into your Supabase SQL editor, and read your findings. It catches the common, repeated failure patterns fast. It is not a full penetration test, so a high-stakes app still deserves a real review. Use it as your pre-launch preflight.
The free download is the read-only auditor SQL plus a plain-language README.
Want the fixes handed to you? The full security pack, $11.40 launch price Launch price USD 11.40 (normal USD 19) for the first 25 buyers or until 2026-10-31, whichever comes first. The code is already in the link., adds a tested fix recipe for every finding and for the three RLS errors people hit most, plus a Claude Code skill that writes the fixes for your exact tables.
Hitting an error right now? 42501, new row violates row-level security policy · the same error on a Storage upload · auth.uid() is null and every policy fails · 42P17, infinite recursion detected in policy · must be owner of table messages · permission denied for table, a missing grant
Designing the policies? Multi-tenant RLS with a membership table, tested on two tenants · works locally but not in production, the five checks in order
Want the fixes written out?
The auditor is free and read-only, and every finding comes with a starting-point fix. If you want a tested recipe for each finding, the RLS Security Pack has them. It is sold through Gumroad, one payment, USD 19.
Get the RLS Security PackLaunch price USD 11.40 (normal USD 19) for the first 25 buyers or until 2026-10-31, whichever comes first. The code is already in the link.
Straight answers.
- Is it safe to run on my production database?
- Yes. It reads system catalogs only. It does not touch your data, change any setting, or send anything anywhere. You can read the whole file before you run it.
- Do I have to share my keys or give access?
- No. You paste and run it yourself inside your own Supabase SQL editor. You never share a password, a service key, or your project with anyone.
- What if it finds a problem I do not know how to fix?
- Each finding comes with a starting-point fix. The full pack ($19) adds a tested recipe for every finding and a Claude Code skill that writes the fixes for your exact tables. The auditor itself is free; the pack is sold through Gumroad.
- Does a policy without WITH CHECK leak data?
- Not on an update policy, whatever you may have read: PostgreSQL reuses USING as the check when WITH CHECK is missing. The policy that does leak is one whose check is always true, which lets a user insert rows carrying someone else's id. We tested both on a real PostgreSQL, and the auditor flags only the second.
- Is this a full security audit?
- No. It catches the common, high-frequency RLS mistakes that leak data in AI-built apps. Treat it as a fast preflight, not a replacement for a full review on a high-stakes app.
- Why does an AI-built Supabase app so often have RLS switched off?
- Because of which path created the table. Supabase enables row level security automatically for tables created through the dashboard, but not for tables created in the SQL Editor or through another tool, where you have to enable it yourself. AI builders such as Lovable, Bolt and Replit generate your schema in SQL, so the one path that turns row security on for you is the path your app never took.
- What does Postgres error 42501 mean in Supabase?
- 42501 is the PostgreSQL error code for insufficient_privilege. In a Supabase app it usually means row level security is enabled on the table but no policy grants the current role access, so the query is refused. The error is the symptom; the missing policy is the cause.