Launchprep launchprep.
readiness scan for AI-built apps

Is your Bolt app secure? What to check before launch

Bolt publishes what it builds, so most of your logic ends up somewhere a visitor can read it. Five things to check.

Bolt gives you a real database and real logins by default, which is good, and it also publishes your site publicly by default, tends to leave most of your app’s logic in the browser where anyone can read it, and has one page in its own beginner documentation that lists a variable name which, used literally in a Vite project, ships your database master key to every visitor. So if you are asking “is my Bolt app secure” a few days before launch, the useful answer is: probably not yet, for reasons that have nothing to do with your code being bad, and you can check every one of them yourself without knowing anything about security. Below are the five checks in the order that matters, starting with the one that is specific to Bolt (bolt.new, by StackBlitz) and that quietly cancels out all the others.

1. Search your built app for the words “service_role”

By default Bolt creates a database for your project on its own, called Bolt Database. Under the hood that is Supabase — Supabase’s own Bolt Cloud launch post says every project that needs a backend is powered by Supabase. Historically it came with two keys. The anon key is meant to be public, and sitting in your app’s code it is fine provided your table rules are actually set up, which is check 5. The service role key is the master key: it ignores every permission rule you set up and can read, change or delete every row belonging to every user. Supabase is in the middle of replacing this pair with new keys named sb_publishable_ and sb_secret_, so which names you see depends on how new your project is. The roles are the same; only the labels changed.

Bolt’s beginner page “Introduction to databases” has a section on environment variables (values you store outside your code) that describes them as keeping information private, and then lists three variable names to use, one of which is VITE_SUPABASE_SERVICE_ROLE_KEY. The problem is the VITE_ part. Anything with that prefix gets copied into the JavaScript file that every visitor to your site downloads. Same file, same prefix: the anon key there is by design, the service role key there is a total loss of your database. Bolt does have a separate Secrets area for exactly this — its docs describe secrets as the way server functions reach sensitive values without exposing them to users — and that is where a master key belongs.

Check the version you actually ship, not your source files. Build the project and search the output:

npm run build && grep -rE 'service_role|sb_secret_|sk_(test|live)_|eyJ[A-Za-z0-9_-]{20,}' dist/

Or, on your live site, open your browser’s developer tools, go to Sources, and search the JavaScript files for service_role and sb_secret_. Also search your project for VITE_ followed by SECRET or SERVICE. If you find it, deleting the line is not enough. The key has already been public, so go into the database settings and rotate it.

2. Find out whether your site is already live

Bolt’s publish menu sets visibility to public by default, which means anyone on the web can open it and search engines can list it. Two documented details make private harder than it looks: a site with a custom domain attached can only be published publicly until you disconnect the domain, and if you are on a team, other members can view your site by default even when it is private. So it is worth confirming rather than assuming you set it once.

Open the publish menu and read the visibility setting. Then test it from outside: load your .bolt.host address in a private browsing window where you are not logged in, and search for site:yourproject.bolt.host in Google. While you are there, click the database icon and confirm whether a database exists at all. Bolt creates one automatically if it thinks your project needs it, so if your app only ever stored things on the visitor’s own device, a live database sitting there is itself worth looking into.

3. Know which of Bolt’s two security checks you actually ran

Bolt documents two different things and they are not the same. The database security check, under the database icon, looks at your database only and is available on all plans. The project security audit reviews your whole project including your code, and at the time of writing Bolt lists it as available on paid plans, so confirm what your plan includes before assuming. Bolt’s own docs draw the line: the database check covers “only your database, not your whole project”. That matters because a green database page says nothing about whether your code lets someone change a price or skip a payment step. If the audit button is missing or locked, then unless you have read the code yourself or run another tool over it, nobody has.

One trap worth knowing: Bolt’s docs say to use the Run security audit button in the publish menu, because that button does not consume tokens, while prompting Bolt in chat to audit your project does — and is not the same check.

4. Work out what runs on your visitor’s computer

Bolt builds and previews your app inside WebContainer, StackBlitz’s technology that runs a full Node.js development environment in your browser tab rather than on a server. That is the editor, not your published site. What gets published is the built front end, so the practical result is that what feels like a full app is usually a page in the visitor’s browser talking straight to the database, and code that runs away from the user exists only where a server function (Bolt’s name for a small piece of code that runs on a server) was created for it — by you asking, or by Bolt deciding it needed one.

Click the database icon, then Server Functions, and list what you have. Then, for every action involving money, permissions or limits, work out which side it happens on. The blunt test: open developer tools on your live site, start a checkout, and change the amount or the plan in the outgoing request before it sends. If the charge goes through at your new number, the decision was being made on the customer’s computer. Bolt’s Stripe setup asks you to paste a secret key into a box early on — its docs tell you to use a test key while building — so confirm that key starts with sk_test_ while you are still testing, and that no text starting sk_ shows up in your built files.

5. Test your data rules with two accounts, and check who can sign up

The system prompt in bolt.diy, the official open-source version of Bolt, tells the model to always enable row level security — the database setting that decides which rows each logged-in person may read — for every new table. Whether the hosted product runs the same instructions is not published, so treat it as an intention rather than a guarantee. The realistic failure is not a missing rule but a rule that lets everyone through, which is why Bolt’s database security check ships a warning literally named “RLS Policy Always True”. Do not take anyone’s word for it. Create two ordinary accounts, put data in each, and from account A try to open account B’s pages by changing the id in the URL.

Then check sign-ups. Click the database icon, go to Authentication, open the Email provider settings, and look at whether “Require users to confirm their email after signing up” is switched on. That same bolt.diy prompt still instructs the model that email confirmation is always disabled unless you say otherwise, and Bolt’s own docs list the toggle without stating a default, so read yours rather than assuming. If confirmation is off, anyone can register using an address they do not own. That becomes a real problem the moment anything in your app decides who someone is by their email address instead of their account id, so check invites and team lookups specifically.

Those five cover most of what actually goes wrong with a Bolt app before launch. If you want the rest in order, the pre-launch checklist walks through the same ground plus the non-database items. npx launchprep automates the parts a scanner can do — searching your built files for exposed keys and flagging decisions your code makes in the browser — and the free tier is unlimited and runs on your machine. The checks that need your Bolt dashboard or two test accounts stay manual.

Questions people ask

My Supabase key is visible in the browser. Have I been hacked? Almost certainly not. The anon key, and its replacement sb_publishable_, are designed to sit in the browser and are safe there as long as your table rules are set up. What is never safe there is the service role key. On the older key format you can check by decoding it and reading its role field: if it says anon, relax; if it says service_role, rotate it today. The newer keys cannot be decoded, so go by the prefix instead — sb_publishable_ belongs in the browser, sb_secret_ never does.

Bolt’s security page shows no issues. Am I done? Only if you ran the audit that reads your code. The database check that everyone gets looks at database settings, and it will happily show green while your app is calculating prices in the browser or letting one customer read another’s records.

Is Bolt less secure than other AI app builders? There is no evidence for that either way, and no published Bolt-specific breach that I could find, which is not the same as there being none. The one difference worth naming is packaging rather than safety: Bolt’s beginner documentation puts a service role key behind the VITE_ prefix, which is exactly the prefix that publishes a value to the browser. If you also build elsewhere, the equivalent list for a Lovable app is a different set of checks.

More writing · The pre-launch checklist

Run every check that applies to your project, on your machine, free and unlimited:

npx launchprep