Secrets Management for SaaS Teams
Secrets management is one of the most consistently mishandled areas in SaaS engineering. The typical pattern: secrets start in a .env file, get committed to git accidentally, get shared in Slack DMs, accumulate in team members' local environments, and never get rotated. Then someone leaves the company and you do not know which credentials they had access to.
This reference covers the full secrets management stack: what counts as a secret, the environments it must be managed across, the tools available at each stage of growth, and the operational practices that keep secrets out of the wrong hands.
🔑 What Counts as a Secret
A secret is any value that grants access to a resource and must not be exposed publicly. The definition is broader than most teams realize.
| Category | Examples | Risk if Exposed |
|---|---|---|
| Database credentials | Connection strings, usernames, passwords | Full data access; data breach |
| Third-party API keys | Stripe, Twilio, SendGrid, OpenAI keys | Unauthorized charges; data access; account lockout |
| Auth secrets | JWT signing keys, session secrets, OAuth client secrets | Session hijacking; auth bypass |
| Encryption keys | AES keys, RSA private keys, KMS key ARNs | Data decryption; compliance violation |
| Internal service tokens | Webhook signing secrets, internal API tokens | Service impersonation; data manipulation |
| Infrastructure credentials | AWS access keys, GCP service account keys, SSH private keys | Full infrastructure access; worst-case scenario |
🏗 Secrets by Environment
Every secret must be managed separately per environment. Using the same secret in development and production is a security control failure — if development is compromised, production is compromised too.
Environment isolation rules:
- → Development — use fake or sandboxed credentials wherever possible. Stripe test keys, dummy database, mock external services. Real secrets never in developer laptops.
- → Staging — separate credentials from production. Staging secrets should be revokable independently. Staging should not have access to production data.
- → Production — secrets injected at runtime only. Never stored in code, config files, or Docker images. Access to production secrets is restricted to production infrastructure roles and on-call engineers.
- → CI/CD — separate secret set for your pipeline. CI secrets give access to deploy, not to run the application. Principle of least privilege applies strictly.
🛠 Secrets Management Tools by Stage
Choose your secrets management tool based on your current team size and infrastructure, not your target architecture.
| Stage | Recommended Tool | Why |
|---|---|---|
| Pre-seed / Solo | Doppler, Railway env vars, Vercel env | Zero infrastructure; works with existing hosting |
| Seed (2–10 engineers) | Doppler, 1Password Secrets Automation, AWS Secrets Manager | Team access controls; audit log; rotation support |
| Series A+ (10+ engineers) | HashiCorp Vault, AWS Secrets Manager + KMS | Fine-grained access policies; dynamic secrets; compliance-grade audit trail |
What to avoid at any stage:
- → Secrets in
.envfiles committed to git (even private repos — they surface in git history and forks) - → Secrets shared in Slack, email, or tickets — use a secrets manager with direct injection instead
- → Secrets hardcoded in application code or Docker images
- → Shared credentials with no individual accountability (one key used by the whole team)
🔄 Secrets Rotation
Secrets rotation is the practice of replacing a secret with a new value on a regular schedule or after a security event. Most SaaS teams do not rotate secrets until something goes wrong — which means they are always reacting, never preventing.
Rotation triggers that require immediate action:
- → A team member with production access leaves the company
- → A secret is accidentally committed to a git repository (even for 1 minute)
- → A secret appears in a log file, error message, or support ticket
- → A third-party service you use reports a breach
- → Any CI/CD system is compromised or replaced
Rotation schedule by secret type:
- → Infrastructure credentials (AWS keys, GCP service accounts): rotate every 90 days minimum
- → Third-party API keys: rotate annually or when a team member with access departs
- → Database passwords: rotate at each major infrastructure change; automate with AWS Secrets Manager or Vault for zero-downtime rotation
- → JWT signing keys: rotate annually; implement key ID versioning so existing tokens remain valid during the transition window
📋 Access Control and Audit
Secrets access should follow the principle of least privilege: each service, each person, and each script gets access only to the secrets it needs to do its specific job — nothing more.
Access control checklist:
- → Production secrets are not accessible on developer laptops
- → Each service has its own credentials — no shared secrets across services
- → Access to production secrets requires a specific IAM role or team membership, not just being in the engineering Slack
- → Every access to a production secret is logged with actor, timestamp, and secret identifier
- → Offboarding procedure includes a secrets audit: which credentials did the departing person have, and which need rotation
What to Do Next
Audit your current secrets posture this week: search your git history for common secret patterns (grep -rn "AKIA" . for AWS keys, grep -rn "sk_live" . for Stripe keys). If any are found, rotate them immediately before doing anything else. Then: pick a secrets manager appropriate for your stage and migrate your highest-risk production secrets this sprint.