Guide

Vibe-Coded App Security Checklist: What to Check Before Launch

What to check before an AI-built app takes real users and data: access rules, Supabase RLS, secrets, webhooks, backups and monitoring, each with a safe test.

Cover: a shield above a launch checklist: server-side authorization, row-level security, no secrets in the browser, verified webhooks, a tested restore and error alerts.

The short answer

Before an AI-built app takes real users, real data or real money, check that every request is authorized on the server for the specific record it touches; that database access rules (row-level security, if you use Supabase) are on for every exposed table; that no secret key reaches the browser; that payment webhooks are verified and processed once; and that you can restore a backup. Those five cover the failures that cost the most. The full checklist below has eighteen items. For each one it says what to check, why it matters, how to verify it safely, the warning sign to look for and the official documentation behind it.

Nothing here assumes your app is insecure because an AI tool wrote it. Many generated apps get several of these right. The aim is to know which ones, before a customer or a stranger finds out for you.

Prototype, test environment or production: which one do you have?

Most of the risk sits in the gap between three different things that can all look like “the app works”. A prototype that appears to work does what it should for the person who built it, on sample data. A working test environment has its own database, test keys and several test accounts, so you can try things without touching anything real. A production system holds real people's data and money, and has to keep working when someone uses it in a way nobody planned. This checklist is written for the step from the second to the third. If you only have the first, set up the second before you work through it.

Prototype, test environment and production comparedThree columns from left to right. A prototype that appears to work runs for its builder with sample data, builder-supplied keys and rules in the interface. A working test environment has its own database and test keys, several test accounts, payments in test mode and migrations from files. A production system has real users, data and money, with access enforced on the server and in the database, secrets kept server-side, backups with a tested restore and errors reported to someone who acts on them.Prototypeappears to workWorks for the personwho built itSample data or noneKeys and settings leftfrom the builderRules mostly enforcedin the interfaceTest environmentworks, safelyIts own database andtest API keysSeveral test accountswith different rolesPayments in test modeSchema changes appliedfrom migration filesProductionreal users, data, moneyAccess enforced on theserver and in the databaseSecrets kept server-side;live keys only hereBackups with atested restoreErrors reported tosomeone who acts on themEach step raises the cost of a mistake: who can reach the app, what data it holds, and whose money moves.
What is typically true at each stage. The same app can look identical in all three; what differs is who can reach it, what data it holds and what a mistake costs.
  • Prototype that appears to work: it works for the person who built it, with sample data or none, keys and settings left from the builder, and rules mostly enforced in the interface.
  • Working test environment: its own database and test API keys, several test accounts with different roles, payments in test mode, and schema changes applied from migration files.
  • Production system with real users, data and money: access enforced on the server and in the database, secrets kept server-side with live keys only here, backups with a tested restore, and errors reported to someone who acts on them.

What the AI tools say about their own checks

The platforms are clear that their checks are a starting point. Lovable's documentation describes a Quick scan that runs automatically every time you publish and looks, among other things, for tables without row-level security. The same page says these tools do not replace a thorough security review and that you are responsible for ensuring that your app meets the security requirements appropriate for its use case. Replit publishes its own security checklist for vibe-coded apps, covering secrets, authorization, rate limiting and dependencies. Supabase puts it the same way for the database: running it is a shared responsibility between you and Supabase, and access management, data and security controls stay with you.

For context only: a 2026 preprint by Deng, Fan and Meng (arXiv:2606.23130, not peer reviewed as far as the arXiv page shows) audited 200 publicly deployed applications built with Claude Code and Lovable and reported that 91.0% of audited applications contain at least one vulnerability, concentrated in broken access control, injection and authentication failures. That is one research team's sample of 200 apps. It does not establish a rate for AI-built apps in general and says nothing about yours, which is why the rest of this guide is about checking.

How to use this checklist safely

  • Run every check on an app you own, in your test environment, with test accounts and test-mode payment keys.
  • None of the self-checks needs a security tool. Two test accounts, the browser's developer tools (the Network tab) and your providers' dashboards are enough.
  • Do not load-test or probe production yourself. If a check suggests real data is exposed in production, treat it as an incident: close the gap, rotate any exposed keys and have an engineer check the logs for access.
  • The references are to official documentation. OWASP's Application Security Verification Standard is the long-form version of most of these items if you want the full requirement list.

