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 Secret | Example | What It Unlocks |
|---|---|---|
| API key | sk_live_abc123def456 | Access to a third-party service (Stripe, SendGrid, OpenAI, etc.) |
| Database password | MyDB_P@ssw0rd! | Access to your database |
| Auth secret | JWT_SECRET=mysecretkey | Ability to forge authentication tokens |
| Encryption key | Encryption key for user data | Ability to decrypt sensitive data |
| OAuth token | gho_abc123def456 | Access to GitHub, Google, or other APIs |
| SSL private key | Private key for your domain | Ability 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:
| Platform | How to Store Secrets |
|---|---|
| Vercel | Environment Variables in project settings |
| Railway | Environment Variables in service settings |
| Render | Environment Variables in service settings |
| Heroku | Config Vars in app settings |
| Netlify | Environment Variables in site settings |
| Cloudflare Pages | Environment Variables in project settings |
| AWS | Secrets Manager or Parameter Store |
| DigitalOcean | App 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
| Tool | What It Does | Free Tier |
|---|---|---|
| GitGuardian | Scans repos for exposed secrets | Yes |
| TruffleHog | Scans Git history for secrets | Open source |
| SecretScanner | Finds secrets in code and files | Open 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
-
.envis in.gitignore -
.env.exampleis 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.