Is my Bolt app secure?
Bolt builds and previews the app in the browser, then you publish a URL. Preview-in-the-browser is handy, and it is also how a secret ends up in the bundle a visitor downloads. Here is what to look for on a Bolt app.
Free check
Check the live app
Paste the public Bolt URL. The check reads what a visitor's browser can already see, then gives you a private report with a fix prompt for each issue.
What Bolt actually ships
Bolt.new runs on StackBlitz WebContainers, so the project is real JavaScript with a live preview. The usual frontend is React with Vite. Bolt's docs say new projects use Bolt Database unless you choose Supabase when you create the project, and the Supabase connection is available for Vite projects. Other frameworks can run if they run on WebContainers. This page sticks to those two databases and to what a public page can leak.
Mistakes worth checking
These are the ones that show up in apps built with Bolt. Each step is something you can do in the browser or in the product dashboard.
Critical
A VITE_ variable that holds a real secret
Vite copies every VITE_ variable into the browser bundle. VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are expected when you connect Supabase. A service role key, an OpenAI key, or a Stripe secret key with that prefix is public as soon as the app is published.
Check it yourself
Open the published site, then search the page and its JavaScript for service_role, sk-, sk_live, and rk_. In the Bolt project, read the env file and confirm secret names do not start with VITE_.
High
Supabase tables with row-level security off
If you picked Supabase, Bolt can create tables from the chat. Creating the table does not lock it. A follow-up prompt that says the query is failing will sometimes add a policy that allows every role, because that makes the preview succeed.
Check it yourself
In the Supabase table editor, turn on row-level security for every table in the public schema. Policies for private data should tie the row to the signed-in user, for example auth.uid() matching that user's id. A policy whose check is only true is a public table.
High
Bolt Database records a stranger can read
New Bolt projects use Bolt Database unless you chose Supabase at the start. Deploy Safely cannot open that database or read its access settings. Private customer data still needs a rule you have looked at yourself.
Check it yourself
In the Bolt project, open the database settings and confirm private records require a signed-in user. If you cannot tell what a signed-out visitor is allowed to read, treat the data as private and tighten the setting before you share the app.
Critical
An API call made directly from a React component
The preview runs in the browser. A model that is asked to "call OpenAI" or "charge the card" may put the secret in the component that is on screen. That file is what visitors download.
Check it yourself
Search the published JavaScript for the key prefix. Move the call to a server or edge function, delete the key from the client, and rotate the key. The old copy is already public if the site was live.
Medium
Source maps, or an .env file, on the published host
A Vite build can leave a source map next to the bundle, and a static deploy can copy .env into the public folder. Bolt's preview env file is easy to forget when you publish elsewhere.
Check it yourself
On the live domain, open /.env. You want a not-found response. In developer tools, look for sourceMappingURL on a script from your domain and open it. If the map contains original source, turn maps off and remove the file.
A prompt you can paste
Paste this into Bolt, publish again, and run the check a second time. If a key was already on the live site, rotate it in the vendor dashboard. The prompt cannot do that part.
Review this Bolt app and remove anything a visitor can already see. 1. In client code and in Vite env variables, remove any Supabase service_role key, any key starting with sk-, sk_live, sk_test, or rk_, and any database URL that contains a password. Keep VITE_SUPABASE_URL and the anon key if Supabase is connected. Do not prefix a secret with VITE_. 2. If this project uses Supabase, enable row-level security on every public table and add policies so each user only reaches their own rows. Do not use a policy of true, and do not put the service role key in the frontend to get around an error. 3. If this project uses Bolt Database, keep private records limited to signed-in users. Tell me which collections you changed. 4. Move provider calls (OpenAI, Anthropic, Stripe secret operations) to a server or edge function that reads the secret from the server environment. 5. Disable production source maps and make sure .env is not deployed. List any key that was already public so I can rotate it. Do not loosen a rule so the preview will load.
What the check looks at
- The public page and the JavaScript it loads, for common leaked secret keys: a Supabase service role key, OpenAI, Anthropic, Stripe secret keys, AWS, GitHub, Slack, private keys, and database URLs that include a password. A Supabase anon key is called out as expected in the browser.
- A short list of public paths: /.env, /.env.local, /.env.production, /.git/config, /.git/HEAD, and /.npmrc.
- A source map, only when a script on the page already points at one, and only when that map includes original source.
- Supabase tables, only when the page already includes a supabase.co address and the public anon key. It asks for one row per table, then drops that row.
- Firebase Realtime Database and Firestore, only when the public config is already in the page. It uses that public config and does not sign in.
- A few browser safety headers on the main response. Missing headers are noted when two or more of the watched ones are absent. They are less urgent than a leaked key.
What stays outside it
- It reads. It does not log in, submit forms, or change data.
- It does not guess passwords, fuzz inputs, or hunt through hidden paths.
- It does not use any secret it finds, including a service role key.
- It does not open your builder's dashboard. A rule that lives only there can stay invisible.
- A clear result describes this public look. It is not a certificate that the whole app is safe.
- Bolt Database access rules are outside this check. Review them in the Bolt project if the app uses that database.
Questions
Free check
Run it on the published URL
Use the address a customer would type. The report stays private, and the shareable scorecard hides the details.
Other builders
- Is my Lovable app secure?Service role keys, row-level security, and variables that ship to the browser.
- Is my Replit app secure?Secrets in the page, a public Repl, and DATABASE_URL where a visitor can read it.
- Is my Cursor app secure?Client env prefixes, row-level security, Firebase test mode, and source maps.
- Is my v0 app secure?Next.js client bundles, Vercel env vars, and optional Supabase or Neon.
- Is my Base44 app secure?Entity rules you check by hand, plus Vite secrets and service-role calls.
- Is my Windsurf app secure?Agent edits that ship a secret, loosen a database rule, or publish a source map.
- Is my Bubble app secure?Privacy rules, API Connector secrets, and the Data API admin token.