ADR-011: Secrets Management Strategy
Status: Accepted
Date: 2026-02-28
Note (2026-10-10): deployed secrets are stored in AWS Systems Manager Parameter Store (SecureString) and read by the deploy script; see ADR-021.
Context
The platform requires secure handling of sensitive credentials across multiple services (Sentry, GitHub Actions) and deployment environments (dev/prod). Security requirements (NFR-001, NFR-002) mandate strict protection of API keys, database credentials, JWT secrets, and integration tokens.
Constraints:
- Must maintain $0 cost for secrets infrastructure
- Cannot rely on paid secret management services
- Must support environment isolation (dev/prod)
- Must prevent accidental exposure through source control or logs
- Must align with existing $0-cost infrastructure stack
Key Requirements:
- Secure storage and retrieval of credentials without additional cost
- Environment-specific secret scoping
- Audit trail for secret access (where feasible)
- Protection against common attack vectors (XSS, repository scanning, log exposure)
- Support for secret rotation without code changes
Decision
Adopt a layered, zero-cost secrets management strategy using platform-native capabilities:
1. Environment Variables via Docker Compose (Local Development)
- Use
.envfiles (git-ignored) with Docker Composeenv_filedirective - Template file
.env.exampletracked in repo with placeholder values - Developers maintain local
.envwith actual credentials
2. GitHub Actions Encrypted Secrets (CI/CD)
- All CI/CD secrets stored in GitHub repository/environment secrets (free tier)
- Environment-specific secrets for dev/staging/prod
- Access controlled via GitHub permissions model
3. Application Runtime Secret Injection
- Backend: Environment variables injected at container runtime (Docker, cloud provider)
- Frontend: Build-time injection for public variables, runtime API calls for sensitive operations
- No secrets embedded in built artifacts or client bundles
4. Secret Access Controls
- Prohibited: Secrets in git commits, source code, client-side bundles, unencrypted config files
- Required:
.gitignoreentries for all secret files, pre-commit hooks to scan for leaked secrets - Rotation: Documented procedures for credential rotation without downtime
Scope note: this ADR covers platform secrets — credentials the application itself holds, and how they reach the runtime. It does not cover encrypting sensitive application data at rest. Field-level encryption of user-supplied AI provider keys is decided in ADR-018: User API Key Encryption at Rest, which works within the $0-cost constraint set here.
Consequences
Positive:
- Zero infrastructure cost — no paid secret vaults or KMS services
- Platform-native — leverages built-in capabilities of GitHub, Docker
- Environment isolation — clear separation between dev/staging/prod secrets
- Reduced attack surface — secrets never committed to source control
- Developer experience — simple
.envworkflow for local development - Audit trail — GitHub Actions secret access logged
Negative:
- Distributed storage — secrets managed across multiple platforms (GitHub, local files)
- Manual rotation — no automated rotation; requires coordinated manual updates
- Limited auditability — local
.envaccess not centrally logged - Onboarding overhead — new developers must manually configure
.envfiles - No centralized policy enforcement — secret policies managed per-platform
Risks:
- Developer error: Accidental commit of
.envfiles or hardcoded secrets- Mitigation: Pre-commit hooks (e.g.,
gitleaks,git-secrets), CI checks,.gitignoreenforcement
- Mitigation: Pre-commit hooks (e.g.,
- Secret sprawl: Difficult to inventory all secrets across environments
- Mitigation: Maintain documented secret inventory in runbook
- Rotation complexity: Coordinating updates across dev machines, GitHub
- Mitigation: Documented rotation runbooks with step-by-step procedures
Alternatives Considered
1. HashiCorp Vault (Self-Hosted Free Tier)
- Requires dedicated infrastructure (server, storage, backups)
- Operational overhead (upgrades, monitoring, HA setup)
- Violates $0 cost constraint (compute/storage costs)
2. Encrypted Files in Repository (e.g., git-crypt, sops)
- Key distribution problem (how to share decryption keys securely)
- Higher risk of accidental exposure of encrypted files + keys
- Requires tooling setup for all developers
- Poor audit trail for secret access