Is your AI-built app leaking data? A 10-minute Supabase check
Apps built with Lovable or Bolt on Supabase often go live with tables anyone can read. How to check yours in ten minutes, and what to fix first.
3 min read
Apps built with Lovable, Bolt or similar tools usually store their data in Supabase. That is a good choice: Supabase is a real Postgres database with authentication built in. But it comes with one rule that AI tools don’t always follow, and when they miss it, the app’s data can be read by anyone who opens the browser’s developer tools.
This guide shows how to check your own app in about ten minutes, without installing anything.
Why the key in your app is public
Your app talks to Supabase from the browser, so the browser needs a key. That key, called the anon key (or publishable key in newer projects), is shipped inside your app’s JavaScript. Anyone can find it. This is by design.
What protects your data is not the key but Row Level Security (RLS): rules in the database that decide which rows each visitor may read or change. With RLS on and good rules, a public key is harmless. With RLS off, the public key reads the whole table.
| Situation | What a stranger with your public key can do |
|---|---|
| RLS off on a table | Read (and often change) every row |
| RLS on, no rules | Nothing: every request is refused |
RLS on, rule using (true) |
The same as RLS off, for the actions and roles the rule covers |
RLS on, rule tied to auth.uid() |
Only rows that belong to the signed-in user |
Step 1: list tables without RLS
Open your project in the Supabase dashboard, go to the SQL Editor and run:
select c.relname as table_name,
c.relrowsecurity as rls_enabled
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public'
and c.relkind = 'r'
order by c.relrowsecurity, c.relname;Every row with rls_enabled = false is a table the public key can reach. Tables created in the Table Editor get RLS by default; tables created by SQL, which is how most AI tools create them, do not.
The dashboard’s Security Advisor flags the same problem as RLS Disabled in Public. If it shows any errors, start there.
Step 2: look for rules that allow everything
RLS that is on but too generous is just as open. List your rules:
select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, cmd;Look closely at rules where qual or with_check is simply true, especially for the anon or public roles. A rule like that on a profiles or orders table means anyone can read every profile or every order.
Step 3: confirm from the outside
Now test it the way an attacker would: with only the public key. Find your project URL and key under Project Settings → API, then run:
curl "https://YOUR-PROJECT.supabase.co/rest/v1/profiles?select=*&limit=5" \
-H "apikey: YOUR_PUBLIC_KEY"How to read the answer:
- Rows that are not yours: the table is exposed. Fix it today.
- An empty list
[]: either the table is empty or RLS is filtering everything out, which is what you want. - A permission error: the table is not reachable through the API at all. Also good.
Repeat for every table that holds personal data, payments or anything private.
Step 4: make sure the secret key is not in your app
Supabase also gives you a service role key (or secret key, starting with sb_secret_). It ignores RLS completely and must only ever live on a server. Open your live app, press F12, go to Sources and search the JavaScript for service_role and sb_secret_. If either appears, rotate the key in the dashboard immediately and move the code that needed it to a server function.
What to fix first
- Rotate any secret key that reached the browser.
- Enable RLS on every table in the public schema:
alter table public.profiles enable row level security; - Replace
using (true)rules on private tables with rules tied to the signed-in user. - Run Step 3 again and confirm that a stranger gets nothing.
Turning RLS on will break any screen that relied on the open table. That is expected: each screen now needs a rule that allows exactly what it should. If your app was generated by AI and you are not sure which rules it needs, that is the work our Security Check starts with.
SupabaseLovableRow Level SecurityAI-built apps
Keep reading
All articles
App security
Found your Supabase secret key in the browser? What to do in the first hour
A service role or secret key in your frontend gives anyone full access to your database. What to do, in order: revoke, replace, check the logs, fix the cause.
5 min read

Websites
Why your contact form emails land in spam (and how SPF, DKIM and DMARC fix it)
Messages from your website form go to spam or never arrive? Usually it is how they are sent, not what they say. What to check and the three DNS records to fix.
4 min read