Skip to content
Back to field notes
BuildersJune 6, 20266 min read

Bolt.new app security: what ships by default and what to fix

Bolt.new deploys a live public URL in minutes, so the public surface is shipping before most builders think about hardening. This note covers the defaults to check first.

Bolt.newBuildersPublic surface

The public URL ships before you harden it

Bolt.new builds in a WebContainer and deploys to a hosted public URL in minutes. That speed is the point, but it also means the public surface is live before most people think about hardening it. By the time you share the link, anything the build left exposed is already reachable by anyone who opens it.

Bolt.new app security splits cleanly into two halves. Some defaults are directly observable on the public surface: anyone can open the URL, read the shipped JavaScript, and inspect response headers without an account. Others live in config or code you have to look at yourself: backend rules, route handlers, and which keys went where. The first half you can verify from a clean browser. The second half needs a look at the project.

This note covers four defaults worth checking before the URL spreads, with a quick check and a fix for each.

Four defaults to check

  • Vite source maps. Bolt.new apps are typically Vite projects, and a production build can emit source maps that map minified JavaScript back to readable source. If those maps are served from the public URL, your component names, route structure, internal comments, and client API paths become easy to read. This is directly observable: open DevTools, go to the Network tab, and look at the loaded .js assets for a trailing //# sourceMappingURL reference or sibling .map files. Safe result: no public .map files, or maps uploaded privately to monitoring. Suspicious result: a .map URL that loads readable source in a clean browser session. Fix: set build.sourcemap to false in vite.config for production, or restrict maps to an error-monitoring upload rather than linking them from public assets.
  • Client-bundle env exposure. In Vite, any environment variable prefixed VITE_ is inlined into the JavaScript that ships to the browser. That is by design for public config, but it means a key placed there is public — it is in the bundle every visitor downloads, not hidden on a server. This is directly observable: open the loaded JS in DevTools and search the bundle text for VITE_, for provider key shapes, or for the literal value of a key you recognize. Safe result: only publishable or anon-style identifiers that are meant to be public. Suspicious result: a service-role key, a private API secret, or a server token sitting in the client bundle. Fix: move anything secret out of VITE_* and behind a server route or backend function; rotate any secret that already shipped to the browser, because it must be treated as leaked.
  • Open API routes and missing headers. The hosted URL serves whatever the template wired up, and a fast deploy often skips a security-header pass. Missing headers and unintended public routes are directly observable. Check response headers on the home page and on any app or API route with DevTools or curl -I against the live URL, and try hitting API paths directly without a session. Safe result: a deliberate header baseline (content type options, framing control, a content security policy that fits the app) and API routes that reject unauthenticated requests. Suspicious result: no security headers and an API route that returns data to an anonymous request. Fix: add an explicit header baseline for production, and confirm every data route checks auth server-side rather than relying on the UI to hide it.
  • Default backend / Supabase config. Templates that wire up Supabase or another backend get you a working data layer fast, but the default often ships without row-level security or auth rules tightened for your data. This is mostly not observable from the public surface — it needs a look at your backend config and policies. The partial public signal is an anon endpoint that returns rows it should not. Safe result: row-level security enabled, policies scoped to the authenticated user, and anon access limited to data that is genuinely public. Suspicious result: RLS off, or a policy that lets the anon key read or write tables it should not. Fix: enable RLS, write per-table policies that match your real access model, and test them with the anon key against your own endpoint.

Why Bolt.new apps hit this

None of these are bugs in Bolt.new. They are the cost of optimizing for a working app fast. The generated template picks sensible build and backend defaults for getting something running, and the deploy step turns a preview into a real launch URL before a hardening pass happens. The review loop that would catch a public source map or a misplaced VITE_ key is the step that gets skipped when the goal is to ship and share.

That is also why these checks are a useful early signal. A public source map or a default-config backend usually means the app is still carrying its demo-era settings — and that the other defaults on this list are worth checking too.

How to check from a clean browser

Run the observable checks from outside your project, in a browser session with no cached login, against the deployed Bolt URL — not against local development, where build and proxy behavior differs.

The backend auth and RLS pieces need a look at your config, not just the browser. Treat the public-surface checks as the fast first pass and the backend review as the deliberate second one.

  • Open the production URL in a clean session and open DevTools.
  • In the Network tab, inspect the loaded .js assets for sourceMappingURL references and try loading any .map URL directly.
  • Search the bundle text for VITE_, for known provider key shapes, and for any secret value you recognize.
  • Check response headers on the home page and on app and API routes, and try an API route without a session.
  • If you use Supabase or a similar backend, query your own anon endpoint and confirm it only returns data that is meant to be public.

Where VibeCodeGuard fits, and what it does not prove

VibeCodeGuard's Launch Check scans the live Bolt URL for the observable half: missing security headers, exposed source maps, publicly readable storage, and secret-shaped strings in the client bundle — without needing workspace access. It reports severity and fix guidance for each finding so you can decide what to fix before sharing the link.

It does not cover the backend half. Auth correctness and RLS policy review still need a manual look at your config and code, because whether a policy matches your real access model is a judgment about your data, not a pattern visible from outside. Launch Check is not a penetration test, a code review, or a guarantee that the app is secure.

A clean public-surface scan means the obvious launch-day exposures are handled — not that your backend authorization is correct. Run a focused Launch Check against the Bolt URL before sharing it publicly, then sit down with your RLS policies and auth routes as a separate, deliberate pass.

> launch check

Scan the public surface before launch.

Get severity, evidence, and practical fix guidance for the checks VibeCodeGuard can run from the outside.

> sources

References