Step-by-Step Guide
8 steps

How to Fix API Key Exposure in Bolt.new Apps

Bolt.new generates code fast, but often places API keys directly in frontend files. If your app has been deployed with exposed keys, attackers can extract them from the JavaScript bundle. This guide walks you through finding, rotating, and properly securing every exposed key.

Find security issues automatically before attackers do.

Follow These Steps

1

Search your codebase for hardcoded keys

Scan all source files for API key patterns. Bolt.new may embed keys in component files, utility functions, or configuration files.

Code Example
grep -rn "sk-\|api_key\|apiKey\|secret_key\|OPENAI\|ANTHROPIC\|STRIPE" src/ --include="*.ts" --include="*.tsx" --include="*.js"
2

Check your git history for previously committed keys

Even if you already removed a key from code, it may still exist in git history.

Code Example
git log --all --full-history -p -- "*.ts" "*.tsx" "*.env" | grep -i "sk-\|api_key\|secret"

If a key was ever committed, consider it compromised and rotate it immediately.

3

Rotate all compromised keys

Go to each API provider dashboard and generate new keys. Deactivate the old keys. Do this before fixing the code.

Code Example
# Common providers to check:
# OpenAI: platform.openai.com/api-keys
# Stripe: dashboard.stripe.com/apikeys
# Anthropic: console.anthropic.com/settings/keys
# Supabase: app.supabase.com/project/_/settings/api
4

Create a .env file and add to .gitignore

Set up environment variables for local development.

Code Example
# Create .env.local
OPENAI_API_KEY=sk-proj-your-new-key
STRIPE_SECRET_KEY=sk-live-your-new-key

# Add to .gitignore (create if it does not exist)
echo ".env*" >> .gitignore
echo "!.env.example" >> .gitignore

# Create .env.example with placeholder values
OPENAI_API_KEY=sk-proj-your-key-here
STRIPE_SECRET_KEY=sk-live-your-key-here
5

Create server-side API routes

Replace direct frontend API calls with server-side routes that access secrets from environment variables.

Code Example
// app/api/ai/route.ts (Next.js)
import { NextResponse } from 'next/server'

export async function POST(req: Request) {
  const { prompt } = await req.json()
  if (!prompt || typeof prompt !== 'string') {
    return NextResponse.json({ error: 'Invalid input' }, { status: 400 })
  }
  
  const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: prompt }]
    })
  })
  
  return NextResponse.json(await response.json())
}
6

Update frontend to use the API route

Change frontend code to call your API route instead of the third-party API directly.

Code Example
// Before (INSECURE)
const res = await fetch('https://api.openai.com/v1/chat/completions', {
  headers: { 'Authorization': 'Bearer sk-proj-EXPOSED' }
})

// After (SECURE)
const res = await fetch('/api/ai', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ prompt: userInput })
})
7

Configure environment variables in your hosting platform

Add the new API keys as environment variables in Vercel, Netlify, or wherever you deploy.

Never use NEXT_PUBLIC_ prefix for secret keys. That prefix makes the variable available in the browser bundle.

8

Scan to verify the fix

Deploy and run a VAS scan to confirm no keys remain in the frontend bundle.

Also check DevTools > Sources > Search for any remaining key patterns.

What You'll Achieve

All exposed API keys are rotated, removed from frontend code, and stored securely in server-side environment variables. API calls are now proxied through server-side routes where secrets are never exposed to browsers.

Common Mistakes to Avoid

Mistake

Using NEXT_PUBLIC_ prefix for secret keys

Fix

NEXT_PUBLIC_ makes the variable available in the browser. Only use it for truly public values. Secret keys must not have this prefix.

Mistake

Forgetting to add .env to .gitignore before committing

Fix

If .env was committed, it is in git history forever. Add .env to .gitignore, then remove with git rm --cached .env, and rotate all keys.

Mistake

Only removing the key from the latest code without rotating

Fix

Once a key has been in code or git history, assume it is compromised. Rotate it at the provider before fixing the code.

Frequently Asked Questions

How do I know if someone has used my exposed key?

Check the usage dashboard of each API provider. Look for unusual spikes in usage, requests from unknown IPs, or unexpected charges. Most providers offer usage monitoring and alerts.

Is it enough to just delete the key from my code?

No. If the key was ever deployed or committed to git, it is compromised. You must generate a new key at the provider and deactivate the old one.

Which keys are safe in frontend code?

Firebase API keys and Supabase anon keys are designed for frontend use. Their security comes from Security Rules and RLS policies respectively. All other API keys should be server-side only.

Ready to Secure Your App?

VAS automatically scans your deployed app for the security issues covered in this guide. Get actionable results in minutes.

Start Security Scan