Hardcoded credentials in source code (CWE-798) or committed .env files (CWE-312) expose API keys, database passwords, and service tokens to every person with repository access — and to public GitHub if the repo is ever made public or forked. OWASP A07 (Identification and Authentication Failures) and NIST IA-5 both classify hardcoded credentials as a critical authentication control failure. PCI DSS v4.0 Req-8.6.2 explicitly prohibits hardcoded passwords/passphrases in scripts, configuration/property files, and bespoke source code. Unlike most vulnerabilities, secrets in git history persist even after the secret is removed from the current codebase — they require key rotation, not just file deletion.
Info in this bundle context because other patterns cover active secret exposure; this pattern focuses on the secrets management hygiene baseline rather than a detected active leak.
Store all secrets in environment variables and exclude .env files from version control. Create .env.example as a committed template with placeholder values.
# .env.example — commit this; never commit .env
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
STRIPE_SECRET_KEY=sk_test_REPLACE_ME
SENTRY_DSN=https://REPLACE_ME@sentry.io/123
Add to .gitignore:
.env
.env.local
.env.*.local
If secrets were ever committed, rotate them immediately — do not rely on git rm alone, as the values remain in history. Use git filter-repo to scrub history, then force-push. For production secret management: Vercel Dashboard → Settings → Environment Variables; AWS Systems Manager Parameter Store; or HashiCorp Vault for self-hosted.
ID: deployment-readiness.environment-configuration.secrets-management
Severity: info
What to look for: Enumerate every relevant item. Check for .env.example or similar template file (without actual values). Look for secrets management in code: environment variable usage, AWS Secrets Manager integration, HashiCorp Vault, or similar. Verify .gitignore excludes .env, .env.local, or similar files. Check git history for any committed secrets.
Pass criteria: At least 1 of the following conditions is met. Secrets are stored in environment variables or a secrets manager. No credentials are committed to version control. A .env.example exists as a template.
Fail criteria: Secrets are hardcoded in source code or config files, or committed to git history. No .env.example template.
Skip (N/A) when: The project has no secrets or external service dependencies.
Detail on fail: "API keys hardcoded in config files. No .env.example template found." or "AWS credentials committed to git history (possibly already rotated)."
Remediation: Use environment variables. Create .env.example:
# .env.example (commit this to git)
DATABASE_URL=postgres://user:pass@localhost:5432/db
API_KEY=your_api_key_here
SENTRY_DSN=https://xxx@sentry.io/123
Then add to .gitignore:
.env
.env.local
.env.*.local
In your app, use process.env:
const apiKey = process.env.API_KEY; // Never commit the real value
Use your platform's secrets manager for deployment: