What Bolt typically generates and where the trust boundary is
Bolt builds and runs projects in the browser and can publish them on its built-in hosting. Its documentation describes a Supabase integration for adding a database, authentication or edge functions, and a separate database and secrets area in its cloud settings. Which stack you got depends on your prompts, so open the project files and identify the framework, the bundler and every place a backend is called.
The trust boundary is the same as for any client-heavy app. Code that runs in the visitor's browser is inspectable. If your project calls a database or a third-party API directly from that code, whatever credentials it uses are visible to anyone who opens the network tab or reads the bundle. Real protection belongs in database rules and in server-side code that holds secrets.
Bolt's documentation describes a project security audit that reviews who can see and change data, authentication, what is exposed publicly, input validation, and keys and security settings, and it says it checks that private keys and passwords are not stored in code or sent to visitors' browsers. It also describes a separate database security check. Use these, then confirm independently. A tool that fixes most issues automatically still flags some for manual action, so read every flag.
The review checklist
| Area | What to verify | How to test on your own project | Pass condition |
|---|---|---|---|
| Built-in audit | The project security audit ran on the final version, and every manual-action item was handled. | Run the audit from the publish flow, then read each finding. | No unresolved findings on data access, keys or authentication. |
| Database rules | If you use Supabase, every table has RLS and user-scoped policies. | Run the tables and policies queries in the commands section. | No user table has RLS off and no policy is simply true. |
| Secrets | No secret key sits in source files or in browser-visible variables. | Build, then grep the output and the source for secret patterns. | No matches, and secrets appear only in the platform's secrets settings or server code. |
| Logged-out access | Visitors without an account cannot read private data. | Open the published site in a private window and call your data endpoint with only the public key. | Private tables return empty results or errors. |
| Account isolation | One user cannot read or change another user's records. | Sign up two test users and swap record ids between them. | The second user cannot see or modify the first user's records. |
| Server functions | Functions verify the caller and derive identity from the token. | Call each function without a token and with the wrong user's token. | Both attempts are rejected or affect nothing of the victim's. |
| Input handling | Forms and API routes validate input on the server. | Submit oversized, empty and unexpected values from curl, bypassing the form. | The server rejects invalid input with a clear error rather than storing it. |
| Repository and history | Nothing sensitive was committed at any point. | Search history with the pickaxe command. | No hits, or every hit has been rotated. |
Commands and queries to run
If your project uses Supabase, run these in its SQL editor. They tell you whether row protection is on and what each policy allows.
select tablename, rowsecurity
from pg_tables
where schemaname = 'public'
order by tablename;
select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, cmd;Test the published site as an outsider
Use your own deployed address. Fetch the page, find the script files, and look for secret-shaped strings in what a stranger can download. Then call your data endpoint with only the public key.
Replace the bundle path with the script name you found in the first command. No output from the second command is the pass result. Empty or rejected results from the third are the pass result for private tables.
export SITE="https://your-project.example"
export SUPABASE_URL="https://YOUR-PROJECT.supabase.co"
export PUBLISHABLE_KEY="your-publishable-or-anon-key"
curl -s "$SITE" | grep -oE 'src="[^"]+\.js"'
curl -s "$SITE/assets/YOUR-BUNDLE.js" | grep -oE "service_role|sb_secret_|sk_live_|BEGIN PRIVATE KEY" | sort -u
curl -s "$SUPABASE_URL/rest/v1/YOUR_TABLE?select=*&limit=5" \
-H "apikey: $PUBLISHABLE_KEY"
git log --all -p -S"sk_live_" | head -50Secrets, environments and the publish step
Bolt's documentation lists a secrets settings area for the database in a Bolt project, and a security audit that looks for keys stored in code. Treat that as the place to put server-side values, and check the current documentation for exactly which contexts can read them. Values that the front end reads at build time end up in the bundle, so anything a framework marks as public should be safe to publish. The Vite documentation is explicit that VITE_ variables are bundled at build time and should not carry API keys.
Before the first publish, decide what is public on purpose. Sample data, seed accounts, debug pages and admin routes created during prototyping often survive into production. Remove them or lock them behind server-checked authorization, then publish and repeat the outsider tests against the live address rather than the preview.
Common mistakes with this workflow
- Treating a green audit as final. Read the manual-action items and re-test the data rules yourself.
- Calling a paid API straight from browser code with the provider's secret key. Route it through a server function that holds the key and limits use.
- Testing only in the in-browser preview. The published site has its own address, headers and environment.
- Letting the assistant loosen permissions to fix a failing feature. Re-run the policies query after every fix.
- Leaving seed users, demo admin accounts and test data in production.
- Forgetting to rotate a key that appeared in chat, in a file or in git history.
- Skipping a second test account, which is the only way to see cross-user leaks.
Keep it working
Re-run the audit and the two SQL queries after any large change, and repeat the two-account test before each release. Pass condition: a stranger with only your public address and public key can read nothing private, no secret string appears in downloadable files, and each test user sees only their own records.
Frequently asked questions
Does Bolt's security audit replace a manual review?
Bolt describes the audit as reviewing data access, authentication, exposure, input validation and keys, and fixing most issues automatically while flagging others for manual action. That is a useful first pass. It is not a substitute for testing your own rules from outside the app.
Where should my API keys go?
Server-side, in the platform's secrets settings or your function environment, never in browser code or a public variable. Check Bolt's current documentation for the exact place and which code can read it, and rotate any key that has appeared in a file, chat or commit.
Can I use this checklist on a Bolt project that is not on Supabase?
Yes, with substitutions. Replace the SQL rows with whatever access control your backend uses, and keep the rest: outsider tests, two-account isolation, secret searches, input checks and history review.
Is the preview the same as production?
Not necessarily. The published site can differ in address, environment values and configuration. Run your outsider tests against the live address after each publish.