4.9 KiB
Secrets Management in GitOps (2024-2025)
Overview
Never commit plain secrets to Git. Use encryption or external secret stores.
Solutions Comparison
| Solution | Type | Complexity | Best For | 2025 Trend |
|---|---|---|---|---|
| Sealed Secrets | Encrypted in Git | Low | Simple, GitOps-first | Stable |
| External Secrets Operator | External store | Medium | Cloud-native, dynamic | ↗️ Growing |
| SOPS + age | Encrypted in Git | Medium | Flexible, Git-friendly | ↗️ Preferred over PGP |
1. Sealed Secrets
How it works: Public key encryption, controller decrypts in-cluster
Setup:
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
Usage:
# Create sealed secret
kubectl create secret generic my-secret --dry-run=client -o yaml --from-literal=password=supersecret | \
kubeseal -o yaml > sealed-secret.yaml
# Commit to Git
git add sealed-secret.yaml
git commit -m "Add sealed secret"
Pros: Simple, GitOps-native, no external dependencies Cons: Key rotation complexity, static secrets only
2. External Secrets Operator (ESO)
Latest Version: v0.20.2 (2024-2025)
Supported Providers:
- AWS Secrets Manager
- Azure Key Vault
- Google Secret Manager
- HashiCorp Vault
- 1Password
- Doppler
Setup:
helm install external-secrets external-secrets/external-secrets -n external-secrets-system --create-namespace
Usage:
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secret-store
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-secret
spec:
secretStoreRef:
name: aws-secret-store
target:
name: my-app-secret
data:
- secretKey: password
remoteRef:
key: prod/my-app/password
Pros: Dynamic secrets, cloud-native, automatic rotation Cons: External dependency, requires cloud secret store
2025 Recommendation: Growing preference over Sealed Secrets
3. SOPS + age
Recommended over PGP as of 2024-2025
Setup age:
# Install age
brew install age # macOS
apt install age # Ubuntu
# Generate key
age-keygen -o key.txt
# Public key: age1...
Setup SOPS:
# Install SOPS
brew install sops
# Create .sops.yaml
cat <<EOF > .sops.yaml
creation_rules:
- path_regex: .*.yaml
encrypted_regex: ^(data|stringData)$
age: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
EOF
Encrypt secrets:
# Create secret
kubectl create secret generic my-secret --dry-run=client -o yaml --from-literal=password=supersecret > secret.yaml
# Encrypt with SOPS
sops -e secret.yaml > secret.enc.yaml
# Commit encrypted version
git add secret.enc.yaml .sops.yaml
Flux Integration:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: app
spec:
decryption:
provider: sops
secretRef:
name: sops-age
Pros: Git-friendly, flexible, age is simpler than PGP Cons: Manual encryption step, key management
Best Practices (2024-2025)
1. Key Rotation
Sealed Secrets: Rotate annually, maintain old keys for decryption ESO: Automatic with cloud providers SOPS: Re-encrypt when rotating age keys
2. Access Control
- Never commit
.sopsage key to Git - Use separate keys per environment
- Store age keys in CI/CD secrets
- Use RBAC for Secret access
3. Encryption Scope
SOPS .sops.yaml:
creation_rules:
- path_regex: production/.*
encrypted_regex: ^(data|stringData)$
age: age1prod...
- path_regex: staging/.*
encrypted_regex: ^(data|stringData)$
age: age1staging...
4. Git Pre-commit Hook
Prevent committing plain secrets:
#!/bin/bash
# .git/hooks/pre-commit
if git diff --cached --name-only | grep -E 'secret.*\.yaml$'; then
echo "⚠️ Potential secret file detected"
echo "Ensure it's encrypted with SOPS"
exit 1
fi
5. ArgoCD 3.0 Recommendation
Use secrets operators (ESO preferred), avoid config management plugins for secrets
Decision Guide
Choose Sealed Secrets if:
- ✅ Simple GitOps workflow
- ✅ Static secrets
- ✅ No external dependencies wanted
- ✅ Small team
Choose External Secrets Operator if:
- ✅ Already using cloud secret stores
- ✅ Need secret rotation
- ✅ Dynamic secrets
- ✅ Enterprise compliance
Choose SOPS + age if:
- ✅ Git-centric workflow
- ✅ Want flexibility
- ✅ Multi-cloud
- ✅ Prefer open standards
2025 Trend Summary
Growing: External Secrets Operator, SOPS+age Stable: Sealed Secrets (still widely used) Declining: PGP encryption (age preferred) Emerging: age encryption as standard (simpler than PGP)