How to Hide Your API Keys (The Right Way)

Share

TL;DR

Create a .env file for your API keys, add it to .gitignore, and access keys only from server-side code. For production, add keys to your hosting platform's environment settings. Never put secret keys in frontend JavaScript or commit them to GitHub.

API keys are the passwords your app uses to talk to services like Stripe, OpenAI, and Supabase. When they're exposed in your code, attackers can use them to rack up charges on your account or steal your data.

This guide walks through the correct way to handle API keys, step by step. It takes about 10 minutes to set up properly and saves you from potentially expensive mistakes.

Why This Matters

Before we get into the how, let's be clear about the stakes:

  • OpenAI key exposed: Attackers run up thousands in API charges
  • Stripe secret key exposed: Access to customer payment data
  • AWS credentials exposed: Crypto mining on your account ($10K+ bills)
  • Supabase service key exposed: Complete database access bypassing all security

These aren't hypothetical. They happen every day to founders who didn't know any better.

1

Create a .env File

In your project root, create a file called .env (just the extension, no filename):

# .env
OPENAI_API_KEY=sk-proj-abc123xyz789...
STRIPE_SECRET_KEY=sk_live_abc123...
SUPABASE_SERVICE_ROLE_KEY=eyJhbG...
DATABASE_URL=postgresql://user:pass@host/db

Each line has a variable name, an equals sign, and the value. No quotes needed in most cases.

2

Add .env to .gitignore

Open or create a .gitignore file in your project root and add:

# .gitignore
.env
.env.local
.env.*.local
.env.production

This prevents git from tracking your environment files. They'll never be committed or pushed to GitHub.

Already Committed a Key? If you've already committed a .env file, adding it to .gitignore won't remove it from history. You need to rotate that key immediately and consider it compromised.

3

Access Keys from Server-Side Code

The critical rule: secret keys should only be accessed from code that runs on the server. Here's how this looks in different frameworks:

Next.js

// app/api/chat/route.js (Server-side API route)
import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY
});

export async function POST(request) {
  // This runs on the server, key is safe
  const completion = await openai.chat.completions.create({
    model: "gpt-4",
    messages: [...]
  });
  return Response.json(completion);
}

Express.js

// server.js
require('dotenv').config();

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

app.post('/create-payment', async (req, res) => {
  // Server-side, key is safe
  const session = await stripe.checkout.sessions.create({...});
  res.json({ url: session.url });
});
4

Configure Production Environment

Your .env file only works locally. For production, add keys to your hosting platform:

PlatformWhere to Add Keys
VercelProject Settings → Environment Variables
NetlifySite Settings → Environment Variables
RailwayProject → Variables tab
RenderDashboard → Environment
ReplitSecrets (padlock icon in sidebar)

Add the same variable names and values you have in your local .env file. The platform will inject them at runtime.

Common Mistakes to Avoid

Mistake 1: Using NEXT_PUBLIC_ for Secret Keys

In Next.js, variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Never use this prefix for secret keys:

# BAD - This is visible to anyone
NEXT_PUBLIC_OPENAI_KEY=sk-proj-abc123...

# GOOD - This stays server-side
OPENAI_API_KEY=sk-proj-abc123...

Mistake 2: Calling Secret APIs from the Frontend

You cannot safely use secret keys in React components, even with environment variables:

// BAD - This runs in the browser
function ChatComponent() {
  const response = await fetch('https://api.openai.com/v1/chat', {
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_KEY}`
    }
  });
}

// GOOD - Call your own API route instead
function ChatComponent() {
  const response = await fetch('/api/chat', {
    method: 'POST',
    body: JSON.stringify({ message })
  });
}

Mistake 3: Hardcoding Keys "Just for Testing"

It's tempting to hardcode a key to test quickly. Don't. Set up environment variables from the start:

// BAD - "I'll remove it later" (you won't)
const apiKey = "sk-proj-abc123...";

// GOOD - Always use environment variables
const apiKey = process.env.OPENAI_API_KEY;

How to Verify Your Keys Are Hidden

  1. Deploy your app to production
  2. Open browser dev tools (F12)
  3. Go to the Network tab and look at request headers
  4. Search in the Sources tab for your key value
  5. Run a security scan to catch what you might miss

If you can find your secret keys through any of these methods, they're exposed and need to be fixed.

API Key Security Checklist

  • Created .env file for local development
  • Added .env to .gitignore
  • Secret keys accessed only from server-side code
  • No NEXT_PUBLIC_ prefix on secret keys
  • Production keys added to hosting platform
  • No hardcoded keys anywhere in codebase
  • Verified keys not visible in browser dev tools

What is the right way to hide API keys?

Store API keys in environment variables, not in your code. Create a .env file for local development, add it to .gitignore so it's never committed, and add the keys to your hosting platform's environment settings for production. Access the keys from server-side code only, never from frontend JavaScript.

Can I put API keys in frontend JavaScript?

No. Any code that runs in the browser can be viewed by users. If you put an API key in React, Vue, or vanilla JavaScript, anyone can find it by opening browser developer tools. API calls requiring secret keys must go through your backend server.

What is a .env file?

A .env file is a simple text file that stores environment variables as key-value pairs. It keeps sensitive values like API keys separate from your code. The file should never be committed to version control and should be listed in your .gitignore file.

What if I already committed my API keys?

Consider those keys compromised. Immediately rotate them by generating new keys in the service's dashboard and revoking the old ones. Then update your code to use environment variables properly. Adding .env to .gitignore won't remove keys from git history.

Check If Your Keys Are Exposed

Run a free security scan to find exposed API keys and other vulnerabilities.

Start Free Scan
How-To Guides

How to Hide Your API Keys (The Right Way)