Docs · Supabase
Checking your Supabase app with Throttle Bird
Throttle Bird helps make sure your app or website is safe from hackers before you launch. If your app uses Supabase, it can check one of the things that matters most: whether a stranger can read your tables using the public key that ships in your app. This page explains how that check works, what it does, and what it never does.
Step 1
Run the free scan
Paste your app's public address into the free scan. Throttle Bird reads your public page and its JavaScript, the same files any visitor's browser downloads.
If it finds Supabase settings in that code, your report says so and lists the table names your app's code mentions (for example, a .from("profiles") call). Finding those names doesn't touch your database. At this point Throttle Bird has not sent a single request to Supabase.
Step 2
Prove you own the app
Throttle Bird only tests a database after its owner says yes. On your report, click Prove I own this app. You'll get a short code to add in one of two ways:
- a meta tag in your homepage's <head>, or
- a file at
/.well-known/throttlebird-verify.txtwhose only contents are the code.
The report gives you a ready-to-paste prompt for Lovable, Bolt, Cursor or Replit that adds it for you. Publish, then click the check button. Throttle Bird looks for the code on your live site again before every verified scan or table re-check you run from your report.
The same rule covers Roost re-scans. Before any database read, a re-scan checks that your code is still on your live site. If it's gone or has expired, the re-scan runs only the public checks, sends no request to your database, and the report tells you why and how to put the code back.
Step 3
Throttle Bird checks whether strangers can read your tables
Your app ships a public Supabase key (the anon or publishable key). That's normal, and it's meant to be public. What protects your data is row level security (RLS). If RLS is off for a table, or a policy lets anyone read it, that public key can read the rows.
After you've proved ownership, Throttle Bird uses that same public key, the one any visitor already has, to try reading each table named in your code. It tests up to 12 tables with one read each, and asks for at most one row. Each table gets one of three results:
- Blocked. Supabase refused the read. Strangers can't read this table.
- Strangers can read it. Rows came back. This is marked critical, along with roughly how many rows a stranger can read when Supabase reports a count.
- Nothing visible right now. The read came back empty. That means RLS is blocking it or the table is empty today, and from the outside we can't tell which. The report says exactly that instead of guessing.
Throttle Bird only tests tables your public code names. It never guesses table names, and tables that only your server code uses won't show up.
Step 4
Read the result and fix it
Every finding is explained in plain words, with a fix you can copy. For a readable table, the fix is to turn on RLS for it and add policies so people can only see their own rows. Supabase's own guide covers this step by step: Row Level Security in the Supabase docs.
The free report shows every table a stranger can read and how to fix it. The $9 Full Report adds fix prompts written for your builder and a one-click re-check of a single table after you've fixed it.
What Throttle Bird never does
- No writes. Every request the scanner makes is a read. It never adds, changes or deletes a row, and never submits a form.
- No database requests until you prove ownership. An unverified scan only reads your public page and its code. Roost re-scans check for your code on your live site again before every database read.
- No secret keys. It only uses the public key already in your app. If the only Supabase key it finds is a service_role key, it skips the table test and flags the key as a problem, because that key bypasses RLS.
- Nothing stored beyond the report. To list column names it reads at most one row per table, and keeps only the column names and an approximate row count, never the values. Your report expires after 7 days. The only other thing saved is the verification code for your domain, for 30 days, so you don't have to add it again.
The fine print
This check looks at your app from the outside, the way a stranger would. It can tell you whether the public key can read a table. It can't see your RLS policies directly, and no scan can promise an app is perfectly safe. If the database check can't finish (Supabase is slow to answer, or the scan runs out of time), your report says it was skipped instead of leaving it out. If you change your database, run a fresh scan.