VibeSec

// guides

How to Secure a Supabase App: The Mistakes AI Tools Make

7 min read

Supabase is great, but AI tools often leave it wide open. The good news: the fixes are simple once you know what to look for.

The anon key being public is not the problem

Supabase apps ship an anon key in the browser, and that is by design. It is meant to be public. So seeing it in your front-end is not, on its own, a leak.

The real question is what that anon key is allowed to do. If your tables have no access rules, the anon key can read and write everything. That is the actual risk.

Turn on Row Level Security

Row Level Security, or RLS, is the rule system that decides who can see and change each row. Without it, anyone with your public anon key can query your whole database from their browser.

Enable RLS on every table, then add policies that only allow users to touch their own data. This is the single most important thing you can do for a Supabase app.

  • Enable RLS on every table that holds real data.
  • Write a policy so users can only read and write rows that belong to them.
  • Test it by trying to read another user's data with a normal account. You should get nothing back.

Never put the service_role key in the browser

Supabase has a second key called service_role. It bypasses every access rule. It is meant for trusted server code only.

If the service_role key ends up in your front-end, RLS no longer protects you, because that key ignores RLS entirely. Keep it in a server-side environment variable and nowhere else.

Lock down storage buckets

  • Set buckets that hold private files to private, not public.
  • Add storage policies so users can only access their own uploads.
  • Do not rely on hard-to-guess file names as security. They get found.

How to check your setup

A scan can confirm whether your anon key over-exposes data and whether your service_role key leaked to the browser, with read-only checks that prove the problem without changing anything.

Frequently asked questions

Do I really need RLS if my app has a login?

Yes. A login controls your UI, but the database is reachable directly with the public anon key. Without RLS, someone can skip your UI and query the data themselves.

What is the difference between the anon key and the service_role key?

The anon key is public and limited by your RLS policies. The service_role key is secret and ignores all policies. The first belongs in the browser, the second never does.

Check your own app

Run a free scan and see these issues for your site, in plain language with copy-paste fixes.

Scan your site for free

// related scanners