principlejavascriptCritical
Secrets in Environment Variables: Never Hard-Code
Viewed 0 times
secretsenvironment variablesdotenvapi keyhard-codedgit historysecrets manager
Problem
Hard-coded secrets (API keys, database passwords, JWT secrets) committed to version control are permanently exposed—even after deletion, they remain in git history.
Solution
Load all secrets from environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler). Use dotenv for local development only, and add .env to .gitignore.
Why
Environment variables are injected at runtime and never appear in source code. If a repository is ever made public or accessed by an unauthorised party, no secrets are exposed.
Gotchas
- dotenv .env files can still be committed by accident—add a pre-commit hook to detect them
- Process environment variables are visible to all processes on the same host—use a secrets manager for highly sensitive values
- Logging req.env or process.env in error handlers can expose secrets in logs
- Build-time environment variables baked into client-side bundles (e.g., NEXT_PUBLIC_*) are public—never put secrets there
Code Snippets
Validate required secrets at startup
// config.js — fail fast if secrets are missing
const required = ['DATABASE_URL', 'JWT_SECRET', 'STRIPE_SECRET_KEY'];
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing required environment variable: ${key}`);
}
}
module.exports = {
databaseUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET,
stripeKey: process.env.STRIPE_SECRET_KEY
};
// .gitignore
// .env
// .env.local
// .env.*.localRevisions (0)
No revisions yet.