Why this happens with AI builders
Supabase and similar backends ship an anonymous key that is meant to live in your front end. It is public by design. The safety does not come from hiding that key. It comes from Row Level Security, a rule on every table that decides which rows an anonymous request is allowed to read.
AI builders scaffold tables fast, and Row Level Security is easy to leave off or leave too open. When that happens, the key that is supposed to be public becomes a door into a table that should have been locked, and nothing in the running app looks wrong.
What exposure actually looks like
Exposure means an anonymous request to your project returns rows it should not. Someone who views the source of your page, takes the public key, and queries a table can read customer names, emails, orders, or messages, with no account and no hacking.
It is quiet because your own app only asks for the rows it needs, so it looks fine. The exposure is in what else the same open table will answer when a stranger asks directly.
Check your own app, free
Smoke Run runs a free self-check for this. You enter your own app address, and it reads your public page and asks your project which tables answer a request with no login. It reports the result in plain words.
The check is read-only and polite by design. It never reads row contents, it never uses any key it finds, and it stores nothing. Only run it on apps you own.
What to do if a table is open
If the check finds an open table, the fix lives in Supabase. Turn on Row Level Security for that table, then add a policy that matches who should actually be allowed to read it, which for most app data is only the signed-in owner of the row.
Then run the check again to confirm the table no longer answers an anonymous request. Exposure is one of several silent failures. A checkout that breaks without an error is another, and Smoke Run watches that money path too.