Context
As the number of external service integrations grows beyond the current minimal set (Cloudflare Pages/Images, Terraform Cloud), secret management complexity increases proportionally. Each integration requires API keys, and following the principle of least privilege means each subsystem should have appropriately scoped credentials rather than a single god-mode token.
Currently, GitHub Secrets (ADR 018) handles secret management well for CI/CD pipelines. However, as integrations expand, several challenges emerge:
- Secret Sprawl: Managing dozens of scoped API keys across multiple environments becomes cumbersome in GitHub's UI
- Local Development: Developers need access to secrets locally without copying them into
.envfiles (which risk accidental commits) - Secret Rotation: Updating a rotated credential requires manual updates across multiple GitHub repositories/environments
- Audit Trail: Limited visibility into what secrets were changed and when
- Cross-Platform Sync: Secrets may need to be shared across CI/CD systems, local development, and cloud functions
Doppler is a specialized secret management platform designed for developers, offering centralized secret storage with excellent DX.
Decision
I propose using Doppler for centralized secret management, while maintaining GitHub Secrets for the "Secret Zero" problem.
Implementation Strategy
- Doppler as Source of Truth: All application secrets (API keys, database credentials, etc.) are stored in Doppler with appropriate environment scoping (development, staging, production)
- GitHub Secrets for Bootstrap: A single
DOPPLER_TOKENis stored in GitHub Secrets to authenticate GitHub Actions to Doppler - Scoped Access: Within Doppler, create separate service tokens for different subsections of the system (e.g., separate tokens for Cloudflare Workers vs. Pages vs. Images) following the principle of least privilege
- Local Development: Use the Doppler CLI to inject secrets into local development sessions without storing them on disk
This approach aligns with:
- Minimize Platforms: While adding a platform, it consolidates secret management that would otherwise sprawl across multiple dashboards
- Fast Feedback Loops: Standardizes how sensitive configuration is handled across all environments, preventing credential management from becoming a friction point that slows down development or integration testing
The "Secret Zero" Problem
The Secret Zero Problem (also called the "Bootstrap Secret Problem") is the fundamental challenge that you need a secret to access your secrets vault. Doppler doesn't eliminate this problem—it shifts it:
- GitHub Actions needs a
DOPPLER_TOKENto authenticate to Doppler - This bootstrap token must be stored somewhere (GitHub Secrets)
- If GitHub is compromised, the attacker gains access to Doppler
This is why Doppler complements GitHub Secrets rather than fully replacing it. GitHub's native integration provides the trust anchor, while Doppler handles the complexity of managing dozens of application secrets.
Alternatives Considered
GitHub Secrets (Current Approach)
- Pros: Native platform integration, solves Secret Zero by being the identity provider itself, supports OIDC for keyless authentication
- Cons: Limited visibility once saved, poor UX for managing many secrets, no local development story, manual rotation process
- Decision: Keep for Secret Zero, use alongside Doppler
HashiCorp Vault
- Pros: Enterprise-grade, extremely powerful policy engine, supports dynamic secrets
- Cons: Requires dedicated infrastructure, suffers from the same Secret Zero problem, massive operational overhead for a solo developer
- Decision: Rejected due to operational complexity
AWS Secrets Manager / GCP Secret Manager
- Pros: Native cloud integration, good security model
- Cons: Requires committing to a Cloud Service Provider, introduces massive overhead (IAM, billing, org structure) just to store strings, conflicts with Minimize Platforms
- Decision: Rejected to avoid cloud lock-in for a cross-cutting concern
Infisical
- Pros: Open-source Doppler alternative, can self-host
- Cons: Self-hosting adds operational burden, smaller community/ecosystem than Doppler
- Decision: Rejected in favor of managed solution (Doppler's free tier eliminates cost concern)
1Password Secrets Automation
- Pros: Integrates with existing 1Password subscription, good developer experience
- Cons: Primarily designed for human-to-app secrets rather than app-to-app, less specialized for CI/CD workflows than Doppler
- Decision: Rejected in favor of purpose-built developer tool
Consequences
Positive
- Scalability: Easily manage hundreds of secrets across multiple environments without GitHub UI limitations
- Developer Experience: Doppler CLI provides seamless local development without
.envfile risks - Secret Rotation: Update a secret in one place, it propagates everywhere (CI/CD, local, cloud functions)
- Audit Trail: Comprehensive logging of secret access and modifications
- Principle of Least Privilege: Easy to create scoped service tokens for different subsections (e.g., different Cloudflare API keys for Workers vs. Pages vs. Images)
- Free for Solo Dev: Doppler's free tier is sufficient for individual developers
- Reduced Risk: Secrets are never written to disk in plain text during local development
Negative
- Platform Dependency: Adds another platform to manage, contradicting Minimize Platforms
- Secret Zero Persists: Still requires
DOPPLER_TOKENin GitHub Secrets, so we haven't eliminated the bootstrap problem - Vendor Lock-in: Migrating away from Doppler requires rewriting secret injection across all pipelines
- Internet Dependency: Local development requires network access to Doppler (though CLI supports caching)
- Premature Optimization: Currently only have 2-3 integrations, so the complexity may not yet justify the additional platform
When This Becomes Necessary
This transition should be considered when:
- Secret Rotation Pain: Manually rotating secrets becomes a frequent, painful task
- Team Growth: Multiple developers need synchronized access to secrets
- Multi-Environment Complexity: Running staging/preview environments with different secret scopes
Until then, maintaining the status quo (GitHub Secrets only) may be the better adherence to Lean & Agile (YAGNI).