Guide2 July 2026

Why Your Supabase Database Might Be Publicly Readable (And How to Check in 30 Seconds)

Why Your Supabase Database Might Be Publicly Readable (And How to Check in 30 Seconds)

Why Your Supabase Database Might Be Publicly Readable (And How to Check in 30 Seconds)

If you built your app with Supabase in the last year, there's a good chance one setting stands between your users' data and anyone with a browser. It's called Row Level Security, and in a new Supabase project, it's off by default.

This isn't a theoretical risk. It's the single most common security failure we see across apps built with AI tools like Lovable, Bolt, and Base44. The pattern is always the same: someone ships fast, the app works, the demo looks great, and nobody ever goes back to lock down the database because nothing in the build process forced the question.

What's actually going wrong

Supabase gives every project a public "anon" API key. It's meant to be public - it ships in your client-side JavaScript by design, so your frontend can talk to your database directly without a custom backend. That's the whole appeal of Supabase: less backend code to write.

The safety net is Row Level Security (RLS). RLS is a set of rules you define per table that say who can read or write which rows. Without it, the anon key has no rules to check against, which means it can read and often write to every row in every table it has been granted access to.

Put simply: the same public key that makes Supabase easy to build with is the same key that exposes your data if RLS was never switched on.

What this looks like from the outside

An attacker doesn't need to guess anything. Your anon key is sitting in your browser's network tab or your JavaScript bundle right now, because it has to be there for your app to function. From there, a request like this is all it takes:

GET https://yourproject.supabase.co/rest/v1/users?select=*
Authorization: Bearer <your public anon key>

If RLS isn't enforced on the users table, that request returns every row. Names, emails, sometimes password hashes, billing details, or anything else you stored. No exploit, no brute force, just a plain HTTP request against your own public API using your own public key.

How to check your own app

You don't need to be technical to check this. Two options:

Manual check: Open your app in a browser, open DevTools → Network tab, and reload the page. Look for requests to *.supabase.co/rest/v1/. Copy one of those URLs and the apikey header value, then try the request again from a fresh browser or a tool like Postman without being logged in. If you get data back, RLS isn't protecting that table.

Automated check: This is exactly what Decloak's free scan does automatically. Paste your URL in, and it fingerprints Supabase, tests whether your tables are readable via the anon key, and flags it immediately if they are; no account, no setup, results in under 15 seconds.

How to fix it

  1. Go to your Supabase dashboard → Authentication → Policies (or Table Editor → RLS).
  2. Enable RLS on every table that holds anything you wouldn't want public. Note: enabling RLS with zero policies blocks all access by default, which is safe but will break your app until you add policies.
  3. Add policies that match how your app actually uses the table, for example, "a user can select their own row where user_id = auth.uid()."
  4. Re-test with the same manual check above, or re-run a Decloak scan, to confirm the table now returns nothing without proper authentication.

The other Supabase mistake we see constantly

RLS gets most of the attention, but there's a second, more serious variant: the service_role key ending up in client-side JavaScript instead of staying server-side only. The service_role key bypasses RLS entirely, by design, so it should never leave your backend. If it's in a bundle your browser downloads, RLS doesn't matter anymore, whoever has that key has full database access regardless of your policies.

If you shipped fast and skipped the security review, it's worth five minutes to check. It's the difference between "AI helped me build a real product" and "AI helped me build a public database."


Decloak checks for exposed Supabase anon keys, missing RLS, and leaked service_role keys automatically, alongside seven other attack surfaces, in a free 15-second scan. Scan your app free →