For apps on Supabase · Lovable · Bolt · vibe coded

Forty paying customers. One table without row-level security, and any of them can read the other thirty-nine.One table without row-level security. Any customer can read every other.

You built something people pay for. If one table in your Supabase project has row-level security off, it answers anyone who holds the public key, and that key is in every browser that loads your app. Signed in or not.

  1. 1 · How it happens

    The table you added last week.

    Supabase lets the browser talk to the database directly, with a public key that ships in every copy of your app. The only thing that keeps one customer's rows away from another is row-level security, set table by table. Tables from a template or the dashboard's table editor usually get it. A table created later through SQL, a migration or a prompt can arrive with it off, and nothing in the app looks any different.

  2. 2 · What it costs

    The day someone notices.

    It is rarely a hacker. It is a customer who changes an id in a request, or a script that walks public Supabase endpoints looking for tables that answer. From that day you are writing to every customer to say their data may have been read, and in the EU a personal-data breach generally has to be reported to the regulator within 72 hours. If nothing recorded which rows went out, “may have been read” means all of them, since launch.

  3. 3 · Why you haven't seen it

    Your app only ever asks for your rows.

    Every screen you built filters by the signed-in user, so every test you click through shows exactly your own data, and it looks right. The leak is not on any screen of your app. It is the one request your app never makes: the same table, without the filter, from someone else's browser. Unless you go looking for it, table by table, nothing you click in your own app will show it to you.

What the free check shows you

Findings like these, for every gap in your app: how serious it is, what is wrong, where it is, and what it costs you if it stays.

prodready · free checkexample · not your app
criticalSecurity Posture

3 tables carrying an owner or tenant column have no row-level security in any migration in this repository: orders, customers, messages. The other 7 tables have policies.

For those three, isolation rests entirely on every query remembering to narrow by owner, so the single query that forgets returns every customer's rows to whoever asked. Unless it was switched on in the dashboard, the public key every browser receives reads all three through the REST API, signed in or not.

Evidencesupabase/migrations/20260514093000_orders.sql:4

highTesting

No test in the suite asserts that a caller from one tenant reading orders with another tenant's identifier gets nothing back; 12 tests were searched.

Isolation is a property nobody has ever checked, so the first proof that it holds or fails arrives as a customer looking at data that belongs to someone else.

Evidencesrc/__tests__/

Your report names your own tables, files and lines, with a score for the whole app.

See a full sample report →

Run the free check tonight.

No coding tool? Check what your live app hands every visitor → From its address, on your phone, nothing to install. It checks keys and headers, not your tables: those are read from your code, below.

The full check runs in your coding tool, on your machine, in a few minutes. What reaches us: counts, rule names and file paths with line numbers. Never your source, your data or a secret value. Your report page is kept 7 days behind an access code. Exactly what it runs →

On your laptop · freeabout two minutes

Add it, sign in, ask.

claude mcp add --transport http prodready https://mcp.prodready.si/mcp --scope user
  1. Add it. Run it in a terminal.
  2. Sign in. In Claude Code type /mcp, pick prodready, choose Authenticate. A browser page asks for your email; type the 6-digit code we send (or click its link), then approve. No password, no card.
  3. Ask. Type “check my app”.
On your phone?no coding tool here

Send it to your laptop.

The check runs in the coding tool on your computer. We email you the one line to paste, and nothing else unless you ask.

See a full sample report →

After the report: when you want the gaps closed the way serious software teams close them, the same prodready connection runs the SDLC on your project. How that works →