2026-10-26

Is your AI-built app safe to launch? Five things to check before real users arrive

The tools that build an app in a weekend are good at making it work and much less careful about who else can make it work. Here is what to check, and how to check it without reading every file.

An app built with Lovable, Bolt, Replit or Cursor usually works. That was never the hard part. The trouble is that "works" gets tested by the person who built it, logged in as themselves, clicking the buttons in the order they expect. Real users don't do that, and neither does someone poking at your app on purpose.

None of what follows needs you to read the whole codebase. Most of it takes an afternoon.

1. Look for secret keys in the browser

Open your live app, open the browser's developer tools, and search the loaded JavaScript for key, secret, sk_, rk_ and sb_secret_. Anything you find there, every visitor can find too.

Some keys are meant to be public. Supabase's anon or publishable key (sb_publishable_ on newer projects) and Stripe's publishable key (pk_) are designed to sit in the browser. Others are not. A Stripe secret or restricted key (sk_ or rk_), a Supabase service_role or sb_secret_ key, or an OpenAI or Anthropic API key in the browser means anyone can spend your money or read your whole database. If you find one, rotate it today, then move whatever uses it to the server.

A quick tell in the code: environment variables starting with NEXT_PUBLIC_ or VITE_ are bundled into the browser on purpose. A secret should never have one of those prefixes.

2. Check that the database refuses strangers

This is the one that bites AI-built apps most often. If your app talks to Supabase directly from the browser, the only thing between your data and the internet is Row Level Security. A table without it is readable, and often writable, by anyone holding the anon key, which is everyone.

In the Supabase dashboard, every table should show RLS as enabled, and each one should have policies that say who can read and write which rows. "Enabled with no policies" blocks everything, which is safe but usually means a feature is quietly broken. "Disabled" is the one to fix first.

The real test is to try it. Log in as a test user and ask for rows that belong to someone else. If you get them back, so will everyone.

3. Change the number in the URL

If a page lives at something like /invoices/1042, log in as one user and change it to /invoices/1041. If you see another customer's invoice, the app checks that you are logged in but not what you are allowed to see. That gap is common in generated code, because the happy path never exercises it.

The fix belongs on the server or in the database rules, not in hiding the link. A hidden button stops nobody who can type a URL.

4. Make sure payments can't be faked

Start with where the price comes from. The price comes from your server or from Stripe, never from something the browser sends. Whatever marks an order as paid is a Stripe webhook whose signature is verified, not a redirect to a "thank you" page that anyone can visit directly. And you have run one real payment end to end in live mode, refund included, before a customer does it for you.

5. Know what happens when you lose data

Ask two questions. Is there a backup? Has anyone ever restored from it? A backup nobody has restored is a hope rather than a backup. Most hosted databases offer point-in-time restore on paid plans, and it is worth knowing which plan you are on before the day you need it.

What this list doesn't cover

These five catch the problems that turn up most often in AI-built apps, not all of them. They won't tell you whether the app will hold up at a thousand users, whether the code can be changed without breaking something else, or whether it meets a regulation your industry cares about. And they are no substitute for a proper security test if you handle health, financial or children's data.

If you run through the list and something turns up that you don't know how to fix, that is exactly what a production review is for. You get a written list of what to fix first, and you keep it whether or not we do the work.