AI-coded apps

    Is Bolt.new production ready for security?

    Bolt.new project open in a browser with the Supabase dashboard alongside, showing default auth and database settings for a production readiness review

    Bolt.new ships builds quickly, which is the whole point, and that is also the source of most of its security problems. The question "is it production ready for security" rarely has a clean yes. The honest answer is that a Bolt project is closer to a working prototype than a hardened app, and the gap between the two is bigger than most founders realize on the first deploy.

    Short answer

    Bolt.new is production ready for security only after you harden it. Out of the box, the default Bolt database is fine for prototypes, and Bolt Cloud authentication handles signup flows. The risk shows up at the seams: API keys in client bundles, Supabase tables created without Row Level Security, and direct browser calls to paid providers. According to Supabase's API security guide, RLS is the foundational layer for any table exposed via the Data API, and tables created outside the dashboard need it enabled manually. That matches what shows up in most Bolt projects audited before launch.

    What you should know

    • Bolt's default backend changed in September 2025. Per Bolt's Supabase integration docs, Claude Agent projects now default to the Bolt database, not Supabase, although Supabase remains an option.
    • The anon key is only safe if RLS is on. A public anon key with RLS disabled is functionally an admin key for the table, since the anon role can read every row.
    • Frontend code is public code. Anything Bolt writes into a Vite client file ends up in the production bundle, including any VITE_* env variable, every fetch URL, and every string that looks like a secret.
    • Bolt Cloud auth replaces Supabase Auth for new projects but does not change the data posture of Supabase tables if you connect Supabase later for storage.
    • App Review is not a security audit. App Store Connect can approve a build with an open Supabase backend, because Apple does not inspect your database posture.

    How does Bolt.new handle authentication by default?

    The short answer is that Bolt.new ships native authentication inside Bolt Cloud, and that is the default for new projects. Bolt's own documentation states that Claude Agent projects created after 2025-09-30 default to the Bolt database with Bolt Cloud auth, while older projects defaulted to Supabase Auth. Both flows handle email signup, password reset, and session tokens reasonably well for a prototype.

    The mechanism matters. Bolt Cloud auth runs on Bolt's infrastructure, which means the session tokens, password hashing, and rate limiting are not your problem to configure. That removes a class of beginner mistakes, like writing a custom JWT verifier that does not check expiry. The trade-off is portability. If you outgrow Bolt Cloud and migrate to Supabase or Clerk later, you re-do the user table mapping by hand.

    In practice the failure mode is not the auth provider itself. It is what happens after login. Bolt's generated client often trusts the user object returned from the auth call and then queries the database with the same anon credentials it would use for an unauthenticated visitor. The authorization check, if there is one, lives in the client. Anyone who opens DevTools and rewrites the request body can act as any user. The fix is to enforce authorization on the server, either through Supabase RLS policies that match auth.uid() or through Bolt Edge Functions that re-check the token.

    Is the default database in Bolt.new safe for real users?

    It depends on which default you mean. The Bolt database, used for prototypes, is a managed Postgres instance with a single connection string and limited per-row access controls. For a side project it is fine. For an app with real users, the relevant question is whether you can express row-level authorization that survives a hostile client, and the Bolt database does not give you that in the same way Supabase does.

    When you connect Supabase instead, the picture changes. Supabase exposes a REST and GraphQL API on every table, and that API trusts whichever JWT the client presents. As Supabase explains, the anon role should have minimal privileges, the authenticated role is still constrained by RLS, and the service_role should only be used in secure backend environments. Bolt's AI assistant frequently violates the second and third of those, by skipping RLS entirely or putting the service role key in client code.

    The pattern looks like this. Bolt generates a supabase.ts file with createClient(URL, ANON_KEY). It writes SQL to create a messages table. RLS stays off by default unless you ask for it. The app works, because the anon role can read every row. A week later, a competitor opens DevTools, copies the anon key, and queries from('messages').select('*') from a script. They get everything.

    What security gaps appear most often in Bolt.new builds?

    Four gaps account for most of the incidents I see in Bolt audits. Each is concrete, each is fixable, and each is invisible until someone exploits it.

    GapWhere it shows upFix
    API keys in client bundles.tsx files, VITE_* env vars referenced in client codeMove to Edge Function or Netlify Function; client calls the function, not the provider
    RLS disabled on Supabase tablesTables created by AI assistant via SQLalter table <name> enable row level security plus policies on auth.uid()
    using (true) policiesPolicies generated as a placeholderReplace with real predicates that match the user id to a row column
    Service role key in client code.env files with SUPABASE_SERVICE_ROLE_KEY referenced from the browserRotate the key, then use it only in server functions

    These match what vendor scans of Bolt projects consistently report, and they line up with OWASP MASVS-AUTH and MASVS-STORAGE controls when the app is wrapped for mobile. The mistake many founders make is treating these as edge cases. They are the base rate. If you ship a Bolt project to production without checking for them, the odds favor at least one being live.

    How do you tell if your Bolt project is leaking secrets?

    The fastest check is to open the deployed site in an incognito tab, open DevTools, and search the loaded JavaScript bundle for strings that look like keys. Look for sk_live_, eyJ, sb-, AIza, and pk_. Any hit on a secret pattern is a leak. The pk_ prefix on Stripe is intentionally public; the sk_ prefix is not.

    The second check is to query your own Supabase backend without logging in. From the browser console, run supabase.from('your_table').select('*'). If you get rows back without an authenticated session, RLS is off or the policy is permissive. If the policy is using (true), the policy exists but does nothing. Repeat the test for every table, because RLS is per-table, not per-database.

    The third check is to read the function code. Bolt Edge Functions and Netlify Functions are not automatically safe. A function that accepts a user id in the request body and uses it as the filter is no better than client-side authorization. The function should read the user from the verified JWT in the request header and ignore any user id the client claims.

    For builders who want an external automated read of their build before submission to App Store Connect or Google Play, PTKD.com (https://ptkd.com) is one of the platforms focused specifically on pre-submission scanning aligned with OWASP MASVS for no-code and vibe-coded apps. It does not replace the manual checks above; it catches the patterns that get missed when the founder has been staring at the same project for three weeks.

    What does "production ready" actually mean for a Bolt.new app?

    Production readiness for a security posture is not a single switch. It is the combination of a few specific properties, each of which can be verified.

    First, every secret with a cost attached lives server-side. OpenAI, Anthropic, Stripe secret keys, Twilio, SendGrid, Resend, and Supabase service role keys never appear in the client bundle. Second, every database query that returns user-scoped data goes through a check that the requesting user owns the rows. In Supabase that means RLS with auth.uid() predicates. In a custom backend that means a server-side authorization function. Third, rate limiting exists somewhere in the request path, either at the function layer or at the CDN, so a single attacker cannot exhaust your AI provider budget overnight.

    The fourth property is logging. You want to know when something unusual happens, not discover it from a billing alert. Supabase exposes auth and database logs. Bolt Cloud exposes deploy and function logs. Wiring them to a basic alert, even a Slack webhook on 4xx spikes, removes the worst surprise category.

    The limit is honest: no automated scan and no checklist guarantees a Bolt build will not be breached. The checklist reduces the surface area to the things attackers do not look at first. The remaining risk lives in business logic, which no scanner can read.

    What to watch out for

    A common mistake is trusting the Bolt assistant when it claims to have "enabled security." The assistant can run SQL that turns RLS on without writing any policies, which leaves the table accessible to no one through the API, including your own app. The app then breaks. The natural reaction is to write create policy ... using (true), which restores access for everyone. Both states are unsafe. The correct state is RLS on, policies written against auth.uid(), and a smoke test that confirms an unauthenticated client gets zero rows.

    Another mistake is assuming a VITE_ prefix means "safe to expose." Vite uses the prefix to decide what to bundle into the client. A VITE_OPENAI_KEY is bundled into the client. The prefix is a routing rule, not a security boundary. If a key would be expensive to abuse, it does not belong in a VITE_ variable.

    A third mistake is treating App Store or Google Play approval as evidence the backend is safe. App Review checks the binary against Apple's App Review Guidelines, and Google Play checks against its policy set. Neither inspects whether your Supabase tables have RLS. A build with an exposed database can pass App Review and still get drained in week one.

    Key takeaways

    • A Bolt.new project is production ready for security only after you remove client-side secrets, enable Supabase RLS on every table, and re-check authorization in server functions.
    • The default Bolt database and Bolt Cloud auth are reasonable for prototypes, but switching to Supabase later requires auditing every table, not just the new ones.
    • The four gaps that account for most incidents are: keys in client bundles, RLS off, using (true) policies, and service role keys exposed to the browser.
    • Verify with three checks: search the bundle for secret patterns, query your tables without auth, and read every server function for client-supplied user ids.
    • Some teams outsource pre-submission scanning of their compiled builds to platforms like PTKD.com, which produces an OWASP MASVS-aligned report covering storage, network, and code quality categories before the binary reaches App Store Connect or Google Play.
    • #bolt.new
    • #supabase
    • #ai security
    • #rls
    • #production readiness
    • #auth

    Frequently asked questions

    Does Bolt.new enable Row Level Security on Supabase by default?
    Not reliably. When the Bolt assistant creates Supabase tables through SQL or the connector, RLS frequently stays off, and the generated policies are often missing or written as `using (true)`. Supabase documents that tables created outside the dashboard need RLS enabled manually, so any Bolt project using Supabase should be audited before the first real signup.
    Is the Supabase anon key safe to ship in a Bolt.new app?
    The anon key is designed to be public, but only if every table has RLS enabled and policies enforce `auth.uid()`. In Bolt builds that condition is often false, so the anon key effectively becomes a read or write token for the entire database. Treat it as public, then verify that public access still gives you nothing useful.
    What is the default authentication in Bolt.new in 2026?
    Projects created with the Claude Agent after September 30, 2025 default to the Bolt database and Bolt Cloud authentication, according to Bolt's own integration docs. Earlier projects defaulted to Supabase Auth. You can still connect Supabase, Auth0, or Clerk, but switching backends after the fact can drop existing data.
    Do Bolt.new apps leak API keys for OpenAI, Stripe, or Anthropic?
    They can, easily. Bolt is frontend-first, so any API key it writes into a `.tsx` or `.ts` file ends up in the browser bundle, visible in DevTools. Scrapers find exposed keys within hours. Move every paid-provider key into a Netlify or Supabase Edge Function, then call that function from the client with the user's session token.
    Can I run a Bolt.new build through App Review without security changes?
    You can, but the build is exposed to the same risks as any web app with an open database. App Review focuses on iOS-specific rules like Privacy Manifests and Guideline 5.1.1, not Supabase posture, so a leaky backend still passes review. Production readiness is a separate bar, and a passing review does not equal a safe app.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free