If you built your app with Lovable, Bolt.new, Cursor, or Claude Code and you're using Supabase as your backend — there's a good chance your database is accessible to anyone on the internet right now.
Not hypothetically. Literally right now.
Here's why, and what to do about it.
What Supabase RLS actually is
Supabase gives every project an anon key — a public API key that ships inside your frontend code. It's visible to anyone who opens your app and inspects the page source or network requests. Supabase knows this, so they built Row Level Security (RLS): a layer of policies that sit between the anon key and your data and control what it's allowed to read or write.
The problem: RLS is disabled by default on every table.
When RLS is off, the anon key can query any table it has access to without restriction. That means anyone who finds your key — which is trivially easy — can make direct API calls to your Supabase project and pull whatever's in those tables.
What AI tools do with this
Lovable, Bolt.new, and Claude Code all generate working Supabase integrations. The auth flow works. Users can sign in. Data gets written to the right tables. From a functional standpoint, everything looks correct.
But none of these tools enable RLS policies by default, because writing correct RLS policies requires understanding your specific data model and access requirements. That's judgment that an AI tool can't make on your behalf — so it skips the step.
The result: your app works fine, your users don't notice anything wrong, and your database is sitting open behind a key that's visible in your frontend bundle.
How to check if you're affected
- Open your Supabase dashboard and go to Table Editor
- Look at the RLS column next to each table
- If it shows a red shield or says "RLS disabled" — your data is accessible via the
anonkey
You can also test it directly. Take your Supabase URL and anon key (both visible in your project settings) and run:
curl https://YOUR-PROJECT.supabase.co/rest/v1/YOUR-TABLE \
-H "apikey: YOUR-ANON-KEY" \
-H "Authorization: Bearer YOUR-ANON-KEY"
If you get data back, so can anyone else.
What's actually at risk
This depends on what's in your tables. Common cases:
- User profiles — names, email addresses, profile data for every account
- Orders and bookings — full transaction history, customer contact details
- Messages — anything users have sent through your app
- Business data — internal records, client data, pricing, whatever your app stores
For apps with payments, the exposure often extends to booking details, billing records, and in some cases partial card data if it was stored incorrectly.
How to fix it
Step 1 — Enable RLS on every table
In Supabase dashboard: Table Editor → select a table → RLS tab → Enable RLS.
Do this for every table. Once enabled, the table is locked down — nothing can read or write to it via the anon key until you add explicit policies.
Step 2 — Write policies for authenticated access
This is the part where it gets specific to your app. A basic policy for authenticated users to read their own data:
CREATE POLICY "Users can read own data"
ON public.profiles
FOR SELECT
USING (auth.uid() = user_id);
You need a policy for each operation (SELECT, INSERT, UPDATE, DELETE) on each table, scoped to what that operation should actually allow.
Step 3 — Check service role usage
Your app might also use Supabase's service_role key for admin operations. This key bypasses RLS entirely — which is intentional for server-side operations, but dangerous if it's accidentally exposed in frontend code or a public API route. Make sure it only exists server-side.
The fix AI tools usually get wrong
If you paste this issue into Claude or ChatGPT and ask it to fix the RLS policies, it'll generate something that looks correct. The problem: it's generating generic policies based on what it knows about common Supabase patterns, not what's actually in your schema.
Common results:
- Policies that reference a
user_idcolumn that doesn't exist in your table - Missing policies for edge cases (public vs. private records, admin roles)
- Policies that silently fail — RLS is "on" but the policy logic is wrong and blocks all access or allows all access
The fix requires reading your actual schema, understanding what each table stores and who should see it, and testing the policies against real queries. That's the part that needs a person.
One more thing — new tables
Claude Code and other AI tools add new tables as your app grows. Every time a migration creates a new table, RLS defaults to off on that table too. If you ran an audit last month and fixed everything, a new feature shipped since then may have introduced new unprotected tables.
This is worth checking after every significant feature addition, not just once.
If you're not sure whether your Supabase setup is secure, Archer Labs does free threat briefs for AI-built apps. We'll look at your specific stack and tell you exactly what's accessible and what isn't — no scanner, no generic report.