The Pre-Launch Security Checklist for Vibe-Coded Apps
A vibe coding security checklist for non-developers: the database, secrets, storage, auth, and header checks to run before you ship your AI-built app. Print and go.
You're close to launching. The app works, the demo looks great, and the only thing nagging you is the part nobody at the AI tool ever explained: is it actually safe to put in front of real users? You don't have a security background, and "do a security review" is not advice you can act on.
This is a security review you can act on. It's a pre-launch checklist for vibe-coded apps, grouped by the area where things actually go wrong, written for someone who didn't write the code by hand.
Work through it once before you ship. Each item tells you what to check and links to a deeper guide if you need it. Nothing here requires you to be a developer — most of it is opening a dashboard and looking.
⚡ TL;DR
- Most leaks in AI-built apps come from five areas: the database, secrets, storage, auth, and the front end. Check each before launch.
- Don't waste time rotating public keys (the Supabase anon key, a Firebase web config). They're meant to ship. Spend that time on the rules behind them.
- This checklist is the manual version of what an automated scan does. Run both.
How to check your own app
This is the do-it-now part: each section below targets one failure area, and the format is the same throughout — a checkbox, what to verify, and where to go deeper. If a box is already ticked, move on. If it isn't, fix it before you launch — none of these are "later" problems once real users and real data arrive.
If you only do one section, do the database. For the large majority of vibe-coded apps, that's where the worst leaks live.
1. Database & access rules
Your database is the crown jewels. If you built on Supabase (the default for most AI tools), the control that protects it is Row Level Security (RLS) — a per-user filter the database enforces on every query.
- Every table with user data has RLS enabled. Open your Supabase dashboard and confirm no table holding real data shows "RLS disabled." See Supabase RLS explained.
- Each policy actually restricts rows — no
USING (true). A table can have RLS on and still leak everything if the policy matches every row. Read the policy, not just the toggle. - You tested as a real anonymous user. Query your public API with just the public key. If you can pull other people's rows, so can anyone. Walk through it at Is my Supabase exposed?.
- No write access you didn't intend. Confirm a stranger can't insert, update, or delete rows in tables they shouldn't touch.
2. Secrets & API keys
Here's where most checklists go wrong by telling you to panic about keys that are supposed to be public. The skill is knowing which keys matter.
- No secret keys in your frontend code. The dangerous ones are server-side secrets: a Supabase
service_rolekey (it bypasses RLS entirely), an OpenAI or Anthropic key, a Stripesk_live_key. None of these belong in browser code, ever. See service_role vs anon key. - You did not rotate keys that are public by design. The Supabase anon key, the Firebase web config, and a Stripe
pk_live_publishable key are meant to ship in the browser. Rotating them wastes time and fixes nothing. See exposed secrets & API keys. - If a real secret did leak, you rotated it in the right order. Rotate, then audit usage, then add monitoring. The order matters. See rotate, audit, monitor.
🐺 Not a real problem
A scanner flagging your Supabase anon key or Firebase
apiKeyis crying wolf. Those are public by design. Tick the box, move on, and put your energy into the access rules behind them.
3. Storage buckets
Uploaded files — profile photos, ID documents, receipts, attachments — live in storage buckets with their own rules, separate from your database. This is the area founders forget, and it's exactly how the Tea app leaked tens of thousands of ID photos.
- No bucket with private files is public. Open your storage settings and confirm buckets holding user uploads require authentication. See Supabase storage bucket security.
- You tested a file URL in a private window. Copy the URL of a private upload and open it logged out. If the file loads, the bucket is open to the world.
- Especially sensitive uploads get extra scrutiny. If you collect ID documents or anything you'd be sued over, the bucket holding them is the single most important lock in your app.
4. Authentication & authorization
Authentication is who you are. Authorization is what you're allowed to do. AI tools are decent at the first and routinely skip the second.
- Every sensitive endpoint checks permission, not just login. A logged-in user shouldn't be able to read or change another user's data by editing an ID in a request. This gap is called IDOR (Insecure Direct Object Reference).
- No undocumented or unprotected endpoints. The Base44 breach happened because sign-up endpoints behind a public ID didn't verify the user. A public identifier in a URL is fine; an unauthenticated endpoint behind it is not.
- Paywalled and admin features are enforced on the server. If the only thing hiding a paid or admin feature is the UI not showing a button, anyone can reach it by calling the API directly.
5. Front end, headers & source maps
The browser-facing layer leaks more than people realize — sometimes it hands an attacker your entire source code.
- Source maps are not deployed to production. Source maps reconstruct your original code from the shipped bundle, including comments and structure that can reveal secrets and logic. Turn them off for production builds. See source map exposure.
- No secrets hard-coded in JavaScript. Anything in your bundle is readable. Attackers routinely extract keys from JS files in seconds.
- Basic security headers are set. Headers like Content-Security-Policy and protections against cross-site request forgery (CSRF — tricking a logged-in user's browser into making a request) are commonly missing entirely in AI-built apps. Confirm they exist.
6. Monitoring (the part that comes after launch)
A checklist gets you to launch. It doesn't keep you safe afterward, because your AI ships new code on every prompt.
- You'll know if a key is being abused. Set spend limits and alerts on paid APIs so a leaked key can't run up an unbounded bill before you notice.
- You re-check after big changes. Every new feature is a chance to reopen one of the gaps above. A check before launch is necessary but not sufficient.
Want this whole checklist run for you, automatically?
Run a free, read-only scan of your live app — no install, results in under a minute.
Scan my app free →Turning the checklist into a prompt
If you'd rather have your AI builder do the remediation, you can hand it a focused prompt. Be specific — vague requests get vague security. Something like:
Review this app for security before launch. Specifically:
- Enable RLS on every table with user data and add policies so each
user can only read and write their own rows. Do not use USING(true).
- Make sure no secret keys (service_role, OpenAI, Stripe sk_live) are
in any frontend/browser code.
- Confirm storage buckets with private files require authentication.
- Add server-side authorization checks on every endpoint that reads or
writes user data, so a user can't access another user's records by
changing an ID.
- Disable source maps in the production build and add basic security
headers (Content-Security-Policy, CSRF protection).
A prompt like this gets you much further than "make my app secure," because you've told it the specific gaps to close. But treat the output as a draft, not a guarantee — the only way to know a gap is closed is to test the deployed app.
FAQ
Do I really need to do all of this before launch?
The database, secrets, storage, and auth sections — yes, before real users and real data arrive. Those are the gaps that turn into breaches and lawsuits. Monitoring you can layer in right after. The one thing you can't safely skip is testing as an unauthenticated user; that's the check that catches the worst leaks.
I'm not a developer. Can I actually do this checklist?
Most of it, yes. The majority is opening a dashboard, reading a setting, and trying a URL in a private window. The parts that need code changes (adding policies, disabling source maps) are things you can hand back to your AI tool with the prompt above. You don't need to write the code; you need to know what to ask for and how to verify it.
Why shouldn't I rotate my exposed keys?
Because the keys that show up in your frontend are usually meant to be there. The Supabase anon key, the Firebase web config, and a Stripe pk_live_ key are all public by design. Rotating them is busywork that fixes nothing and can break your app. Spend that effort on the rules behind them and on the secret keys that should never have shipped.
The bottom line
A pre-launch security checklist for a vibe-coded app comes down to five areas — database, secrets, storage, auth, and the front end — plus monitoring for after you ship. Skip the false alarms about public keys; focus on the missing rules behind them. An attacker can walk this same list against your app in minutes. The point is to walk it first, and to keep walking it, because your AI ships new code (and new gaps) on every deploy.
Find your gaps before an attacker does.
Is My Site Hackable? scans your deployed app for the exact issues in this article — exposed keys, missing RLS, open buckets — and tells you what's real and what's a false alarm.
Run a free scan →