Who can get in, and what they can see

1. Authentication

What to check
Sign-up, login, password reset and logout use the platform's auth service or an established library, not hand-written code. Logging out ends the session. Your own admin accounts on the hosting, database and code platforms use multi-factor authentication.
Why it matters
OWASP's Top 10 lists missing or ineffective multi-factor authentication and sessions that are not invalidated during logout or a period of inactivity among authentication failures. Replit's checklist says that if you build custom auth, use established libraries.
How to verify safely
Log in, copy the URL of a private page, log out and paste it back: you should land on the login page. Request a password reset for an address that has an account and for one that does not; OWASP recommends using the same messages for all outcomes. Supabase's production checklist asks you to protect your Supabase Account with multi-factor authentication (MFA); do the same for GitHub and your host.
Warning sign
Passwords checked in front-end code, an “admin” flag stored where the browser can change it, or different reset messages that reveal who has an account.
Reference
OWASP Top 10:2025 A07 Authentication Failures; Replit security checklist.

2. Authorization on the server, per record

What to check
Every request that reads or changes a record checks, on the server, that this user may do this to this record. Hiding a button or a menu item is not a check.
Why it matters
OWASP: access control is only effective when implemented in trusted server-side code or serverless APIs. Its first listed failure pattern includes viewing or editing someone else's account by providing its unique identifier. In Next.js, a Server Action is reachable via a direct POST request, not just through your application's UI, and the docs say to verify authentication and authorization inside each one.
How to verify safely
Create two test accounts, A and B. As A, create a record and note its ID in the address bar or the Network tab. Log in as B and open the same URL. You should get “not found” or “access denied”. Repeat for edit pages and downloads.
Warning sign
B can open A's record, or an API response in the Network tab contains other users' records that the interface filters out before display.
Reference
OWASP Top 10:2025 A01 Broken Access Control; OWASP API Security API1:2023; Next.js data security guide.

3. Supabase row-level security and the secret key

What to check
If the app uses Supabase: row-level security (RLS) is enabled on every table in an exposed schema, each table has policies that match what each role may do, and the secret key (or the older service_role key) is only ever used on a server.
Why it matters
Supabase: a table in an exposed schema without RLS is readable and writable by any role with a grant on it. The publishable key is meant for the browser: anyone can read it, so it only reaches what Row Level Security allows. A secret key bypasses every Row Level Security policy you have; Supabase says never to put one in a browser, a shipped application or source control. In PostgreSQL itself, RLS with no policy is a default-deny policy, so a table that suddenly returns nothing usually means RLS is on and a policy is missing.
How to verify safely
In the Supabase dashboard, run the Security Advisor and check the RLS status of each table. In the browser, open the developer tools on your deployed app and search the loaded scripts for sb_secret_ and service_role; neither should appear. Then repeat the two-account test from item 2.
Warning sign
A policy to anon using (true) on a table that holds private data. A view over a protected table: Supabase notes that views bypass RLS by default. A secret key in any file the browser downloads.
Reference
Supabase: Row Level Security, API keys, production checklist.

4. Tenant isolation

What to check
If the app serves several companies or teams (tenants), every query, file path, cache key and search index is scoped to the tenant, and the tenant comes from the signed-in user's verified membership, not from a value the browser sends.
Why it matters
OWASP's multi-tenant cheat sheet: a single vulnerability can expose all tenants' data. It advises to treat client-supplied tenant identifiers as selectors only and to verify that the user is authorized to act in that tenant.
How to verify safely
Create two test tenants with one user each and repeat the record-swap test across them, including file downloads, exports, search results and emails sent by the system. Thorough isolation tests are engineering work: OWASP asks to test isolation through the same role, connection path, and pooling mode used by the application.
Warning sign
A tenant ID in a header, body or URL that the server trusts; admin screens that can reach every tenant without a record of who looked. For a full treatment, see building a multi-tenant SaaS platform.
Reference
OWASP Multi-Tenant Application Security Cheat Sheet.

