Usage
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.
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"
Your AWS credentials must be present in ~/.aws/credentials. sops uses
aws-sdk-go.
$ cat ~/.aws/credentials
[default]
aws_access_key_id = AKI.....
aws_secret_access_key = mw......
If you want to use PGP, export the fingerprints of the public keys,
comma separated, in the SOPS_PGP_FP env variable.
export SOPS_PGP_FP="85D77543B3D624B63CEA9E6DBC17301B491B3F21,E60892BB9BD89A69F759A1A0A3D652173B763E8F"
Note: you can use both PGP and KMS simultaneously.
Then simply call sops with a file path as argument. It will handle the
encryption/decryption transparently and open the cleartext file in an
editor
$ sops 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 $EDITOR is set to, or, if it's not
set, in vim. 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/mozilla/sops/issues/127) for more
information.
The resulting encrypted file looks like this:
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:
$ sops -d 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:
$ sops <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.
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/mozilla/sops.git
$ cd sops
$ gpg --import tests/sops_functional_tests_key.asc
$ sops example.yaml
This last step will decrypt example.yaml using the test private key.
Adding and removing keys
When creating new files, sops uses the PGP and KMS defined in the
command line arguments --kms and --pgp, or from the environment
variables SOPS_KMS_ARN and SOPS_PGP_FP. That information is stored
in the file under the sops section, such that decrypting files does not
require providing those parameters again.
Master PGP and KMS keys can be added and removed from a sops file in one
of two ways: by using command line flag, or by editing the file
directly.
Command line flag --add-kms, --add-pgp, --rm-kms and --rm-pgp can be
used to add and remove keys from a file. These flags use the comma
separated syntax as the --kms and --pgp arguments when creating new
files.
# add a new pgp key to the file and rotate the data key
$ sops -r --add-pgp 85D77543B3D624B63CEA9E6DBC17301B491B3F21 example.yaml
# remove a pgp key from the file and rotate the data key
$ sops -r --rm-pgp 85D77543B3D624B63CEA9E6DBC17301B491B3F21 example.yaml
Alternatively, invoking sops with the flag -s will display the
master keys while editing. This method can be used to add or remove kms
or pgp keys under the sops section.
For example, to add a KMS master key to a file, add the following entry
while editing:
sops:
kms:
- arn: arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e
And, similarly, to add a PGP master key, we add its fingerprint:
sops:
pgp:
- fp: 85D77543B3D624B63CEA9E6DBC17301B491B3F21
When the file is saved, sops will update its metadata and encrypt the
data key with the freshly added master keys. The removed entries are
simply deleted from the file.
When removing keys, it is recommended to rotate the data key using -r,
otherwise owners of the removed key may have add access to the data key
in the past.
Assuming roles and using KMS in various AWS accounts
SOPS has the ability to use KMS in multiple AWS accounts by assuming
roles in each account. Being able to assume roles is a nice feature of
AWS that allows administrators to establish trust relationships between
accounts, typically from the most secure account to the least secure
one. In our use-case, we use roles to indicate that a user of the Master
AWS account is allowed to make use of KMS master keys in development and
staging AWS accounts. Using roles, a single file can be encrypted with
KMS keys in multiple accounts, thus increasing reliability and ease of
use.
You can use keys in various accounts by tying each KMS master key to a
role that the user is allowed to assume in each account. The IAM
roles
documentation has full details on how this needs to be configured on
AWS's side.
From the point of view of sops, you only need to specify the role a KMS
key must assume alongside its ARN, as follows:
sops:
kms:
- arn: arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e
role: arn:aws:iam::927034868273:role/sops-dev-xyz
The role must have permission to call Encrypt and Decrypt using KMS. An
example policy is shown below.
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Principal": {
"AWS": [
"arn:aws:iam::927034868273:role/sops-dev-xyz"
]
}
}
You can specify a role in the --kms flag and SOPS_KMS_ARN variable by
appending it to the ARN of the master key, separated by a + sign:
<KMS ARN>+<ROLE ARN>
arn:aws:kms:us-west-2:927034868273:key/fe86dd69-4132-404c-ab86-4269956b4500+arn:aws:iam::927034868273:role/sops-dev-xyz
AWS KMS Encryption Context
SOPS has the ability to use AWS KMS key policy and encryption context
<http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html>
to refine the access control of a given KMS master key.
When creating a new file, you can specify encryption context in the
--encryption-context flag by comma separated list of key-value pairs:
When creating a new file, you can specify encryption context in the
--encryption-context flag by comma separated list of key-value pairs:
$ sops --encryption-context Environment:production,Role:web-server test.dev.yaml
The format of the Encrypt Context string is
<EncryptionContext Key>:<EncryptionContext Value>,<EncryptionContext Key>:<EncryptionContext Value>,...
The encryption context will be stored in the file metadata and does not
need to be provided at decryption.
Encryption contexts can be used in conjunction with KMS Key Policies to
define roles that can only access a given context. An example policy is
shown below:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/RoleForExampleApp"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:EncryptionContext:AppName": "ExampleApp",
"kms:EncryptionContext:FilePath": "/var/opt/secrets/"
}
}
}
Key Rotation
It is recommended to renew the data key on a regular basis. sops
supports key rotation via the -r flag. Invoking it on an existing file
causes sops to reencrypt the file with a new data key, which is then
encrypted with the various KMS and PGP master keys defined in the file.
sops -r example.yaml
Using .sops.yaml conf to select KMS/PGP for new files
It is often tedious to specify the --kms and --pgp 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.
Let's take an example:
- file named something.dev.yaml should use one set of KMS A
- file named something.prod.yaml should use another set of KMS B
- other files use a third set of KMS C
- all live under mysecretrepo/something.{dev,prod}.yaml
Under those circumstances, a file placed at mysecretrepo/.sops.yaml
can manage the three sets of configurations for the three types of
files:
# creation rules are evaluated sequentially, the first match wins
creation_rules:
# upon creation of a file that matches the pattern *.dev.yaml,
# KMS set A is used
- filename_regex: \.dev\.yaml$
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: '1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A'
# prod files use KMS set B in the PROD IAM
- filename_regex: \.prod\.yaml$
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: '1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A'
# Finally, if the rules above have not matched, this one is a
# catchall that will encrypt the file using KMS set C
# The absence of a filename_regex means it will match everything
- 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: '1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A'
When creating any file under mysecretrepo, 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.
Creating a new file with the right keys is now as simple as
$ sops <newfile>.prod.yaml
Note that the configuration file is ignored when KMS or PGP parameters
are passed on the sops command line or in environment variables.
Specify a different GPG executable
sops checks for the SOPS_GPG_EXEC environment variable. If specified,
it will attempt to use the executable set there instead of the default
of gpg.
Example: place the following in your ~/.bashrc
SOPS_GPG_EXEC = 'your_gpg_client_wrapper'