Secure your Bolt.new app
Bolt.new is fantastic for going from "idea" to "deployed prototype" in fifteen minutes. The "deployed" part is where it gets dangerous. The starter templates ship with example keys, the generated endpoints rarely have auth, and the one-click Netlify deploy pushes the lot straight to a public URL. If you're past the prototype stage, run through this before another deploy.
- 01
Strip example keys from the starter template
Bolt's templates include placeholder values like "your-stripe-key-here." Sometimes they also include real example tokens that look fake but actually work (typically test-mode keys from sandbox accounts). Strip them all before you commit.
Read the deep-dive: Exposed API keysPaste this into Cursor / Lovable / BoltGrep this project for any string that looks like an API key (sk_, pk_, AIza, ghp_, eyJ, sb-, AKIA). Replace each one with process.env.WHATEVER or import.meta.env.VITE_WHATEVER as appropriate. Tell me which ones I need to set in production.
- 02
Move env vars to the Netlify dashboard
The Bolt-to-Netlify pipeline doesn't always carry your .env over. Even when it does, the safer pattern is to set production secrets in the Netlify dashboard so they never touch your repo. Local .env keeps dev values; production reads from the host.
Read the deep-dive: .env file exposurePaste this into Cursor / Lovable / BoltList every env var this project reads. For each one, tell me whether it's a public client-side value or a server-side secret. Then give me the exact commands or dashboard steps to set the secrets in Netlify production.
- 03
Tighten CORS before deploying
Bolt's scaffolded endpoints often use the maximally permissive CORS config (Access-Control-Allow-Origin: *) because it works in every browser and never blocks development. In production, that means any website can call your API in the background using a logged-in user's cookies.
Read the deep-dive: CORS misconfigurationPaste this into Cursor / Lovable / BoltFind every CORS config in this project. Replace any `*` or `true` with a list containing exactly my production domain and (optionally) http://localhost:5173 for dev. Set Access-Control-Allow-Credentials to true only if I actually use cookies cross-origin.
- 04
Add auth to every Bolt-generated endpoint
"Add a route that returns user data" usually comes back as a route that returns user data to anyone who asks. Bolt skips the auth check more often than it adds it. Read the diff specifically for `if (!session)` or your framework's equivalent.
Read the deep-dive: Unprotected API routesPaste this into Cursor / Lovable / BoltAudit every API route in this project. For each one, confirm there's an auth check that returns 401 when the user isn't signed in. List any routes missing the check and add one.
- 05
Check ownership in resource-by-id handlers
Same problem as Cursor here: Bolt will happily write `db.from('orders').select().eq('id', req.params.id)` without checking the order belongs to the caller. Logged-in user, any ID, your data.
Read the deep-dive: Broken access controlPaste this into Cursor / Lovable / BoltFind every route that fetches a resource by id from the URL. Add an ownership check that verifies the resource belongs to the current session's user. Return 403 on mismatch.
- 06
Rate limit before you go public
Prototypes don't need rate limits. Public URLs do. Without limits, your free-tier hosting and any provider quotas (OpenAI, Twilio, SendGrid) get drained by a single curl loop.
Read the deep-dive: API rate limitingPaste this into Cursor / Lovable / BoltAdd rate limiting to the public-facing endpoints in this project. Use Vercel or Netlify Edge Middleware, or a Redis-backed limiter like Upstash. Cap at 60 requests per minute per IP for general endpoints and 5 per minute for auth endpoints.
- 07
Verify Stripe webhooks
If Bolt scaffolded Stripe for you, the webhook handler may not verify the signature. That's a paid-feature unlock for anyone willing to send a POST request.
Read the deep-dive: Stripe webhook securityPaste this into Cursor / Lovable / BoltIn my Stripe webhook handler, verify the stripe-signature header using stripe.webhooks.constructEvent and STRIPE_WEBHOOK_SECRET. Reject the request with 400 if verification fails.
- 08
Force HTTPS and set HSTS
Netlify gives you HTTPS for free, but the redirect from HTTP isn't always on for custom domains. Same for the HSTS header. Flip both, then make sure your cookies are Secure.
Read the deep-dive: HTTPS enforcementPaste this into Cursor / Lovable / BoltAdd an HTTP-to-HTTPS redirect for this Netlify app. Add a Strict-Transport-Security header with max-age=31536000 and includeSubDomains. Set Secure and SameSite=Lax on any auth cookies.
Bolt makes the first deploy feel free. The second deploy is the one that hurts, once real users find your app and the bills come in. Heimdall checks all eight of these issues plus the rest in under a minute, so it's worth running once after your first proper deploy.