5. API access control

What to check
There is a list of every API route, Server Action, edge function and database function the app exposes, each marked public or protected, and each protected one checks the caller itself.
Why it matters
OWASP: permission should be validated correctly on every request, whatever started the request. Next.js warns that a page-level authentication check does not extend to the Server Actions defined within it. Replit's checklist says to add authentication to sensitive endpoints.
How to verify safely
While logged in, note the API calls the app makes in the Network tab. Open a private browser window (logged out) and request one of those URLs that only reads data. Expect a 401 or 403 response, not data. Leave anything that writes or deletes to an engineer in the test environment.
Warning sign
Nobody can produce the list of routes, or an admin route answers a logged-out request.
Reference
OWASP Authorization Cheat Sheet; Next.js data security.

Secrets, input and limits

6. Secrets and environment variables

What to check
No secret is in the source code, the repository history or the browser bundle. Variables with a client-exposed prefix hold only values you would publish. Test and production use different keys. Any key that was ever exposed has been rotated.
Why it matters
Next.js copies any variable prefixed NEXT_PUBLIC_ into the js bundle that is delivered to the client. Vite: VITE_* variables should not contain sensitive information such as API keys. On Vercel, environment variable changes only apply to new deployments, so a rotated key needs a redeploy. GitHub's advice for a leaked secret is to rotate the affected credential immediately.
How to verify safely
List every variable in the hosting dashboard and in .env.example. For each one with a NEXT_PUBLIC_ or VITE_ prefix, ask: would I put this on a public web page? If the repository is on GitHub, turn on secret scanning.
Warning sign
A payment, email or AI provider secret with a public prefix; a committed .env file; the same key in test and production.
Reference
Next.js environment variables; Vite env variables; Vercel environment variables; OWASP Secrets Management Cheat Sheet.

7. Input validation

What to check
The server checks the type, length, format and allowed values of every input, including uploaded files, whatever the form already checks.
Why it matters
OWASP: validate on the server even when the browser checks the same fields; browser checks are for quick feedback. The API Security Top 10 asks for a maximum size on all incoming parameters and payloads.
How to verify safely
In the test environment, paste a very long block of text into a form field and upload a file of a type the app should not accept. Expect a clear rejection, not a crash, a stack trace or the value saved as-is. Ask an engineer where the server-side validation for each endpoint lives.
Warning sign
Validation only inside form components, or database queries built by joining user input into a string.
Reference
OWASP Input Validation Cheat Sheet; API4:2023 Unrestricted Resource Consumption.

8. Rate limiting and spending limits

What to check
Login, sign-up, password reset and every feature that costs money per call (AI model calls, SMS, email) are limited per user or per client. Each paid provider has a spending cap or a billing alert.
Why it matters
OWASP asks you to implement a limit on how often a client can interact with the API within a defined timeframe and to configure spending limits for all service providers/API integrations. For logins it says to limit or increasingly delay failed login attempts without locking real users out.
How to verify safely
Open the billing settings of each paid provider and confirm a limit or alert is set. Ask where rate limits are configured and what a user sees when one is hit. Do not try to trigger them against production.
Warning sign
An AI feature that calls a paid model on every request with no per-user cap and no billing alert.
Reference
OWASP API4:2023; A07:2025; Replit security checklist.

Payments, events and background work

9. Payment and webhook signature verification

What to check
Every webhook endpoint (payments, auth, third-party events) verifies the sender's signature on the raw request body before it does anything.
Why it matters
Stripe: without verification, an attacker could send fake webhook events to your endpoint to trigger actions like fulfilling orders, granting account access or modifying records. Verification needs the untouched body: Stripe requires the raw body of the request to perform signature verification.
How to verify safely
Find the webhook handler and ask to be shown the line that verifies the signature with the signing secret. In the provider dashboard (in test mode), look at recent deliveries and their responses. Sending a deliberately unsigned request belongs in the test environment, done by an engineer.
Warning sign
The handler parses the JSON first and never verifies; or paid access is granted when the browser reaches a “success” page, not when a verified payment event arrives. Our guide to reliable webhook integrations covers the full receive path.
Reference
Stripe: verify events are sent from Stripe, receive events in your webhook endpoint.

