Supabase security checklist for AI-built apps
Supabase lets the browser talk to Postgres directly, which is why it is the default backend for Lovable, Bolt and many Cursor projects. That design is safe only when the database itself enforces who can see what. Here is what to check.
Common security risks in Supabase apps
1. Row Level Security off, or policies that allow everyone
With RLS disabled, the public anon key can read and write every row of the table. Policies like
using (true)are just as open. Every table in an exposed schema needs RLS on and a policy based onauth.uid().2. service_role or secret key in client code
The
service_rolekey, and the newersb_secret_keys, bypass RLS entirely. One copy in a JavaScript bundle gives anyone full database access. Rotate it immediately if it was ever public.3. Storage buckets left public
Public buckets serve every file to anyone with the URL. Keep user uploads in private buckets and serve them with signed URLs or storage policies.
4. RPC functions that skip checks
Postgres functions declared
security definerrun with elevated rights. If they are callable from the client, they must check the caller themselves.5. Auth settings left at defaults
Review email confirmation, redirect URL allow lists and rate limits on sign-up and password reset before launch.
What a FixPrompt scan checks
Passive checks on your public site, the same way a visitor's browser loads it. No attacks, no logins, no data queried.
- Supabase project hosts in your public code, flagged for an RLS review (no data is queried, client keys are not stored)
- Supabase
service_roleJWTs andsb_secret_keys in JavaScript bundles - JWTs in public code that carry a privileged role or identify a person
- Database connection strings (
postgres://…) in client code - Security headers, cookie flags and exposed files on the front end
Copy-paste fix prompt
Paste this into Claude Code, Cursor, Codex or any coding agent with access to your repository. A scan gives you a prompt tailored to the issues found on your live site.
Fix prompt
Harden the Supabase setup in this project: 1. List every table in exposed schemas. Enable Row Level Security on each one and write policies that limit select, insert, update and delete to the owner (auth.uid() = user_id), unless a table is meant to be public. 2. Search the client code for service_role keys, sb_secret_ keys or postgres:// connection strings. Move that logic into Edge Functions or server code and tell me which keys to rotate. 3. Make storage buckets with user files private and use signed URLs. 4. Review every security definer function and add an explicit check on auth.uid(). Show me the SQL for each change and how to test that another user cannot read my data.
FAQ
- Is it safe to expose the Supabase anon key?
- Yes, it is designed to be public, as long as Row Level Security protects every table. The service_role key and sb_secret_ keys must never reach the browser.
- How do I know if RLS is enabled?
- In the Supabase dashboard, open Table Editor or Authentication → Policies: each table shows whether RLS is on. Supabase's Security Advisor also lists tables without it.
- Can an outside scan prove my RLS is correct?
- No, and FixPrompt does not try: it never queries your data. It tells you when your app talks to Supabase directly and when a privileged key is exposed, so you know to review the policies.
Check your Supabase app in minutes
Paste your URL and get a plain-English report with prioritized risks and a fix prompt for your AI. Your first scan is free.
Scan my app free