Step-by-Step Guide
6 steps

How to Fix API Key Exposure in Netlify Apps

Netlify apps may expose API keys through hardcoded values in frontend code or secrets stored in netlify.toml (which is committed to git). This guide helps you find, rotate, and properly secure exposed keys using Netlify environment variables.

Find security issues automatically before attackers do.

Follow These Steps

1

Search for exposed secrets

Check both source code and configuration files.

Code Example
grep -rn "sk-\|api_key\|apiKey\|secret" src/ netlify.toml --include="*.ts" --include="*.js" --include="*.toml"
2

Check netlify.toml for secrets

The netlify.toml file is committed to git and should never contain secret values.

Code Example
# BAD - secrets in netlify.toml (committed to git)
[build.environment]
  OPENAI_API_KEY = "sk-proj-secret"

# GOOD - only non-secret config in netlify.toml
[build.environment]
  NODE_VERSION = "20"
3

Rotate compromised keys and add to Netlify dashboard

Generate new keys at each provider, then add them in the Netlify dashboard under Site settings > Environment variables.

Mark variables as "Secret" to prevent them from appearing in build and function logs.

4

Use Netlify Functions for sensitive API calls

Move API calls that require secrets to Netlify Functions.

Code Example
// netlify/functions/api-proxy.ts
import { Handler } from '@netlify/functions'

export const handler: Handler = async (event) => {
  const apiKey = process.env.OPENAI_API_KEY
  const body = JSON.parse(event.body || '{}')
  
  const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  })
  
  return {
    statusCode: 200,
    body: JSON.stringify(await response.json())
  }
}
5

Update frontend to call Netlify Functions

Replace direct API calls with calls to your serverless functions.

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

// After (SECURE)
fetch('/.netlify/functions/api-proxy', {
  method: 'POST',
  body: JSON.stringify({ prompt: userInput })
})
6

Deploy and verify

Deploy and run a VAS scan to confirm no secrets are in the frontend bundle.

What You'll Achieve

All secrets are removed from netlify.toml and source code, stored in Netlify environment variables, and accessed only through Netlify Functions. Your frontend bundle contains no sensitive credentials.

Common Mistakes to Avoid

Mistake

Putting secrets in netlify.toml build environment

Fix

netlify.toml is committed to git. Use the Netlify dashboard for secrets instead.

Mistake

Using VITE_ or NEXT_PUBLIC_ prefix for secrets in Netlify

Fix

These prefixes embed variables in the client bundle. Use unprefixed names and access them only in Netlify Functions.

Frequently Asked Questions

Are Netlify environment variables secure?

Yes. Variables set in the Netlify dashboard are encrypted and only available at build time and in serverless functions. They are not embedded in static site output unless your framework exposes them.

Can I use different secrets for deploy previews?

Yes. Netlify lets you scope environment variables to different deploy contexts (production, deploy previews, branch deploys). Use test keys for previews.

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