The 7 Security Checks Every AI-Built App Needs Before Launch
Shipping an app that an AI coding tool generated is not the same problem as shipping an app you typed line by line. The code usually runs. The gap is everything the generator assumed on your behalf: that you would turn on row-level security later, that the key it wired into the front end was the safe one, that someone would review the storage bucket before real files landed in it.
A launch decision needs evidence. Below are the seven checks that produce it, and the proof each one should leave behind.
1. Database access rules
The single highest-impact check. For every table your app can reach, confirm row-level security is enabled and that at least one policy actually constrains rows to the current user. RLS enabled with a using (true) policy is not protection — it is protection-shaped.
Evidence to keep: the list of tables, whether RLS is on, and the policy expression for each. A table with RLS on and zero policies is unreachable; a table with RLS off is world-readable through the public API.
2. Secrets and keys
Look for service-role keys, provider tokens and private API keys that ended up in client-side bundles, committed .env files, or git history. Third-party scans of AI-built apps keep finding admin keys in front-end JavaScript (one 29-app sample put it at roughly one in four). A key in a shipped bundle is public forever, so rotation — not deletion — is the fix.
Evidence to keep: the file and line of every match, plus the rotation timestamp.
3. Authentication and authorization
Confirm every private route is gated on the server, not only in the UI. Check that roles live in their own table rather than on a profile row a user can edit, that password recovery works end to end, and that email confirmation matches your intent.
Evidence to keep: an unauthenticated request to a protected endpoint, and the status code it returned.
4. Storage
Buckets default to whatever the generator chose. For each bucket: is it public, and does that match what it holds? Signed URLs for private files, path-scoped policies for user uploads, and a size/MIME limit so an upload field is not a free CDN.
5. HTTP security headers
The cheapest hardening you will ever do, and the most consistently missing. A content security policy, Strict-Transport-Security, X-Content-Type-Options, a referrer policy and a frame-ancestors rule. Headers do not fix a broken database, but their absence turns a small bug into a session-stealing one.
6. Dependencies
Resolve the lockfile against advisory data and look at what is actually reachable from your code. A critical advisory in a build-only dev dependency is not the same risk as one in your request path — and treating them identically trains you to ignore both.
7. Deployment configuration
Debug mode off, source maps not served publicly, environment variables scoped to the right environment, preview deployments not pointing at the production database, and webhook endpoints verifying signatures before they trust a payload.
The verdict is the point
Once all seven have fresh evidence, you get one of four honest answers:
| Verdict | Meaning |
|---|---|
| Ready | All seven fresh, no unresolved critical or high findings |
| Needs review | Evidence complete, only medium or low findings left to decide |
| Blocked | Evidence complete, at least one critical or high finding open |
| Insufficient evidence | A required check never ran, failed, or went stale |
The fourth row is the one most tools quietly skip. If a check has not run, the correct output is not a green badge and not a score — it is "we do not know yet." Everything else is a guess wearing a launch button.
Sentrail runs these seven checks against your real GitHub, Supabase and Vercel resources and records the evidence behind each verdict, so a launch decision can be re-checked instead of remembered.
