Pre-launch security review for vibe-coded apps

Six checks to run before you submit a vibe-coded app. Each one ends as detected, unknown or confirmed by owner evidence.

Timothy Lindblom

Founder, Newly

Published Last updated

Review a vibe-coded app in this order: the keys that ship inside it, the database rules, the server check on every route, what the AI feature can reach and spend, and what the app stores require. Each check ends as detected, unknown or confirmed by owner evidence. No review proves an app has no flaws, so the aim is a short list of proof you can show.

In what order should I review a vibe-coded app?

Start with what costs most when wrong and is quickest to confirm. A leaked secret key and an open table work for a stranger on launch day. A missing store declaration only blocks your submission.

CheckQuestionConfirmed by owner evidence
1. KeysWhich keys are inside the app?Only public keys ship; any secret key that shipped is revoked
2. Database rulesCan a user read rows that belong to someone else?Rules on every table; a second account is refused
3. RoutesDoes every endpoint check who is asking?A logged refusal for another user's record
4. AI featureWhat can it reach, and what does it cost?Provider key on a server; a per-user limit is set
5. Stores and paymentsWhat must be in place to publish?In-app account deletion; webhook signatures verified
6. Website and repositoryAre secrets served or stored in history?404 on /.env and /.git/config

The checks work whoever wrote the code. Newly builds a real iPhone and Android app with React Native and Expo, and you can download the code or connect your own repository, so every file named below is one you can open. The settings and the proof that they hold are yours. The OWASP Mobile Top 10 (2024) names the failures these checks target: improper credential usage (M1), insecure authentication and authorization (M3) and security misconfiguration (M8).

Which keys can ship inside the app, and which cannot?

Anything compiled into an app can be read by whoever installs it. Expo's docs warn that EXPO_PUBLIC_ variables "will be visible in plain-text in your compiled application", and the EAS docs add that anything included in client-side code should be considered public. List every variable in your .env files, your app config and your EAS settings, then sort each one with this table.

KeyIn the app?What the docs say
Supabase publishable (anon)YesSafe to expose, provided row level security is on
Supabase secret (service role)NoBackend only; it carries the bypassrls attribute
Firebase API keyYesIdentifies the project; Security Rules decide access
Stripe publishableYesMeant for apps and web pages
Stripe secretNoServer environment only; prefer restricted keys
OpenAI or another AI providerNoNever deploy the key in a mobile app

Firebase adds that keys for other services, such as the Gemini Developer API, should stay protected. If a secret key was ever inside a build or a public repository, treat it as exposed. GitHub's remediation guide calls revoking the secret with its provider the most important step, and says removing it from the code is not enough. Create the new key, switch the server to it, revoke the old one, then read the provider's usage log for requests you do not recognise. The rotation guide on red.run.cloud lists what to rotate first.

Tokens the app receives after sign-in belong somewhere else. expo-secure-store keeps them in the iOS Keychain and Android Keystore. It suits values created on the device at run time. It cannot hide a key you shipped.

Can one user read another user's data?

Request path of a typical app. The phone holds only public keys. A server you control checks who is asking and holds the secret keys, then talks to the database and the AI provider.The app on the phonePublic keys onlySession token after sign-inReadable by anyone who installs itEverything left of this line is publicYour server or functionChecks who is askingChecks the record is theirsHolds secret keys, sets limitsDatabaseRules on every tableAI provider, paymentsBilled per requestDirect call with the public key: the database rules are the only guard
Where each check from this page sits on the request path.

The public key in the app lets anyone call your backend directly, so the rules behind it are the guard. Supabase states that a table in an exposed schema without row level security is readable and writable by any role with a grant on it. With security enabled and no policy, the publishable key sees nothing. In each table, look for three things:

  • Row level security is enabled. In the dashboard this is a per-table switch.
  • No policy has a condition of plain true, which lets everyone through.
  • Views respect the policies. Supabase notes that views bypass row level security by default and offers security_invoker = true on Postgres 15 and later. Its guide on securing the Data API covers grants.

On Firebase, open the published rules. Firestore's test mode lets anyone read and overwrite your data, and Firebase describes Security Rules as the only safeguard against malicious users. A rule that allows read and write with a condition of true belongs to development only.

The two-account test

Rules can look right and still leave a gap, so test the behaviour. Create account A and account B. As A, make a record. Signed in as B, ask for A's record by its id, then try to change it and delete it. You want three refusals or empty results. OWASP lists this failure first in its API Security Top 10 as API1:2023, broken object level authorization. A secret key bypasses these rules when a request carries no user token, so any server function that uses one must run its own check on who is asking.

What can your AI feature reach, and what can it cost?

Four entries in the OWASP Top 10 for LLM Applications (2025) matter before launch: prompt injection (LLM01), excessive agency (LLM06), system prompt leakage (LLM07) and unbounded consumption (LLM10). OWASP's prompt injection cheat sheet says input screening is not a security boundary, because models do not separate instructions from data. Its advice is to grant minimal permissions and to require human approval for consequential tool actions.

Check five things in your own app. For the chat screen, use the chatbot self-test:

  • The provider key sits on a server. If it ever shipped, rotate it, as in this key rotation page.
  • The system prompt holds no secrets. Assume a user can make the model repeat it.
  • The model's tools act with the signed-in user's rights and no more.
  • Deleting, paying and sending need a confirmation from the user.
  • Each user has a message limit. AI inside a Newly app uses credits, and some features have limits. An endpoint anyone can call lets a stranger spend them.

What do the app stores and payment providers require?

You publish under your own Apple and Google accounts, so these declarations are yours. Both stores ask for account deletion from inside the product.

