Skip to main content

API Keys and Secrets

Every app that connects to external services uses secrets — API keys, database passwords, authentication tokens, encryption keys.

How you handle these secrets is one of the most important security decisions you'll make.


What Are Secrets?

Secrets are pieces of sensitive information that grant access to your systems:

Type of SecretExampleWhat It Unlocks
API keysk_live_abc123def456Access to a third-party service (Stripe, SendGrid, OpenAI, etc.)
Database passwordMyDB_P@ssw0rd!Access to your database
Auth secretJWT_SECRET=mysecretkeyAbility to forge authentication tokens
Encryption keyEncryption key for user dataAbility to decrypt sensitive data
OAuth tokengho_abc123def456Access to GitHub, Google, or other APIs
SSL private keyPrivate key for your domainAbility to impersonate your website

The Problem: AI Puts Secrets in the Wrong Places

When you ask AI to connect your app to a service, it often puts the secret directly into the code. This is the simplest way to make it work — and the most dangerous.

What AI-Generated Code Often Looks Like

// DANGEROUS: Secret hardcoded in code
const stripe = require('stripe')('sk_live_abc123def456');

const db = mysql.createConnection({
host: 'localhost',
user: 'admin',
password: 'MyDB_P@ssw0rd!',
database: 'myapp'
});

const API_KEY = 'sk-test-12345';

This code works. But anyone who can see your code can see your secrets.

What Safe Code Looks Like

// SAFE: Secret loaded from environment variable
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const db = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});

const API_KEY = process.env.API_KEY;

What Can Go Wrong

Scenario 1: You Push Code to GitHub

You build your app, it works, you push it to GitHub. If your secrets are in the code, they're now public (or visible to anyone on your team).

Within hours, automated bots scan GitHub for exposed secrets. They find your Stripe API key and start using it.

Result: Thousands of dollars in fraudulent charges on your account.

Scenario 2: Someone Views Your Frontend Code

If your API key is in frontend JavaScript, anyone can see it by viewing your page source or opening browser developer tools.

Result: Anyone can use your API key to access the service — and you get billed.

Scenario 3: A Developer Leaves Your Team

If database passwords are in the code, every developer who ever had access to your codebase still has your production database password.

Result: You can't revoke access without changing the password and updating every deployment.


How to Handle Secrets Safely

1. Use Environment Variables

Environment variables are values set outside your code, in the environment where your app runs.

In your code:

const apiKey = process.env.STRIPE_API_KEY;

In your deployment environment:

# Set on your server or hosting platform
STRIPE_API_KEY=sk_live_abc123def456

In development: Create a .env file (which is listed in .gitignore so it's never committed):

STRIPE_API_KEY=sk_test_abc123def456
DB_PASSWORD=local_dev_password

2. Use a .env.example File

Create a file called .env.example that shows what environment variables are needed, but without the actual values:

# .env.example — copy this to .env and fill in your values
STRIPE_API_KEY=sk_test_your_key_here
DB_PASSWORD=your_db_password_here
JWT_SECRET=your_jwt_secret_here

Commit this file to GitHub. It documents what secrets are needed without exposing them.

3. Add .env to .gitignore

Make sure your .env file is in .gitignore so it's never committed to version control:

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

4. Use Your Hosting Platform's Secret Management

Most hosting platforms have built-in secret management:

PlatformHow to Store Secrets
VercelEnvironment Variables in project settings
RailwayEnvironment Variables in service settings
RenderEnvironment Variables in service settings
HerokuConfig Vars in app settings
NetlifyEnvironment Variables in site settings
Cloudflare PagesEnvironment Variables in project settings
AWSSecrets Manager or Parameter Store
DigitalOceanApp Platform environment variables

5. Rotate Secrets Regularly

  • Change database passwords every 90 days
  • Rotate API keys if you suspect they've been exposed
  • Use different keys for development and production
  • Immediately rotate any secret that was accidentally committed to code

How to Check for Exposed Secrets

Before You Commit Code

Search your codebase for common secret patterns:

# Search for things that look like API keys
grep -r "sk_live_" --include="*.js" --include="*.py" --include="*.ts"
grep -r "api_key" --include="*.js" --include="*.py" --include="*.ts"
grep -r "password" --include="*.js" --include="*.py" --include="*.ts"

Use Automated Tools

ToolWhat It DoesFree Tier
GitGuardianScans repos for exposed secretsYes
TruffleHogScans Git history for secretsOpen source
SecretScannerFinds secrets in code and filesOpen source

What to Ask Your AI

When asking AI to integrate a service, add this to your prompt:

Security requirement: All API keys, database passwords, and secrets must be loaded from
environment variables using process.env or equivalent. Never hardcode secrets in the code.
Create a .env.example file showing required variables without actual values.

The Secrets Checklist

  • All secrets are in environment variables, not in code
  • .env is in .gitignore
  • .env.example is committed to the repo
  • Different secrets are used for development and production
  • Secrets are stored in your hosting platform's secret management
  • No secrets are visible in frontend code
  • Secrets are rotated regularly
  • Exposed secrets can be revoked and replaced
  • Team members have only the secrets they need
  • Automated scanning is set up to catch exposed secrets

The Bottom Line

A secret in your code is not a secret.

Environment variables, secret management tools, and proper .gitignore configuration are not optional. They are the minimum standard for running a professional application.

AI will put secrets in your code unless you explicitly tell it not to. Make "use environment variables" a standard part of every prompt you write.