Supabase security checklist
Supabase is the most common backend for AI-built apps, and a handful of its defaults are the difference between a private database and a public one. Four things account for almost every Supabase incident: tables without Row Level Security, the service_role key reaching the browser, public Storage buckets, and open signups with email confirmation turned off. ShipReady checks all four on a live site — here is what each means and how to fix it.
This is a focused slice of the full production readiness checklist.
01Enable Row Level Security on every table
criticalSupabase hands your browser a public anon key — it is meant to be public and ships inside your JavaScript. The only thing between that key and your data is Row Level Security (RLS): per-table policies deciding who may read or write each row. New tables have RLS disabled by default, and AI-generated Supabase code very often skips it. Without RLS a table answers unauthenticated reads from anyone who finds the anon key — which takes no skill, it is in your page source — and every row can be downloaded in bulk. Enable RLS on every table and write explicit policies. ShipReady flags tables that still answer anonymous reads with the anon key.
02Keep the service_role key server-side only
criticalSupabase also issues a service_role key that bypasses RLS entirely — it is the database superuser, meant only for trusted server code. If it ever reaches the browser (inlined into client JavaScript, exposed through a NEXT_PUBLIC_ variable, or committed in a deployed file), anyone can read, modify, and delete every row in every table regardless of the policies you wrote. Keep it out of anything the client can download. If it has been exposed, rotate it immediately and treat the data as compromised. ShipReady flags a service_role key found in client-reachable code.
03Require email confirmation for public signups
highIf public signups are on and email confirmation is off, a Supabase account is active the instant it is created — no link clicked, no proof the address belongs to the person registering. Someone can sign up using a colleague’s or customer’s email and act as them. Turn on email confirmation whenever signups are open to the public. ShipReady flags projects where signups are enabled but confirmation is disabled.
04Confirm Storage buckets are public on purpose
mediumSupabase Storage buckets can be public or private. A public bucket lets anyone list and download every file it holds without signing in. Public buckets are a legitimate feature — the real question is whether you meant this one to be public, and whether anything user-uploaded ended up in it. ShipReady flags buckets that allow anonymous listing so you can confirm the choice was deliberate.
Check your Supabase app in about a minute
ShipReady scans your live site for these Supabase issues and every other production readiness check, with a paste-ready fix for each. Free, no signup.