Secret management
Hierarchy
Section titled “Hierarchy”┌──────────────────────────────────────────────┐│ Google Secret Manager (runtime, per-env) │ ← servers read from here└──────────────────┬───────────────────────────┘ │ mirrored for human use ▼┌──────────────────────────────────────────────┐│ 1Password vaults │ ← humans read from here│ - TapPass — Engineering (shared eng) ││ - TapPass — Ops (prod secrets) ││ - TapPass — GTM (Stripe, commercial) │└──────────────────────────────────────────────┘- Commit secrets to git, even in private repos
- Paste secrets in Slack (use 1Password shared items)
- Share secrets over email
- Screenshot secrets
- Put secrets in Linear, PR descriptions, or ADRs
- Log secrets (the core server has a
SecretFilterlog processor — keep it on)
Always
Section titled “Always”- Use 1Password for human access
- Use Secret Manager for runtime access
- Rotate on suspicion
- Revoke immediately on employee offboarding
- Prefer least-privilege scoped tokens over root keys
Secret types and lifecycle
Section titled “Secret types and lifecycle”| Type | Storage | Rotation |
|---|---|---|
| Provider API keys (OpenAI, Anthropic, etc.) | Secret Manager (prod, staging separately) | 90 days |
| Postgres credentials | Secret Manager + IAM auth | Quarterly |
| Audit signing key (Ed25519) | Secret Manager, versioned | Do not rotate casually — breaks hash chain |
| JWT signing key | Secret Manager | 180 days |
| Cloudflare API tokens | 1Password (Ops vault) | 180 days |
| GitHub fine-grained PATs | 1Password (Engineering vault) | 90 days |
| Employee SSH keys | Local device + GitHub | Yearly |
| Employee GPG keys (commit signing) | Local device | Yearly |
Rotation procedure
Section titled “Rotation procedure”Documented per-key in Rotate API keys.
Secret scanning
Section titled “Secret scanning”gitleaks pre-commitenabled in every repo- GitHub secret scanning enabled at org level
- On a positive hit: rotate the secret immediately, force-push history cleanup only if absolutely necessary (usually a rotation is enough)
Developer secrets
Section titled “Developer secrets”Local dev uses .env files with fake values, loaded via op run for real values:
op run --env-file=.env.1password -- make devThe .env.1password file references 1Password items by URI:
OPENAI_API_KEY=op://Engineering/openai-dev/credentialANTHROPIC_API_KEY=op://Engineering/anthropic-dev/credentialCommit the .env.1password file (it’s just references). Never commit .env.