Why this matters
The ‘anon’ key in a front-end app is public by design. Without RLS, anyone who finds it can query tables directly. Most Supabase data exposures come from missing or overly broad policies, not from clever attacks.
How RLS works
- RLS is enabled per table; with it on and no policy, access is denied.
- Policies are rules such as ‘a user can select rows where user_id equals their own id’.
- Separate policies for select, insert, update and delete.
- The service-role key bypasses RLS and must never be in client code.
Test it properly
- Enable RLS on every table in the public schema.
- Write policies that reference auth.uid() for per-user data.
- Test as an anonymous visitor: you should see nothing private.
- Test as user A trying to read or edit user B’s rows: it should fail.
- Review storage bucket policies too.
- Check views and functions that might bypass policies.
Pre-launch checklist
- No service-role key in the front end or repository
- RLS on all tables, tested
- Storage buckets private unless intentionally public
- Rate limits and spend caps on any paid API
- Backups enabled and restore tested
Need help shipping your app? From $100/h
We deploy, secure and support apps built with AI tools. Send the repo for a free review.
Frequently asked questions
Is the Supabase anon key a secret?
No. It is meant to be public, which is why RLS must protect the data.
Can AI tools write correct policies?
They can draft them, but you must test them as different users; mistakes are common.
Can you review my Supabase setup?
Yes. It is part of our AI-built app security review.
Get a free quote in 24 hours
Tell us what you need. We reply with scope, timeline and a fixed price.