How to Hide API Keys
The essential guide to keeping your secrets out of your code
TL;DR
TL;DR: Move all API keys to environment variables stored in .env files. Add .env to your .gitignore immediately. In production, use your hosting platform's secret management (Vercel, Netlify, Railway all have built-in tools). Never put secret keys in frontend code.
Why This Matters
Exposed API keys are the most common security issue in vibe-coded apps. According to GitGuardian, over 10 million secrets were exposed in public GitHub repos in 2023 alone. When AI generates code, it often hardcodes example keys or uses placeholder values that you might forget to remove.
The consequences can be severe: compromised Stripe keys can drain your bank account, exposed OpenAI keys can rack up thousands in charges, and leaked database credentials can expose all your user data.
Step-by-Step Guide
Identify all your API keys
Search your codebase for hardcoded secrets:
# Search for common key patterns
grep -r "sk_live\|sk_test\|api_key\|apiKey\|API_KEY" --include="*.ts" --include="*.js" --include="*.tsx"
# Search for specific services
grep -r "OPENAI\|STRIPE\|SUPABASE\|FIREBASE" --include="*.ts" --include="*.js"
Look for anything that looks like a key: long random strings, keys starting with sk_, pk_, or containing secret.
Create a .env.local file
In your project root, create a .env.local file:
# .env.local - Never commit this file!
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# Stripe (secret key - server only)
STRIPE_SECRET_KEY=sk_test_51xxxxx
# OpenAI
OPENAI_API_KEY=sk-xxxxx
# Supabase (these are safe for client)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxxx
Add .env files to .gitignore
Open or create .gitignore and add these lines:
# Environment files - NEVER commit these
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.env.production
# Keep the example file for documentation
!.env.example
Run this to make sure .env files aren't already tracked:
git rm --cached .env .env.local 2>/dev/null || true
Create an example file for documentation
Create .env.example with placeholder values (this file IS safe to commit):
# .env.example - Copy to .env.local and fill in real values
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
STRIPE_SECRET_KEY=sk_test_your_key_here
OPENAI_API_KEY=sk-your_key_here
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_here
Update your code to use environment variables
Replace hardcoded keys with process.env:
// BEFORE - Hardcoded (dangerous!)
const stripe = new Stripe('sk_test_51xxxxx');
// AFTER - Using environment variable (safe)
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// Add validation to catch missing keys early
if (!process.env.STRIPE_SECRET_KEY) {
throw new Error('Missing STRIPE_SECRET_KEY environment variable');
}
Configure production secrets in your hosting platform
Never deploy .env files to production. Instead, configure secrets in your platform:
- Vercel: Project Settings → Environment Variables
- Netlify: Site Settings → Environment Variables
- Railway: Service → Variables
- Render: Service → Environment
- Cloudflare Pages: Settings → Environment Variables
Important: Public vs Private Keys
In Next.js, only variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Secret keys should NEVER have this prefix:
# WRONG - This exposes the secret to everyone
NEXT_PUBLIC_STRIPE_SECRET=sk_live_xxxxx
# CORRECT - This stays server-side only
STRIPE_SECRET_KEY=sk_live_xxxxx
# CORRECT - Public key, safe for browser
NEXT_PUBLIC_STRIPE_PUBLISHABLE=pk_live_xxxxx
How to Verify Your Keys Are Hidden
- Check your git status: Run
git statusand make sure no .env files appear - Search your bundle: Build your app, then search the output for key patterns
- Check network requests: Open DevTools Network tab and look for keys in requests
- View page source: Search for keys in your compiled HTML/JS
# Search built files for leaked keys
grep -r "sk_live\|sk_test" .next/ dist/ build/ 2>/dev/null
Pro Tip: Use a tool like CheckYourVibe to automatically scan your codebase for exposed secrets before every deploy.
What if I already committed a key to git?
Assume it's compromised. Immediately rotate the key in the service's dashboard, then update your environment variables. Don't waste time trying to remove it from git history; the key should be considered public.
Are Supabase anon keys safe to expose?
Yes, Supabase anon keys are designed to be public. They only work with Row Level Security policies, which is why RLS is so important. The service_role key, however, must stay secret.
Can I use the same .env file for development and production?
You shouldn't. Use .env.local for development with test keys, and configure separate production secrets in your hosting platform. This prevents accidentally using test data in production.
Related guides:How to Rotate API Keys · How to Check for Exposed Keys · How to Use Environment Variables