10. Duplicate webhook delivery and idempotency

What to check
Processing the same event twice has the same effect as processing it once: one order, one email, one credit. Event IDs are recorded and repeats skipped. Nothing assumes events arrive in order.
Why it matters
Stripe: webhook endpoints might occasionally receive the same event more than once, and it recommends logging processed event IDs and skipping them. Stripe also doesn't guarantee the delivery of events in the order that they're generated, and in live mode retries delivery for up to three days with an exponential backoff.
How to verify safely
Ask an engineer to deliver the same test event twice in the test environment and confirm one order, one email and one credit. During your own testing, note any duplicate emails or double charges.
Warning sign
Duplicate emails or credits in testing; a handler that expects “created” to arrive before “updated”.
Reference
Stripe webhooks: handle duplicate events, event ordering.

11. Background jobs

What to check
Work that runs outside a web request (emails, imports, AI processing, scheduled tasks) has a retry limit, is safe to run twice, re-checks which user or tenant it acts for, and leaves a visible record when it fails.
Why it matters
OWASP: a shared queue or topic is not itself a tenant-isolation boundary; a job must not trust an unverified tenant field in its message. Jobs that retry also run twice, so the idempotency rule from item 10 applies to them too.
How to verify safely
Ask where jobs run, what happens when one fails and where you can see failed jobs. In test, cause a known failure (for example an invalid email address) and check that it shows up somewhere a person will see it.
Warning sign
No record of failed jobs anywhere, or jobs that use the database secret key with no tenant check. Our guide to reliable background jobs with Redis and BullMQ covers retries, stalled jobs and idempotent handlers.
Reference
OWASP Multi-Tenant Application Security Cheat Sheet (tenant-aware asynchronous work).

Data you cannot afford to lose

12. Database migrations

What to check
Every schema change, including access policies, is a migration file in the repository, applied to the test environment before production. Nobody edits the production schema by hand in a dashboard.
Why it matters
Supabase describes migrations as SQL statements that change your schema and a common way of tracking changes to your database over time. When policies live in migration files, they are reviewed like code and can be rebuilt in a fresh environment.
How to verify safely
Ask whether a fresh database can be built from the repository alone, then compare its tables and policies with production.
Warning sign
Production has tables or policies that exist in no file; a migration drops or renames a column with no plan for the data already in it.
Reference
Supabase database migrations.

13. Backups and restore tests

What to check
Automatic backups are on, you know how far back they go, and someone has restored one into a separate database and checked the data.
Why it matters
PostgreSQL's manual: PostgreSQL databases should be backed up regularly. On Supabase, Pro plan projects can access the last 7 days of daily backups; database backups are not available for download for Free Plan projects, and Supabase recommends that free projects regularly export their data using the Supabase CLI db dump command and maintain off-site backups. A backup nobody has restored is an assumption, not a plan.
How to verify safely
Check your plan and the backups page. Write down the date of the last restore test and how long it took. If there has never been one, schedule it before launch.
Warning sign
A free-plan project holding customer data with no exports, or no one able to say how a restore would work. Backups also go with the project: when you delete one, Supabase says we permanently remove all associated data, including any backups.
Reference
PostgreSQL Backup and Restore; Supabase database backups.

Running it in production

14. Dependency management

What to check
The lockfile is committed, dependency alerts are on, every package is one you meant to install, and updates are reviewed rather than skipped.
Why it matters
GitHub: Dependabot alerts help you find and fix vulnerable dependencies. npm audit asks for a report of known vulnerabilities in your dependencies, though some vulnerabilities cannot be fixed automatically. OWASP notes a risk specific to AI tools: they frequently suggest package names that do not exist on public registries, which attackers can then register.
How to verify safely
Turn on Dependabot alerts for the repository and run npm audit locally to see the report. Look up any package name you do not recognize on the public registry.
Warning sign
Hundreds of open alerts nobody reads; a package with an unfamiliar name, few downloads and a recent creation date.
Reference
GitHub Dependabot alerts; npm npm audit; OWASP Secure Coding with AI Cheat Sheet.

15. Error monitoring

