SEC-002 recommended Secret Storage
Secrets Loaded into Process Environment
Secrets injected into process environment at startup, not read from files at runtime
Question to ask
"Would a crash dump expose any credentials?"
What to check
- ☐ Application reads from process.env / os.environ
- ☐ Centralized config with env validation at startup
- ☐ Deployment passes env vars (not files)
- ☐ dotenv only used for local development
Pass criteria
- ✓ Application reads secrets via environment variables
- ✓ Secrets injected at deploy time (not read from files)
- ✓ Centralized config validates required env vars at startup
- ✓ dotenv dev-only, not used in production
Related items
Verification guide
Severity: Critical
Secrets should be injected into the process environment at startup, not read from files at runtime. The application reads from process.env / os.environ / equivalent.
Check automatically:
- Check application reads from environment variables:
# Node.js - process.env usage
grep -rE "process\.env\." src/ lib/ app/ --include="*.ts" --include="*.js" 2>/dev/null | head -20
# Python - os.environ or os.getenv
grep -rE "os\.environ|os\.getenv" src/ app/ --include="*.py" 2>/dev/null | head -20
# Go - os.Getenv
grep -rE "os\.Getenv" . --include="*.go" 2>/dev/null | head -20
- Check for proper config patterns (centralized config loading):
# Config file that loads from env
ls -la src/config* lib/config* app/config* config/ 2>/dev/null
# Environment validation at startup (good pattern)
grep -rE "required.*env|validateEnv|envalid|zod.*env|env-var" src/ lib/ 2>/dev/null
- Check deployment passes env vars (not files):
# Kubernetes env injection
grep -rE "env:|envFrom:" k8s/ kubernetes/ manifests/ 2>/dev/null
# Docker Compose environment
grep -rE "environment:" docker-compose*.yml 2>/dev/null
# Systemd service (should use Environment= or EnvironmentFile=)
grep -rE "Environment=|EnvironmentFile=" *.service 2>/dev/null
- Check for anti-patterns (reading secrets from files at runtime):
# Reading .env files in production code (anti-pattern)
grep -rE "dotenv\.config|load_dotenv|godotenv" src/ lib/ app/ 2>/dev/null
# Direct file reads for secrets
grep -rE "readFileSync.*secret|readFile.*key\.pem|readFile.*\.env" src/ lib/ 2>/dev/null
Ask user:
- "Does your app read secrets from environment variables or config files?"
- "Is dotenv/similar used in production?" (acceptable for local dev only)
Cross-reference with:
- SEC-001 (secret manager - source of the env vars)
- SEC-003 (not stored on filesystem)
- ENV-002 (environment tiers)
Pass criteria:
- Application reads secrets via
process.env/os.environ/ equivalent - Secrets injected into environment at deploy time (not read from files)
- Centralized config pattern validates required env vars at startup
- dotenv only used for local development, not production
Fail criteria:
- Secrets read from filesystem in production
- No environment variable usage - hardcoded or file-based
- dotenv used in production to load
.envfiles from disk
Evidence to capture:
- How secrets reach the process (env injection method)
- Config pattern used (centralized validation or scattered)
- Whether dotenv is dev-only or also used in prod