Skip to content
SealMyApp

Is my Bolt app secure?

A Bolt app can be secure, but Bolt doesn't make it secure for you: your data is protected by your database's access rules and by keeping secret keys in server functions, and both are easy to get wrong when an AI writes the code. Before you publish, check that every table has access rules, that no secret key is in the browser bundle, and run Bolt's own security audits.

Run a free, read-only scan of your Bolt app to see where you stand. It takes a couple of minutes once you've proved you own the app.

How Bolt apps are usually built

Bolt builds web apps in the browser and can give them a built-in database through Bolt Cloud. Bolt's docs say that on paid plans you can choose Supabase for new projects or claim the database into your own Supabase project.

Bolt's Supabase docs use VITE_-prefixed variables, the Vite convention for values that are compiled into the frontend. Anything in a VITE_ variable is public.

Secret keys belong in Bolt Cloud's Secrets (in the database settings), where server functions can use them without exposing them to visitors.

Bolt's own security tools

Bolt's docs describe a Database Security Audit, available on all plans, that checks database permissions and missing Row Level Security and can ask Bolt to fix what it finds.

On paid plans there's also a project-wide security audit from the Publish menu that looks for secrets in code or the browser, CORS problems and unvalidated input.

Use both before every publish. They read your project; an outside-in scan checks what the live app actually exposes.

Common risks in Bolt apps

Tables with missing or loose access rules

If the browser talks to Supabase directly, every table it can reach needs Row Level Security with owner-based policies. A policy with using (true) or one that only checks "signed in" is effectively public.

Secret keys in VITE_ variables

Putting an OpenAI or Stripe secret key in a VITE_ variable feels private because it's in an env file, but Vite copies it into the JavaScript every visitor downloads. Move the call into a server function that reads the key from Secrets, then rotate the key.

Server functions anyone can call

A server function that forwards requests to a paid API is a public URL. It should check the signed-in user, validate what they're asking for, and rate-limit.

The service role key in the client

When an AI hits a permissions error it sometimes switches the client to the Supabase service_role key, which bypasses all access rules. That key must only ever be used on a server.

Files and source maps on the published site

Check that .env, .git and .map files aren't served from your live URL. Source maps publish your original code, comments included.

What SealMyApp's scan checks

  • If your app talks to Supabase from the browser, we test which tables and storage buckets answer to the public key, fetching at most one row to confirm and keeping only the table and column names.
  • If the browser never talks to the database directly, that check has nothing to test, and we focus on the bundle, files and routes below.
  • Searches your JavaScript for secret keys (Stripe, OpenAI, Anthropic, AWS, Supabase service role and more).
  • Checks for exposed .env, .git, database dump and source-map files.
  • Probes common admin and API paths for responses that don't need a login, and reviews basic security headers.

We check from the outside, the way a stranger would, and never sign in, so problems that only show up for logged-in users (one user reading another's data, for example) aren't visible to us. A clean result means our checks found nothing, not that your app is guaranteed secure.

Quick checklist

  • Run Bolt's Database Security Audit (and the project security audit if your plan has it).
  • Every table the browser can reach has Row Level Security with owner checks.
  • No secret key is in a VITE_ variable or pasted into a component.
  • Secret keys live in Secrets and are only used in server functions.
  • Server functions check the signed-in user and rate-limit.
  • No .env, .git or source-map files on the live site.
  • Re-check after big AI edits.

FAQ

Is the Supabase anon key in my Bolt app a problem?

No, it's designed to be public. What matters is that Row Level Security stops it reading private tables. The service_role key is the one that must never be in the frontend.

Are my Bolt secrets safe?

Secrets stored in Bolt Cloud's Secrets and used from server functions aren't sent to visitors. A key in a VITE_ variable or in component code is public, wherever it's stored.

Is Bolt's security audit enough?

It's a good first pass and you should run it. It's worth also testing the live app from the outside and re-checking after changes, because each AI edit can change what's exposed.

Can you scan a Bolt app that uses the built-in database?

Yes. If the browser queries the database directly we test what the public key can read; if it doesn't, we still check the bundle, exposed files, routes and headers.

Go deeper

Sources

Bolt details were checked against the official docs on 2026-10-16. Builders change their products often, so check the current docs if something here doesn't match what you see.

Sealed — a short weekly security note for vibe coders

One common security mistake in AI-built apps, how to fix it in your builder, and one useful tool. No spam; unsubscribe any time.