Secrets Management
Principles
- Never commit secrets — use
.gitignorereligiously - Rotate regularly — especially after any leak suspicion
- Least privilege — each service only gets the keys it needs
- Validate at startup — fail fast if a required key is missing
- Redact in logs — never log full key values
Julia's Secret Inventory
# .env.secrets (never committed)
OPENAI_API_KEY=sk-... # orchestrator + frontend
ANTHROPIC_API_KEY=sk-ant-... # cowork-mcp
TELEGRAM_BOT_TOKEN=... # openclaw
RAPHAEL_CHAT_ID=... # escalation target
DATABASE_URL=postgresql://... # backend (Docker internal)
Startup Validation
const REQUIRED_VARS = ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY'];
for (const key of REQUIRED_VARS) {
if (!process.env[key]) {
console.error(`FATAL: Missing required env var: ${key}`);
process.exit(1);
}
}
Git Protection
# .gitignore — MUST contain:
.env.secrets
.env.local
*.key
*.pem
If a Secret is Leaked
- Immediately rotate the key (generate new one in provider dashboard)
- Update
.env.secretswith new value - Restart affected services:
pm2 restart all - Audit git history:
git log --all -S "old-key-prefix" - If committed: use
git filter-repoto scrub history
Credential Rotation Schedule
- API keys: every 90 days or on team member change
- DB passwords: every 180 days
- Telegram tokens: rotate if bot was ever exposed