Is my Bolt app secure? A pre-launch checklist for Bolt.new apps
Short answer: not automatically. Bolt can check your project for security problems and fix many of them, and its own docs recommend running a check at least once before you publish. But a built-in audit only looks for a fixed list of problems. Once your app is live, every visitor can read what it sends to the browser, so check that too.
Fastest outside check: run a free SniffPup scan on your published Bolt URL (your bolt.host address or custom domain). SniffPup looks at your site the way a stranger would: secret keys in your HTML and same-origin JavaScript (masked in the report), public /.env and /.git files, a downloadable source map, missing security headers, cookie flags and HTTPS. It lists every issue it finds, gives your site a 0–100 score, and shows the full explanation and a fix prompt you can paste into Bolt for the most serious one. It's passive: about 40 requests or fewer, no logins, and it never uses a secret key it finds. Then work through the steps below for the things no outside scan can see.
1. Run Bolt's own security checks first
Bolt has two checks, and they look at different things:
- Project security audit (paid plans): in the top-right corner click Publish, then Run security audit. It reviews your whole project, including who can see and change data, sign-in and sign-out, input your app accepts, and whether private keys are in your code or sent to the browser. Bolt fixes most problems itself and lists anything you need to do by hand. Running it from the Publish menu doesn't use tokens; asking for an audit in the chat does.
- Database security check (all plans): click the database icon at the top of your project, then Security. It uses the same checks as Supabase's Security Advisor and shows warnings such as RLS Policy Always True, Function Search Path Mutable or Leaked Password Protection Disabled, with an Ask Bolt to fix button.
Re-run both after you add a table, an integration or a login change. See Bolt's database security docs for what each warning means.
2. Keep secret keys out of VITE_ variables and the frontend
Most Bolt web projects are built with Vite. Vite puts every environment variable whose name starts with VITE_ into the JavaScript it sends to the browser, so anyone can read it. That's fine for public values like a Supabase project URL, a Supabase anon or sb_publishable_ key, or a Stripe pk_live_ key. It is never fine for a Supabase service_role or sb_secret_ key, a Stripe sk_live_ key, an OpenAI sk- key or any other secret. Calls that need a secret belong in server-side code, such as an Edge Function.
How to check: open your published site (not the editor preview), open DevTools → Sources and press Ctrl+Shift+F (Cmd+Option+F on Mac). Search for service_role, sb_secret_, sk_live_, sk- and PRIVATE KEY. If a secret key ever shipped, revoke it and make a new one at the provider. Deleting it from the code isn't enough. Our guide to finding exposed API keys on your website has the full list of patterns.
3. Check Row Level Security on every table
Bolt Cloud databases run on Supabase, and many Bolt apps connect their own Supabase project. Either way the frontend talks to the database with the public anon key, so Row Level Security policies are what keep strangers out of your data. Every table in an exposed schema needs RLS turned on, and each policy should be tied to the user (for example auth.uid() = user_id) unless the data really is public. A policy that just says using (true) lets everyone read every row. That's what Bolt's RLS Policy Always True warning is about.
How to check: fix every RLS warning in the database Security page, then test with two real accounts: user A should never see or change user B's rows. Check write policies (insert, update, delete) as carefully as reads. Our Supabase RLS checker guide has the SQL to list tables with RLS off and a signed-out test with your anon key.
4. Make sure protected pages are protected on the server
Hiding a button or redirecting non-admins in the browser doesn't protect anything, because anyone can call your database or functions directly. Admin-only data and actions need a database policy or a server-side check that verifies who is calling.
How to check: open your app signed out in a private window and try a few links that should need a login. Then sign in as a normal user and change an ID in a URL to someone else's record. You should be refused both times.
5. Check what your published site exposes
- Public
/.envor/.git/configfiles (you should get a 404 or your app's normal page, never file contents) - A public JavaScript source map, which can hand out your original code
- Missing security headers (Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- Cookies without Secure, HttpOnly or SameSite flags, and HTTP that doesn't redirect to HTTPS
How to check: add /.env and then /.git/config to the end of your live URL, and look at the response headers in DevTools → Network. A free SniffPup scan checks all of these at once.
6. Re-check after every big change
The risky moment is usually a new table, a new integration or a key pasted into the chat. Run Bolt's checks and an outside scan again whenever you change sign-in, payments or data access.
Where SniffPup fits
Bolt's audit sees your code and database settings, which an outside scanner can't. SniffPup sees what your published site actually serves to the public, which is what an attacker sees first. The free scan lists every issue by title and severity and shows the full fix for the most serious one. On Pro, after you verify you own the domain, a read-only Supabase check uses your site's public anon key to count which tables an anonymous visitor can read (row counts only, never row data). See exactly what the scanner does.
FAQ
Is my Bolt app secure by default?
Not automatically. Bolt offers a project security audit (on paid plans) and a database security check (on all plans), and recommends running a check at least once before you publish. Both are automated checks with a fixed list of things they look for, so also check your secrets, your database policies and what your published site exposes.
Is it safe that my Supabase anon key is in my Bolt app's JavaScript?
Yes, the anon or sb_publishable_ key is designed to be public, but only if Row Level Security is on for every exposed table and the policies are scoped to the right user. A service_role or sb_secret_ key must never be in the frontend, because it bypasses RLS.
Can SniffPup scan my Bolt app?
Yes, if it is published at a live web URL (a bolt.host address or your own domain). SniffPup checks what that site serves to any visitor: secrets in HTML and JavaScript, public .env and .git files, source maps, security headers, cookies and HTTPS. It can't scan native mobile apps, and the free scan can't see your database policies.
Does a clean SniffPup report mean my Bolt app is secure?
No. SniffPup checks what is publicly visible on your site. A clean report is not a guarantee of security. It can't see your source code, server logic, database policies or anything behind a login.
A clean report is not a guarantee of security. Only scan sites you own.