---
obj: application
repo: https://github.com/getsops/sops
website: https://getsops.io
rev: 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
```sh
# 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:

```yml
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`:
```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.
