TL;DR
| |
SOPS encrypts the values of a structured file (YAML/JSON/env/ini) and leaves the keys readable, so a secrets.enc.yaml is a clean, reviewable git diff. Decryption needs the GPG private key on the machine.
Prerequisites
gpg and sops installed. Check: gpg --version and sops --version.
1. Get a GPG key
Use an existing key or create one:
| |
Copy the 40-char fingerprint (the long hex line under sec). That fingerprint is what SOPS references — not the short key id.
2. Tell SOPS which key to use
Put a .sops.yaml at the repo root so you never pass keys by hand:
| |
path_regexscopes the rule to files you name*.enc.yaml.pgptakes one or more comma-separated fingerprints (multiple recipients = anyone with one of those private keys can decrypt).
3. Encrypt, edit, decrypt
| |
Commit the encrypted file. The plaintext never touches git.
What SOPS touches
| Part | Encrypted? |
|---|---|
Values (password: hunter2) | yes |
Keys / structure (password:) | no (readable diffs) |
Extra sops: metadata block | added (recipients, MAC) |
Traps
- Subkeys: to force a specific GnuPG subkey, append
!to the fingerprint increation_rules(e.g.A3D6...E8F!). Only honored since SOPS 3.9.3. - Different gpg binary: set
SOPS_GPG_EXECto point SOPS at a wrapper instead of the defaultgpg. - Back up the private key. Lose it and the encrypted files are gone — SOPS is only as recoverable as the GPG key. Add a second recipient (a backup/escrow key) in
creation_rulesfrom day one. - Rotating recipients: after editing
creation_rules, runsops updatekeys secrets.enc.yamlto re-encrypt the file key for the new set. - Only structured files get value-level encryption; for a blob use
sops -e --input-type binary.
Git and automation
- The encrypted file is what lives in git; reviewers see key names, never values.
- On any host/CI that must decrypt, import the private key into its GPG keyring first (
gpg --import), thensops -d. - Ansible can consume SOPS directly via the
community.sopscollection (e.g. thecommunity.sops.sopslookup /load_vars) so playbooks read secrets without a manual decrypt step. Verify the collection is installed on the control node.
See also
- SOPS PGP / GnuPG docs: https://getsops.io/docs/usage/identities/pgp/