Introduction
sops solves a fundamental DevOps problem: how to store secrets in version control safely. Unlike tools that encrypt entire files (making diffs useless), sops encrypts only the values while keeping keys readable. This means you can see what secrets exist (database_url, api_key) in a git diff, but the actual values remain encrypted.
With over 21,000 GitHub stars, sops is the most popular file-level secrets encryption tool. Originally created by Mozilla, it is now maintained by the CNCF. It supports multiple encryption backends and integrates with Kubernetes, Terraform, Ansible, and CI/CD pipelines.
What sops Does
sops takes a YAML, JSON, ENV, or INI file and encrypts the values while preserving the keys and file structure. It supports multiple Key Management Services (KMS) for key wrapping, allowing teams to use cloud-native key management without manual key distribution.
Architecture Overview
[Plain secrets.yaml]
db_password: hunter2
api_key: sk-abc123
|
sops --encrypt --age age1...
|
[Encrypted secrets.enc.yaml]
db_password: ENC[AES256_GCM,data:abc...]
api_key: ENC[AES256_GCM,data:def...]
sops:
age:
- recipient: age1...
enc: ...
lastmodified: 2024-01-01
version: 3.8.0
[Encryption Backends]
+------+------+------+------+
| | | | |
[age] [AWS [GCP [Azure [PGP]
KMS] KMS] KV]Self-Hosting & Configuration
# .sops.yaml — project configuration
creation_rules:
# Production secrets use AWS KMS
- path_regex: production/.*\.yaml$
kms: arn:aws:kms:us-east-1:123:key/abc-def
encrypted_regex: "^(password|secret|key|token)$"
# Development secrets use age
- path_regex: development/.*\.yaml$
age: age1yourkey...
# Default: use age
- age: age1yourkey...# Workflow examples
# Create new encrypted file
cat > /tmp/secrets.yaml << EOF
database:
host: db.example.com
password: supersecret
port: 5432
api:
key: sk-abc123
webhook_secret: whsec-xyz
EOF
sops --encrypt /tmp/secrets.yaml > secrets.enc.yaml
# Edit in place (opens in $EDITOR)
sops secrets.enc.yaml
# Decrypt for application use
export DB_PASS=$(sops -d --extract '["database"]["password"]' secrets.enc.yaml)
# Use with Kubernetes
sops -d secrets.enc.yaml | kubectl apply -f -
# Use with Terraform
# data "sops_file" "secrets" {
# source_file = "secrets.enc.yaml"
# }Key Features
- Value-Level Encryption — keys stay readable, only values are encrypted
- Multiple Backends — age, AWS KMS, GCP KMS, Azure Key Vault, PGP
- Git-Friendly — meaningful diffs on encrypted files
- In-Place Editing — sops opens encrypted files in your editor
- Selective Encryption — encrypted_regex to encrypt only specific fields
- Key Groups — require multiple keys to decrypt (M-of-N threshold)
- Audit Trail — tracks who encrypted, when, and with which keys
- Format Agnostic — works with YAML, JSON, ENV, INI, and binary files
Comparison with Similar Tools
| Feature | sops | HashiCorp Vault | Sealed Secrets | AWS Secrets Manager |
|---|---|---|---|---|
| Type | File encryption | Secrets server | K8s controller | Cloud service |
| Storage | Git (encrypted files) | Vault server | K8s etcd | AWS |
| Git-Friendly | Yes (key insight) | No | Limited | No |
| Infrastructure | None | Vault cluster | K8s cluster | AWS account |
| Cost | Free | Free / Enterprise | Free | Per-secret pricing |
| Best For | GitOps, small teams | Enterprise, dynamic | Kubernetes | AWS-native |
FAQ
Q: Why not just use a .env file with .gitignore? A: Gitignored files are not version-controlled — you lose history, peer review, and disaster recovery. sops lets you commit secrets to Git safely, with full diff history and code review.
Q: How do I rotate encryption keys? A: Run "sops rotate -i secrets.enc.yaml" to re-encrypt with a new data key. To change the master key, update .sops.yaml and run "sops updatekeys secrets.enc.yaml".
Q: Can I use sops with Kubernetes? A: Yes. Decrypt at deploy time: "sops -d secrets.enc.yaml | kubectl apply -f -". Or use flux/argo-cd sops integration for automatic decryption in GitOps workflows.
Q: What if I lose the encryption key? A: You cannot decrypt without the key — there is no recovery. Use key groups with multiple backends (e.g., age + AWS KMS) so losing one key does not lock you out.
Sources
- GitHub: https://github.com/getsops/sops
- Documentation: https://getsops.io
- Originally created by Mozilla, now CNCF
- License: MPL-2.0