What to check
Errors in production are reported to a tool that alerts a named person. Users see a plain error message, not a stack trace or a database error.
Why it matters
OWASP lists as a failure that the application cannot detect, escalate, or alert for active attacks in real-time or near real-time. Detailed error output helps an attacker: unhandled errors can assist an attacker in the reconnaissance phase.
How to verify safely
In the test environment, open a page with an ID that does not exist and submit a form with a missing field. Check what the user sees and whether the error reached your monitoring and someone was told.
Warning sign
Errors visible only in the browser console; stack traces or SQL in responses; alerts going to an inbox nobody reads.
Reference
OWASP Top 10:2025 A09; OWASP Error Handling Cheat Sheet.

16. Logging hygiene

What to check
Logs record security events (logins, failed logins, denied requests, admin actions) and leave out secrets and personal data.
Why it matters
OWASP's logging guidance lists access tokens, authentication passwords, database connection strings, encryption keys, payment card data and sensitive personal data among things that should usually not be recorded directly in the logs. The Top 10 names logging sensitive information that should not be logged (such as PII or PHI) as a failure.
How to verify safely
Sign up in the test environment with a distinctive test password, then search your log viewer for that password and for the names of your secret keys. Neither should appear.
Warning sign
Whole request bodies or headers logged; debugging statements that print the full user object; logs anyone on the project can read.
Reference
OWASP Logging Cheat Sheet; A09:2025.

17. Automated tests

What to check
Tests cover the rules that matter: user B cannot read user A's records, each role sees what it should, RLS policies hold, a repeated webhook is processed once. They run on every change.
Why it matters
OWASP's API guidance: write tests to evaluate the vulnerability of the authorization mechanism. Do not deploy changes that make the tests fail. Supabase documents running database tests in CI so you run your tests when you or your team make changes. For RLS, OWASP asks to prove that expected cross-tenant operations are denied and expected same-tenant operations succeed.
How to verify safely
Ask to see the access-control tests and when they last ran. A quick way for an engineer to prove a test is real: remove one check on a branch and confirm the test fails.
Warning sign
No tests, tests that only cover the happy path, or tests switched off to get a deploy through.
Reference
OWASP API1:2023; Supabase automated testing.

18. CI/CD and production configuration

What to check
The code is in a repository your company controls. Production deploys from the main branch through a pipeline that runs the tests. Production, preview and development have separate settings and keys. Admin access is limited to current people, with MFA.
Why it matters
Next.js's production checklist: ensure your .env.* files are added to .gitignore and only public variables are prefixed with NEXT_PUBLIC_. On Vercel you can select one or more Environments to apply the Variable to (Production, Preview, Development), so preview deployments can use test keys. Supabase reminds owners that they are always responsible for account and access management.
How to verify safely
List who has admin access to the repository, hosting, database, payment provider and domain registrar, and remove anyone who has left. Confirm MFA on each. Confirm preview deployments do not point at the production database or live payment keys.
Warning sign
Production deployed from someone's laptop or a builder's publish button with no tests; a former contractor still an admin; preview builds writing to production data.
Reference
Next.js production checklist; Vercel environment variables; Supabase shared responsibility model.

Summary: what you can check, and what needs an engineer

