Sops
Simple and flexible tool for managing secrets
Install / Use
/learn @getsops/SopsREADME
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, HuaweiCloud KMS, age, and PGP.
(demo <https://www.youtube.com/watch?v=YTEVyLXFiq0>_)
.. image:: https://i.imgur.com/X0TM5NI.gif
.. image:: https://pkg.go.dev/badge/github.com/getsops/sops/v3.svg :target: https://pkg.go.dev/github.com/getsops/sops/v3
Download
Stable release
Binaries and packages of the latest stable release are available at `https://github.com/getsops/sops/releases <https://github.com/getsops/sops/releases>`_.
Development branch
For the adventurous, unstable features are available in the main branch, which you can install from source:
.. code:: bash
$ mkdir -p $GOPATH/src/github.com/getsops/sops/
$ git clone https://github.com/getsops/sops.git $GOPATH/src/github.com/getsops/sops/
$ cd $GOPATH/src/github.com/getsops/sops/
$ make install
(requires Go >= 1.19)
If you don't have Go installed, set it up with:
.. code:: bash
$ {apt,yum,brew} install golang
$ echo 'export GOPATH=~/go' >> ~/.bashrc
$ source ~/.bashrc
$ mkdir $GOPATH
Or whatever variation of the above fits your system and shell.
To use SOPS as a library, take a look at the decrypt package <https://pkg.go.dev/github.com/getsops/sops/v3/decrypt>_.
.. sectnum:: .. contents:: Table of Contents
Usage
For a quick presentation of SOPS, check out this Youtube tutorial:
.. image:: https://img.youtube.com/vi/V2PRhxphH2w/0.jpg :target: https://www.youtube.com/watch?v=V2PRhxphH2w
If you're using AWS KMS, create one or multiple master keys in the IAM console and export them, comma separated, in the SOPS_KMS_ARN env variable. It is recommended to use at least two master keys in different regions.
.. code:: bash
export SOPS_KMS_ARN="arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e,arn:aws:kms:ap-southeast-1:656532927350:key/9006a8aa-0fa6-4c14-930e-a2dfb916de1d"
SOPS uses aws-sdk-go-v2 <https://github.com/aws/aws-sdk-go-v2>_ to communicate with AWS KMS. It will automatically
read the credentials from the ~/.aws/credentials file which can be created with the aws configure command.
An example of the ~/.aws/credentials file is shown below:
.. code:: sh
$ cat ~/.aws/credentials
[default]
aws_access_key_id = AKI.....
aws_secret_access_key = mw......
In addition to the ~/.aws/credentials file, you can also use the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
environment variables to specify your credentials:
.. code:: bash
export AWS_ACCESS_KEY_ID="AKI......"
export AWS_SECRET_ACCESS_KEY="mw......"
For more information and additional environment variables, see
specifying credentials <https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials>_.
If you want to use PGP, export the fingerprints of the public keys, comma separated, in the SOPS_PGP_FP env variable.
.. code:: bash
export SOPS_PGP_FP="85D77543B3D624B63CEA9E6DBC17301B491B3F21,E60892BB9BD89A69F759A1A0A3D652173B763E8F"
Note: you can use both PGP and KMS simultaneously.
Then simply call sops edit with a file path as argument. It will handle the
encryption/decryption transparently and open the cleartext file in an editor
.. code:: sh
$ sops edit mynewtestfile.yaml
mynewtestfile.yaml doesn't exist, creating it.
please wait while an encryption key is being generated and stored in a secure fashion
file written to mynewtestfile.yaml
Editing will happen in whatever $SOPS_EDITOR or $EDITOR is set to, or, if it's
not set, in vim, nano, or vi.
Keep in mind that SOPS will wait for the editor to exit, and then try to reencrypt
the file. Some GUI editors (atom, sublime) spawn a child process and then exit
immediately. They usually have an option to wait for the main editor window to be
closed before exiting. See #127 <https://github.com/getsops/sops/issues/127>_ for
more information.
The resulting encrypted file looks like this:
.. code:: yaml
myapp1: ENC[AES256_GCM,data:Tr7o=,iv:1=,aad:No=,tag:k=]
app2:
db:
user: ENC[AES256_GCM,data:CwE4O1s=,iv:2k=,aad:o=,tag:w==]
password: ENC[AES256_GCM,data:p673w==,iv:YY=,aad:UQ=,tag:A=]
# private key for secret operations in app2
key: |-
ENC[AES256_GCM,data:Ea3kL5O5U8=,iv:DM=,aad:FKA=,tag:EA==]
an_array:
- ENC[AES256_GCM,data:v8jQ=,iv:HBE=,aad:21c=,tag:gA==]
- ENC[AES256_GCM,data:X10=,iv:o8=,aad:CQ=,tag:Hw==]
- ENC[AES256_GCM,data:KN=,iv:160=,aad:fI4=,tag:tNw==]
sops:
kms:
- created_at: 1441570389.775376
enc: CiC....Pm1Hm
arn: arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e
- created_at: 1441570391.925734
enc: Ci...awNx
arn: arn:aws:kms:ap-southeast-1:656532927350:key/9006a8aa-0fa6-4c14-930e-a2dfb916de1d
pgp:
- fp: 85D77543B3D624B63CEA9E6DBC17301B491B3F21
created_at: 1441570391.930042
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA0t4uZHfl9qgAQ//UvGAwGePyHuf2/zayWcloGaDs0MzI+zw6CmXvMRNPUsA
...=oJgS
-----END PGP MESSAGE-----
A copy of the encryption/decryption key is stored securely in each KMS and PGP block. As long as one of the KMS or PGP method is still usable, you will be able to access your data.
To decrypt a file in a cat fashion, use the -d flag:
.. code:: sh
$ sops decrypt mynewtestfile.yaml
SOPS encrypted files contain the necessary information to decrypt their content. All a user of SOPS needs is valid AWS credentials and the necessary permissions on KMS keys.
Given that, the only command a SOPS user needs is:
.. code:: sh
$ sops edit <file>
<file> will be opened, decrypted, passed to a text editor (vim by default),
encrypted if modified, and saved back to its original location. All of these
steps, apart from the actual editing, are transparent to the user.
The order in which available decryption methods are tried can be specified with
--decryption-order option or SOPS_DECRYPTION_ORDER environment variable
as a comma separated list. The default order is age,pgp. Offline methods are
tried first and then the remaining ones.
Test with the dev PGP key
If you want to test **SOPS** without having to do a bunch of setup, you can use
the example files and pgp key provided with the repository::
$ git clone https://github.com/getsops/sops.git
$ cd sops
$ gpg --import pgp/sops_functional_tests_key.asc
$ sops edit example.yaml
This last step will decrypt ``example.yaml`` using the test private key.
Encrypting with GnuPG subkeys
If you want to encrypt with specific GnuPG subkeys, it does not suffice to provide the
exact key ID of the subkey to SOPS, since GnuPG might use another subkey instead
to encrypt the file key with. To force GnuPG to use a specific subkey, you need to
append ! to the key's fingerprint.
.. code:: yaml
creation_rules:
- pgp: >-
85D77543B3D624B63CEA9E6DBC17301B491B3F21!,
E60892BB9BD89A69F759A1A0A3D652173B763E8F!
Please note that this is only passed on correctly to GnuPG since SOPS 3.9.3.
Encrypting using age
`age <https://age-encryption.org/>`_ 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:
.. code:: sh
$ 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.
- **Linux**
- Looks for ``keys.txt`` in ``$XDG_CONFIG_HOME/sops/age/keys.txt``;
- Falls back to ``$HOME/.config/sops/age/keys.txt`` if ``$XDG_CONFIG_HOME`` isn’t set.
- **macOS**
- Looks for ``keys.txt`` in ``$XDG_CONFIG_HOME/sops/age/keys.txt``;
- Falls back to ``$HOME/Library/Application Support/sops/age/keys.txt`` if ``$XDG_CONFIG_HOME`` isn’t set.
- **Windows**
- Looks for ``keys.txt`` in `%AppData%\\sops\\age\\keys.txt``.
You can override the default lookup by:
- setting the environment variable **SOPS_AGE_KEY_FILE**;
- setting the **SOPS_AGE_KEY** environment variable;
- providing a command to output the age keys by setting the **SOPS_AGE_KEY_CMD** environment variable.
This command can read the age recipient for which to return the private key from the **SOPS_AGE_RECIPIENT** 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 also supported by SOPS. You can use SSH public keys
("ssh-ed25519 AAAA...", "ssh-rsa AAAA...") as age recipients when encrypting a file.
When decrypting a file, SOPS will attempt to source the SSH private key as follows:
- From the path specified in environment variable **SOPS_AGE_SSH_PRIVATE_KEY_FILE**.
- From the output of the command specified in environment variable **SOPS_AGE_SSH_PRIVATE_KEY_CMD**.
.. note:: The output of this command must provide a key that is not password protected.
- From ``~/.ssh/id_ed25519``.
- From ``~/.ssh/id_rsa``.
Note that only ``ssh-rsa`` and ``ssh-ed25519`` are supported.
A list of age recipients can be added to the ``.sops.yaml``:
.. code:
