Skip to content

Guide: Encrypting and decrypting SOPS files

SOPS (Secrets OPerations) is a secret encryption tool that uses AWS KMS for key management. This secrets management tool allow us to store encrypted secrets in our Git Repositories and use these secrets in terraform.

Brief introduction to AWS KMS

AWS Key Management Service (KMS) is a service that securely stores cryptographic keys and performs encryption and decryption operations without exposing the underlying key to the calling application.

When a tool like sops uses KMS, it sends a request to the service to encrypt or decrypt a data key; KMS performs the cryptographic operation internally and returns only the encrypted or decrypted result. At no point does the calling application receive or handle the raw master key.

Developers may encounter KMS when sops encrypts a secrets file. During encryption, sops requests that AWS KMS generate and encrypt a data encryption key using a specified KMS key. This encrypted key is stored within the file’s sops metadata block. Later, when the file needs to be decrypted,such as during Terraform runs, SOPS again contacts AWS KMS to decrypt the data key, provided the caller has appropriate IAM permissions.

Creating/finding the AWS KMS key to use for sops commands

The AWS KMS key ARN to use for sops commands comes from the create sops key instructions in the guide to provision a fresh environment.

If the sops terraform has already been applied, the sops key arn is a terraform output to make it easy to find again.

INFRA_AWS_ENV="sandbox"
PROFILE_NAME="oc-${INFRA_AWS_ENV}-automation"

aws-vault exec ${PROFILE_NAME} --no-session -- terraform output
Output:
region = "us-west-2"
sops_kms_arn = "arn:aws:kms:us-west-2:825979908767:key/b0f7069e-571e-4a9a-91f8-5ed17458a02a"

Encrypt a new plain-text secrets file

If we have the name of our secrets file secrets-${INFRA_AWS_ENV}.yaml, we can encrypt this using the KMS alias keyname from AWS.

INFRA_AWS_ENV="sandbox"
PROFILE_NAME="oc-${INFRA_AWS_ENV}-automation"
INFRA_AWS_REGION="us-west-2"
INFRA_AWS_ACCOUNT_ID=`aws-vault exec ${PROFILE_NAME} --no-session -- aws sts get-caller-identity | jq '.Account' | tr -d '"'`

# using aws-vault for managing the AWS credentials the `sops` cmd uses
aws-vault exec ${PROFILE_NAME} --no-session -- sops --encrypt \
    --kms "arn:aws:kms:${INFRA_AWS_REGION}:${INFRA_AWS_ACCOUNT_ID}:key/<kms-key-id>" \
    --in-place secrets-${INFRA_AWS_ENV}.yaml

aws-vault exec ${PROFILE_NAME} --no-session -- sops --decrypt \
    --kms "arn:aws:kms:${INFRA_AWS_REGION}:${INFRA_AWS_ACCOUNT_ID}:key/<kms-key-id>" \
    --in-place secrets-${INFRA_AWS_ENV}.yaml

Update existing secrets file

By not specifying the --decrypt/--encrypt flag, we can edit the file using $EDITOR.

sops --kms "arn:aws:kms:<region>:<account_id>:key/<kms-key-id>" secrets-myenv.yaml

Re-encrypt secrets file with new KMS key

To rotate a specific file, we can use the following command. This command is equivilent to decrypting using the old KMS key, and re-encrypting using the new KMS key.

sops --rotate --in-place --kms="arn:aws:kms:<region>:<account_id>:key/<kms-key-id>" secrets-myenv.yaml