ItemSelf-checkNeeds an engineer
AuthenticationLog out and reuse an old URL; compare reset messages for known and unknown emails; MFA on your own admin accountsReview of session handling, reset flow and any custom auth code
Authorization per recordOpen user A’s record while logged in as user BTrace every read and write path to a server-side check
Supabase RLS and keysSecurity Advisor; RLS status per table; search the browser bundle for a secret keyWrite and review policies per role; check views and security definer functions
Tenant isolationRepeat the A/B test across two test tenants, including files and exportsIsolation tests on the real connection path and role
API access controlOpen a protected API URL while logged outInventory of routes, Server Actions and functions with their checks
Secrets and env varsList every NEXT_PUBLIC_ / VITE_ value and ask if you would publish itRotate exposed keys; clean repository history if needed
Input validationVery long text and an unexpected file type in a test formServer-side schemas for every endpoint
Rate and spending limitsSpending caps and billing alerts at each paid providerRate limits on login, reset and paid endpoints
Webhook signaturesLook for failed deliveries in the provider dashboardConfirm verification on the raw body before any action
Duplicate webhooksWatch for double emails or credits during testingIdempotent handlers keyed on event ID; ordering assumptions
Background jobsFind where failed jobs are visibleRetries, idempotency and tenant context in each job
MigrationsAsk whether a fresh database can be built from the repositoryReconcile dashboard changes into migrations; plan data changes
Backups and restoreCheck plan, retention and the date of the last restoreRun and time a restore into a separate database
DependenciesTurn on Dependabot alerts; run npm auditTriage alerts; check unfamiliar packages; plan upgrades
Error monitoringTrigger an error in test and see who is toldSet up reporting, alerts and generic error pages
Logging hygieneSearch logs for a unique test passwordRemove secrets and personal data from log statements
Automated testsAsk to see the access tests and their last runWrite tests for access rules, RLS and webhooks; gate deploys
CI/CD and production configList who has admin access; check MFA and which keys each environment usesPipeline from the main branch with tests; separate environments

When the self-checks are not enough

The self-checks tell you whether a problem is likely. They do not prove its absence. If the record-swap test fails, if nobody can list the API routes, if the webhook handler has never been tested twice, or if a restore has never been tried, the next step is an engineer reading the code paths behind those items. The work is usually specific: policies written per role, checks moved to the server, keys rotated, handlers made idempotent, migrations reconciled, a restore run and timed. That is the scope of our AI app to production service, which takes an existing AI-built codebase and makes it ready for real users.

If you want a second opinion on your own results, the first step is a 30-minute technical discovery call with an engineer. Bring the summary table with your answers filled in. We will tell you which items look fine, which need work, and whether that is a small fix or a larger piece of work. More on how that works is on the AI app to production page.

Frequently Asked Questions

Are apps built with Lovable, Replit, Bolt or Cursor insecure?

Not as a rule. The tool does not decide whether an app is secure; what was built and what was checked decides that. The tools say so themselves: Lovable’s documentation says its scans cannot guarantee complete security and that the app owner is responsible for meeting the security requirements of the use case. An AI-built app can pass every item on this checklist; the point is to check rather than assume.

Is it safe to have the Supabase publishable (anon) key in the browser?

Yes, that is what it is for, as long as Row Level Security is on. Supabase’s key guide says of the publishable key that anyone can read it, so it only reaches what Row Level Security allows. The secret key (and the older service_role key) is different: it bypasses every policy and must stay on servers you control.

Is the built-in security scan in my AI app builder enough?

It is a useful first pass, not a review. Lovable describes its Quick scan as a fixed set of checks that runs on every publish, and says its tools do not replace a thorough security review. Scans catch configuration problems such as a table without row-level security; they cannot tell whether your business rules (who may approve, refund or export) are enforced on the server.

Which checks can I do myself, and which need an engineer?

Anything you can test with two test accounts, the browser’s developer tools and your providers’ dashboards is a fair self-check: the record-swap test, a logged-out request to a protected URL, spending limits, Dependabot alerts and a search of the logs for a test password. Reading authorization code, writing RLS policies, making webhook handlers idempotent, cleaning up migrations and running a restore drill are engineering work. The summary table in this guide splits each item that way.

Do I need to rebuild an AI-built app before launch?

Not by default. Most items on this checklist are fixed in place: a policy added, a key moved to the server, a handler made idempotent. A rebuild is worth discussing only when a review shows that access rules, data model and tenancy would all have to change at once. Decide after the review, not before.

Technical consultation

Getting an AI-Built App Ready for Real Users?

Tell us what the app does, what it was built with and which items on this checklist you are unsure about. An engineer will tell you what looks fine, what needs work and how much.

  • A 30-minute technical discovery call with an engineer, not a salesperson.
  • Fixed-scope projects, monthly retainers, or a combination, agreed after the call.
  • Small, well-defined tasks get a scoped estimate. We reply within 1 business day.

Prefer to pick a time? Book a call on Calendly

Tell us about your project

We'll review your details and reach out within 1 business day.

Book Strategy CallCase Studies