RequirementWhat the source saysWhat to check
Apple account deletionGuideline 5.1.1(v): if the app supports account creation, offer deletion within the appCreate and delete an account; confirm the rows are gone
Google account deletionIn-app path plus a web link to request deletion of the account and its dataBoth paths work and reach the same deletion
Google data safetyDeclare how the app collects and handles user dataThe form matches what your database and AI provider receive
Payment webhooksStripe: verify that events come from Stripe before acting on themA test event with a bad signature is rejected

Declarations follow the data

If a chat message or an uploaded document goes to an AI provider, your store declarations and privacy text should say so. We checked the store sources on 24 October 2026; read the current text when you submit.

What about the website and the repository?

Open /.env and /.git/config on your own domain in a browser. A 404 is the result you want. Automated requests for these paths are common, and the 30-second check on red.run.cloud explains what a hit in your logs means.

For the repository, turn on push protection, which blocks pushes that contain secrets before they reach the repository. GitHub's docs say it requires GitHub Secret Protection on private repositories, so read the current plan terms. It does not clean history that already holds a secret, so rotate those keys first. Runtime versions such as Node.js belong to your build and server machines, and the 15-minute check has the fixed versions.

Where do you stand?

Every item starts as unknown. Mark it detected when you find the problem, and confirmed only when you hold the evidence listed under it. For a longer list, OWASP's MASVS sets out the requirements a mobile app can be verified against.

Your pre-launch review

  • Detected: You found the problem.
  • Unknown: Not checked yet, or the check could not tell.
  • Confirmed by owner evidence: You checked and kept the proof.
  1. 1. Every key in the bundle is public by design, and any secret key that ever shipped has been revoked and replaced.

    Evidence: your variable list, each marked public or server-only, plus the provider's revocation record.

  2. 2. Row level security or your backend's rules are on for every table, and no policy or rule lets everyone through.

    Evidence: a screenshot of each table's status and policies, and for Firebase the published rules file.

  3. 3. A second test account is refused when it reads, changes or deletes the first account's records.

    Evidence: the three requests you sent and the refusal or empty result each returned.

  4. 4. The AI provider key lives on a server, each user has a message limit, and the model's tools can only do what that user could do.

    Evidence: the server setting that holds the key, the limit value and the tool list.

  5. 5. A new account can be deleted inside the app, and its data is gone from the database afterwards.

    Evidence: a screen recording of the flow and the database rows before and after.

  6. 6. Payment webhooks are accepted only after their signature is verified.

    Evidence: the verification line in your server code and a rejected test event.

  7. 7. /.env and /.git/config on your domain return 404, and no secret remains in the repository history.

    Evidence: the two 404 responses and a secret-scanning report for the repository.

0 detected7 unknown0 confirmed by owner evidence

Your answers stay in this browser tab. Nothing is saved or sent.

Frequently asked questions

How long does a pre-launch review take?

The key list and the store checks are quick. Most of the time goes into reading each table's policies and running the two-account test on every route that returns user data, so it grows with the size of the app.

Is a Supabase publishable (anon) key in my app a leak?

No. Supabase documents publishable keys as safe to expose in a mobile app, provided row level security is enabled on every table in an exposed schema. The service role (secret) key must never ship.

I found a secret key in my app bundle. What do I do first?

Revoke it with the provider and issue a new one. GitHub's guidance calls revoking the most important step, and deleting the key from code or history does not help once a build has shipped. Then keep the new key on a server and read the provider's usage for requests you do not recognise.

Do I have to read every line of code the AI wrote?

No. The checks look at behaviour: which keys ship, which rows a second account can reach, what an endpoint answers and what the AI feature may do. Reading the code only helps you find where to point them.

If a red.run.cloud scan finds nothing, can I launch?

No scan can say that. Both red.run.cloud scans work from outside, so rules and code that never answer a public request stay unknown until you hold owner evidence.

Who is responsible for the security of an app built with AI?

You are, as the owner. You publish under your own Apple and Google accounts, hold the keys, write the database rules and make the store declarations.

Sources

  1. OWASP Mobile Top 10, 2024 final list, OWASP Foundation, checked 2026-10-24
  2. OWASP API Security Top 10, 2023, OWASP Foundation, checked 2026-10-24
  3. OWASP Top 10 for LLM Applications, 2025, OWASP GenAI Security Project, checked 2026-10-24
  4. LLM Prompt Injection Prevention Cheat Sheet, OWASP Cheat Sheet Series, checked 2026-10-24
  5. Mobile Application Security Verification Standard, OWASP MAS project, checked 2026-10-24
  6. Row Level Security, Supabase docs, checked 2026-10-24
  7. Understanding API keys, Supabase docs, checked 2026-10-24
  8. Securing your API, Supabase docs, checked 2026-10-24
  9. Get started with Cloud Firestore Security Rules, Firebase docs, checked 2026-10-24
  10. Learn about using and managing API keys, Firebase docs, checked 2026-10-24
  11. Environment variables in Expo, Expo docs, checked 2026-10-24
  12. Environment variables in EAS, Expo docs, checked 2026-10-24
  13. SecureStore, Expo docs, checked 2026-10-24
  14. Remediating a leaked secret, GitHub Docs, checked 2026-10-24
  15. About push protection, GitHub Docs, checked 2026-10-24
  16. API key best practices, Stripe docs, checked 2026-10-24
  17. Receive Stripe events in your webhook endpoint, Stripe docs, checked 2026-10-24
  18. Best practices for API key safety, OpenAI Help Center, checked 2026-10-24
  19. App Review Guidelines, section 5.1.1, Apple Developer, checked 2026-10-24
  20. Understand app account deletion requirements, Google Play Console Help, checked 2026-10-24
  21. Provide information for Google Play's Data safety section, Google Play Console Help, checked 2026-10-24

Continue Learning