What's in this guide
Why AI-built apps ship insecure The 13-point checklist Why a one-time scan isn't enough Enforce it at runtime — and prove it FAQWhy AI-built apps ship insecure by default
An AI coding agent optimizes for one thing: making the feature work. Ask it to "add login" and it will produce something that logs in. It will not, unasked, threat-model the auth flow, rotate secrets out of the repo, add rate limiting, or lock down the database — because none of that is what you asked for, and none of it shows up when you click around the happy path.
That's the trap. The app looks done. It demos perfectly. And the holes — a Supabase key sitting in client-side JavaScript, an authorization check that runs in the browser, an admin route with no guard — are invisible until someone who isn't you goes looking. By then it's a headline, not a checklist item.
AI ships your features. It does not ship your security. Every control below is something you have to add on purpose — the model won't volunteer it.
The 13-point vibe coding security checklist
Run this before anything AI helped you build touches real users:
- No secrets in the repo or the client bundle. Grep for API keys, tokens, and connection strings in your source and your shipped JS. AI loves to hardcode them. Move everything to server-side environment variables.
- Authorization is enforced on the server, not the browser. The single most common AI mistake: hiding a button or gating a route in client code. Anyone with dev tools bypasses it. Every protected action must be checked server-side, per request.
- Row-level / object-level access control on your data. "User A can only see User A's rows" must be enforced by the database or the API, not assumed. Backwards or missing access control has exposed tens of thousands of users in real vibe-coded apps.
- Rate limiting on every public endpoint. Without it, one script maxes out your API, your bill, or your login form. AI rarely adds it.
- No debug, seed, or admin endpoints left exposed. Scaffolding the AI generated to "test" something often ships to prod wide open. Remove or guard them.
- Input is validated and parameterized. Confirm queries are parameterized (no string-built SQL) and user input is validated server-side — injection is still the classic.
- Auth tokens are short-lived and stored safely. Check token lifetime, refresh handling, and that nothing sensitive sits in
localStoragewhere any script can read it. - The database is not publicly reachable. Confirm it's firewalled to your app, not the internet, and that default credentials are gone.
- Dependencies are pinned and scanned. AI pulls in packages freely. Lock versions and run a vulnerability scan.
- Error responses don't leak internals. No stack traces, env values, or SQL in what the user sees.
- Money paths are server-verified. Paywalls, entitlements, and prices must be checked server-side. Client-only paywalls get bypassed and your keys get drained.
- You can see what's actually running. Runtime logs and request traces, in one place — so you find a problem before a user does.
- Every production change is logged and reversible. A tamper-evident record of what shipped, who approved it, and a rollback path — so a bad change is an "undo," not an incident.
Why a one-time scan isn't enough
Most "vibe coding security" advice ends at "run a scanner." Scanners are useful — but a scan is a snapshot of one moment. The whole premise of vibe coding is that you keep shipping AI-generated changes, fast. The change you make tomorrow can reintroduce the exact hole the scan cleared today, and nobody re-runs the scan before every deploy.
Security that survives vibe coding isn't a one-time audit. It's enforced at runtime — the rules apply to what's actually running, every deploy, automatically — and it's provable, so when something looks wrong you can see exactly what changed and roll it back.
Enforce it at runtime — and prove it
This is the layer a code scanner and a coding assistant can't give you, because it isn't about the code — it's about the live system:
- Security policy enforced on the running app, not just recommended in a report — rate limits, blocked traffic, and access rules applied to real requests.
- Every change gated by your approval, so an AI-generated deploy can't quietly ship a regression to production.
- Runtime logs and request traces in one place, so you catch the breach attempt or the broken auth check as it happens.
- A tamper-evident audit trail + one-click rollback, so "the AI wrote half of it" stops being a liability you can't account for.
Infraveil is that runtime layer.
It's a control plane you run on your own servers: it enforces your security policy on live traffic, gates every deploy behind your approval, puts runtime logs and request traces in one place, and keeps a tamper-evident audit trail of everything that shipped. The hole a scan would catch once, Infraveil keeps closed — and proves it.
See the live demo →Frequently asked questions
Is vibe coding secure enough for production?
Not by default — AI optimizes for "it works," not "it's safe." It can be production-ready after you explicitly add and enforce the controls the AI skipped: server-side authorization, no exposed secrets, rate limiting, locked-down data, and an audit trail.
What are the most common security mistakes in AI-built apps?
Hardcoded/exposed secrets, missing or backwards authorization, access control enforced only in the browser, no rate limiting, leftover debug/admin endpoints, and no audit trail — because the model ships the happy path and skips the controls nobody asked for.
Is a one-time security scan enough?
No. A scan is a snapshot; the next AI change can reopen the hole. Lasting security comes from enforcing the rules at runtime and keeping a tamper-evident record of what actually ran.
Ship fast without shipping the breach.
One control plane on your own servers — deploy, supervise, enforce security, recover, and prove what happened, with every change gated by your approval. Keep the speed of AI; lose the 72-hour breach.
Enter the live demo →