VibeCheck

Is row level security on for my Supabase tables?

Row level security is on only when every table the client can reach has RLS enabled and a policy that limits rows to the people who should see them; the anon key still ships in the browser.

Does the anon key count as a secret?

No. The anon key is meant to be in the client, and it can read any table that grants the anon role or leaves row level security off.

Treat the key as public and lock the tables.

How do I check a table before launch?

Request the table with the anon key and confirm you cannot select rows you would not paste into a public chat.

Enable row level security, add a policy, and repeat that request before you ship.

What policy should a user-owned table use?

Give the authenticated role a policy that compares the row owner to auth.uid(), and do not add a policy that lets anon select every row.

Repeat that for every table in the public schema the client can touch.

alter table public.users enable row level security;

create policy "read own row"
on public.users
for select
to authenticated
using (auth.uid() = id);

What about storage buckets?

A storage bucket that allows public listing shows every object to anyone who knows the project URL.

Require a signed-in user, and scope the path to that user, before you mark the bucket public.

What should I do if the table was already readable?

Assume the rows were copied, rotate any secrets that were in those rows, and turn on row level security before the next deploy.

Changing the policy later does not pull data back from someone who already downloaded it.

How does VibeCheck report an open table?

On an origin you own, VibeCheck tries the public client key that the bundle already contains and reports a table that returns rows without a signed-in user.

The paid report includes the location, a short redacted response, and a copy-paste fix. The free teaser can show that the issue exists without that evidence.

Scan an app you own