Supabase is safe when Row Level Security is on and its policies are right. Most data leaks in AI-built apps come from tables where RLS was never enabled or policies allow every signed-in user.
What Supabase builds
Supabase provides Postgres, sign-in, file storage and Edge Functions. Lovable, Bolt, v0 and many Cursor projects use it as the back end. The browser talks to the database directly with a public key, so the database rules are the security.
Where Supabase apps usually break
Access rules are on for every table
In Supabase, open Table Editor: every table should show RLS enabled, with at least one policy. In Firebase, your rules should never say allow read, write: if true.
No secret keys reach the browser
Open your live app, then DevTools, Sources, and search the loaded JavaScript for sb_secret_, sk_live_, sk-proj- and sk-ant-. Older Supabase keys are long tokens starting with eyJ: decode the middle part of each on your own machine, and if it contains "role":"service_role", your secret key is public. A publishable or anon key in the browser is expected.
File storage is private where it should be
Upload a private file, copy its URL, and open it in a private window. If it loads, the bucket is public.
Admin actions are checked on the server
Hiding an admin button is not protection. Call the admin endpoint as a normal user and confirm it is refused.
Database backups run automatically and a restore has been tested
Check what your database plan actually includes, then restore a backup into a test project once.
Testing and real users use separate databases
Experiments and AI agents should never run against production data.
Check it yourself
- In Table Editor, look for tables marked as having RLS disabled. Enable it and add policies before launch.
- Read each policy.
using (true)or a check for any signed-in user lets every user see every row. - Confirm the secret key (
sb_secret_…, or the legacy service_role key) is used only in Edge Functions or on your server, never in front-end code. - Review Storage buckets: anything with personal files should be private, with policies.
- Check which backups your plan includes and how far back you can restore.
A policy that keeps each user's rows private
alter table public.profiles enable row level security;
create policy "Users can read their own profile"
on public.profiles for select
to authenticated
using ((select auth.uid()) = user_id);
Replace profiles and user_id with your table and the column that holds the owner's id, then add matching policies for insert, update and delete.
When to call an engineer
Call an engineer when you find tables with personal or payment data and RLS off, or when you are not sure what a policy allows.
A one-off check costs $49 to $800. Fixing and hardening an app costs $1,500 to $15,000 and takes 1 to 8 weeks, based on the prices companies publish.
Top-rated companies for Supabase apps
Ranked by our score: published prices, scope of work, AI tools named, timing and a low-risk first step. How we score.
- 1Redlab10.0/10Best for: A full rescue by one team that keeps buildingFree first step · from $490
- 2Vibe Code Rescue (Lev Arakelyan)9.0/10Best for: A one-off check and a cleanupFrom $299
- 3LazyCodeLab9.0/10Best for: A one-off check and a cleanupFrom $399
Questions
Is it a problem that my Supabase key is visible in the browser?
No, if it is the anon or publishable key and RLS is set up. The service role or secret key must never be visible.
What is the fastest way to check RLS?
Open Table Editor in the Supabase dashboard. Tables without RLS are flagged, and the Security Advisor lists them too.
What should a Supabase RLS audit service check?
Every table's policies, not only whether RLS is on; storage bucket rules; where the secret key is used; and Edge Functions that bypass the rules. Ask for a test that proves one customer cannot read, change or delete another customer's rows, and for a recheck after the fixes.
