Holdfast

Guides

Check your Supabase app's security in 15 minutes

Your AI tool says permissions are fixed. Here's how to prove it.

By Robert Udah, principal engineer. 20 October 2026. 7 minute read.

Lovable, Bolt and most AI app builders put your data in Supabase. That's a good choice, with one catch that surprises a lot of founders: the key your app uses to talk to the database (the anon or publishable key) is public by design. It ships to every visitor's browser. Anyone can copy it.

That's fine, as long as the database itself decides who can see what. In Supabase that job belongs to row level security (RLS): rules on each table that say, for example, "a user can only read their own orders". If RLS is off, or the rules are too loose, your public key opens the whole table.

AI tools are good at saying they've "fixed permissions". They're less good at proving it. Here's how to check for yourself, in about 15 minutes. Only test your own app, with your own keys.

Your anon key is public. Row level security is the only lock on the door.

1. Is RLS switched on for every table?

Open the SQL editor in your Supabase dashboard and run:

select tablename, rowsecurity
from pg_tables
where schemaname = 'public';

Every row should say true. Any false means that table can be read, and possibly changed, by anyone who has your public key.

2. Do the rules actually restrict anything?

RLS can be on and still let everyone in. List the rules:

select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public';

Look at the qual and with_check columns. Warning signs:

  • The rule is just true: everyone allowed.
  • It applies to anon or public on a table holding customer data.
  • It never mentions auth.uid(), so it doesn't tie rows to the logged-in user.

A table with RLS on and no rules at all blocks everything for normal users. That's safe, but it's often why an AI tool "fixes" a broken screen by adding a rule that lets everyone in.

3. Try it logged out, like a stranger would

Find your project URL and anon (or publishable) key in Settings, API. Then, from a terminal:

curl "https://YOUR-PROJECT.supabase.co/rest/v1/YOUR_TABLE?select=*" \
  -H "apikey: YOUR_ANON_KEY"

If that returns rows a stranger shouldn't see, the fix didn't work, whatever the AI said. Try each table that holds anything personal: users, profiles, orders, messages, bookings.

4. Try it as the wrong customer

This is the one AI fixes miss most. Create two test accounts, A and B. Log in as A, then try to read or change B's data: change an ID in the address bar, or in a request your browser's developer tools show the app making. If A can see or edit anything of B's, the rules check that someone is logged in, but not who.

5. Is the master key hiding in your frontend?

Supabase also gives you a service_role (or secret) key, which ignores every RLS rule. It must never reach the browser. Search your code and your built site for service_role and for your secret key's first few characters. If you find it anywhere a visitor could load, treat it as leaked: rotate it in the dashboard today.

6. Check the places RLS doesn't cover by default

  • Storage buckets. Run select id, public from storage.buckets;. A public bucket means anyone with a file's address can open it. Fine for logos, not for invoices or ID documents.
  • Views. A view can quietly bypass the RLS on the tables underneath it. If your app reads from views, make sure they're created with security_invoker = true.

If a check fails

For a table where each row belongs to one user, switching RLS on and adding an owner-only rule looks like this:

alter table public.orders enable row level security;

create policy "Owners read their own orders"
on public.orders for select
to authenticated
using ((select auth.uid()) = user_id);

You'll need similar rules for insert, update and delete, and then test again with steps 3 and 4. Changing rules on a live app can break screens that relied on the loose version, so try it on a copy or a quiet hour first.

Make it a habit

Re-run these checks after every big AI-assisted change. AI tools fix one screen at a time and can quietly undo an earlier fix to make a new feature work. Fifteen minutes now is a lot cheaper than a customer emailing to say they can see someone else's data.

Robert Udah is principal engineer at Holdfast, which runs fixed-fee audits for founders of AI-built apps and buyers of small software businesses. These checks are part of every audit, along with payments, backups, hosting and account ownership. Audits for AI-built apps or read a sample report.

Rather someone checked it properly?

A fixed-fee audit covers this, payments, backups and hosting, and fixes the worst of it.

Or email [email protected]

Book a call