7.5 KiB
obj | repo | website | rev |
---|---|---|---|
application | https://github.com/getsops/sops | https://getsops.io | 2025-06-02 |
SOPS: Secrets OPerationS
SOPS is an editor of encrypted files that supports YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, age, and PGP.
Usage
# Edit a file
sops <file>
# Decrypt a file
sops -d <file>
# Example: kubectl
sops -d <file> | kubectl apply -f -
Configuration
It is often tedious to specify the --kms
--gcp-kms
--pgp
and --age
parameters for creation of all new files. If your secrets are stored under a specific directory, like a git repository, you can create a .sops.yaml
configuration file at the root directory to define which keys are used for which filename.
Note
: The file needs to be named
.sops.yaml
. Other names (i.e..sops.yml
) won’t be automatically discovered by sops. You’ll need to pass the--config .sops.yml
option for it to be picked up.
When creating any file in the repository, whether at the root or under a subdirectory, SOPS will recursively look for a .sops.yaml
file. If one is found, the filename of the file being created is compared with the filename regexes of the configuration file. The first regex that matches is selected, and its KMS and PGP keys are used to encrypt the file. It should be noted that the looking up of .sops.yaml
is from the working directory (CWD) instead of the directory of the encrypting file.
The path_regex
checks the path of the encrypting file relative to the .sops.yaml
config file. Here is an example:
creation_rules:
# upon creation of a file under development,
# KMS set A is used
- path_regex: .*/development/.*
kms: 'arn:aws:kms:us-west-2:927034868273:key/fe86dd69-4132-404c-ab86-4269956b4500,arn:aws:kms:us-west-2:361527076523:key/5052f06a-5d3f-489e-b86c-57201e06f31e+arn:aws:iam::361527076523:role/hiera-sops-prod'
pgp: 'FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4'
# prod files use KMS set B in the PROD IAM
- path_regex: .*/production/.*
kms: 'arn:aws:kms:us-west-2:361527076523:key/5052f06a-5d3f-489e-b86c-57201e06f31e+arn:aws:iam::361527076523:role/hiera-sops-prod,arn:aws:kms:eu-central-1:361527076523:key/cb1fab90-8d17-42a1-a9d8-334968904f94+arn:aws:iam::361527076523:role/hiera-sops-prod'
pgp: 'FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4'
# other files use KMS set C
- kms: 'arn:aws:kms:us-west-2:927034868273:key/fe86dd69-4132-404c-ab86-4269956b4500,arn:aws:kms:us-west-2:142069644989:key/846cfb17-373d-49b9-8baf-f36b04512e47,arn:aws:kms:us-west-2:361527076523:key/5052f06a-5d3f-489e-b86c-57201e06f31e'
pgp: 'FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4'
Example to encrypt all secrets.yml
:
creation_rules:
- path_regex: secrets.yml
encrypted_regex: '^(data|stringData)$'
age: <age_key>
Encrypting using age
age is a simple, modern, and secure tool for encrypting files. It's recommended to use age over PGP, if possible.
You can encrypt a file for one or more age recipients (comma separated) using the --age
option or the $SOPS_AGE_RECIPIENTS
environment variable:
$ sops encrypt --age age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw test.yaml > test.enc.yaml
When decrypting a file with the corresponding identity, SOPS will look for a text file name keys.txt
located in a sops subdirectory of your user configuration directory. On Linux, this would be $XDG_CONFIG_HOME/sops/age/keys.txt
. On macOS, this would be $HOME/Library/Application Support/sops/age/keys.txt
. On Windows, this would be %AppData%\sops\age\keys.txt
. You can specify the location of this file manually by setting the environment variable $SOPS_AGE_KEY_FILE
. Alternatively, you can provide the key(s) directly by setting the $SOPS_AGE_KEY
environment variable.
The contents of this key file should be a list of age X25519 identities, one per line. Lines beginning with #
are considered comments and ignored. Each identity will be tried in sequence until one is able to decrypt the data.
Encrypting with SSH keys via age is not yet supported by SOPS.
Showing diffs in cleartext in git
You most likely want to store encrypted files in a version controlled repository. SOPS can be used with git to decrypt files when showing diffs between versions. This is very handy for reviewing changes or visualizing history.
To configure SOPS to decrypt files during diff, create a .gitattributes
file at the root of your repository that contains a filter and a command.
*.yaml diff=sopsdiffer
Here we only care about YAML files. sopsdiffer
is an arbitrary name that we map to a SOPS command in the git configuration file of the repository.
$ git config diff.sopsdiffer.textconv "sops decrypt"
$ grep -A 1 sopsdiffer .git/config
[diff "sopsdiffer"]
textconv = "sops decrypt"
With this in place, calls to git diff will decrypt both previous and current versions of the target file prior to displaying the diff. And it even works with git client interfaces, because they call git diff under the hood!
Encrypting only parts of a file
Note
: this only works on YAML and JSON files, not on BINARY files.
By default, SOPS encrypts all the values of a YAML or JSON file and leaves the keys in cleartext. In some instances, you may want to exclude some values from being encrypted. This can be accomplished by adding the suffix _unencrypted
to any key of a file. When set, all values underneath the key that set the _unencrypted
suffix will be left in cleartext.
Note that, while in cleartext, unencrypted content is still added to the checksum of the file, and thus cannot be modified outside of SOPS without breaking the file integrity check. This behavior can be modified using --mac-only-encrypted
flag or .sops.yaml
config file which makes SOPS compute a MAC only over values it encrypted and not all values.
The unencrypted suffix can be set to a different value using the --unencrypted-suffix
option.
Conversely, you can opt in to only encrypt some values in a YAML or JSON file, by adding a chosen suffix to those keys and passing it to the --encrypted-suffix
option.
A third method is to use the --encrypted-regex
which will only encrypt values under keys that match the supplied regular expression. For example, this command:
$ sops encrypt --encrypted-regex '^(data|stringData)$' k8s-secrets.yaml
will encrypt the values under the data
and stringData
keys in a YAML file containing kubernetes secrets. It will not encrypt other values that help you to navigate the file, like metadata which contains the secrets' names.
Conversely, you can opt in to only leave certain keys without encrypting by using the --unencrypted-regex
option, which will leave the values unencrypted of those keys that match the supplied regular expression. For example, this command:
$ sops encrypt --unencrypted-regex '^(description|metadata)$' k8s-secrets.yaml
will not encrypt the values under the description and metadata keys in a YAML file containing kubernetes secrets, while encrypting everything else.
For YAML files, another method is to use --encrypted-comment-regex
which will only encrypt comments and values which have a preceding comment matching the supplied regular expression.
Conversely, you can opt in to only left certain keys without encrypting by using the --unencrypted-comment-regex
option, which will leave the values and comments unencrypted when they have a preeceding comment, or a trailing comment on the same line, that matches the supplied regular expression.