Secrets With SOPS
Tags: kubernetes, security, devops
Published: 2021-11-13 11:58:54

SOPS (Secrets OperationS) is an open source tool from Mozilla, intended to edit, encrypt, decrypt a range of different file types, such as YAML, JSON, ENV etc. 

Encryption can be done in variety of ways, using major cloud providers encryption tools, PGP, and even age.

In this article, we'll focus on using AWS + KMS. A similar setup and workflow can be used for GCP and Azure as well. 

### Installing 
Download + install one of: 
- [stable releases](https://github.com/mozilla/sops/releases)

- [unstable features](go.mozilla.org/sops/v3/cmd/sops)

More details can be found on the SOPS github repo.

### Configuring
Pre-requistes for this are: 
- A ready to use KMS key.
- Correctly configured AWS credentials, for example: 
```
[default]
aws_access_key_id = <access-key-id>
aws_secret_access_key = <access-key>

[kmsuser]
aws_access_key_id = <kmsuser-access-key-id>
aws_secret_access_key = <kmsuer-access-key>

```

A separate kmsuser is not a requirement, but SOPS supports switching profiles, which will be discussed later on. 


Next, you'll need to set up your sops configuration, which means telling sops which key to use, possibly what profile and what role to use. 

Set up a .sops.yaml, locally. 

Some configurations are as follows:

```
sops:
    kms:
    - arn: arn:aws:kms:ap-southeast-2:036762315531:key/46b7ee9d-d11a-4a7e-83a5-c83fe5c93e8f
```
This is the most basic configuration. It specifies KMS and the specific resource to use for encryption and decryption. 
There is no profile or role listed, so it uses your default credentials. 

```
sops:
    kms:
    - arn: arn:aws:kms:ap-southeast-2:036762315531:key/00aa1727-d895-4dc9-a10c-96ad40470a91
      aws_profile: kmsuser
```
In some situations you'll want to define alternative credentials, so you can specify which profile to use, from your credentials file. 

```
sops:
    kms:
    -   arn: arn:aws:kms:ap-southeast-2:036762315531:key/00aa1727-d895-4dc9-a10c-96ad40470a91
        role: arn:aws:iam::913492025681:role/sopsuser
```

SOPS also allows you to make use of AWS' roles feature, meaning you can use KMS from multiple accounts. 

### Using

Encryption:
- sops -e secrets.yaml > secrets.enc.yaml

Decryption:
- sops -d secrets.enc.yaml > secrets.yaml

Example:

Plaintext secrets: 
```
apiVersion: v1
kind: Secret
metadata:
    name: t0p-S3cret
type: Opaque
data:
    password: 12345-password
```

Encrypted secrets: 
```
apiVersion: ENC[AES256_GCM,data:690=,iv:GM5Rle5baQNBC4MBECfVEY9YZzAeywnHcrcclGnwAVw=,tag:xN311xVOyvqC+TXy16KNcQ==,type:str]
kind: ENC[AES256_GCM,data:PGiPB4h3,iv:t9kAkvT9u38dwqOtBAPXEcLGqBa07/Ggk4gEhO/SzSQ=,tag:4NN94br3Ut9EmB/zMjkWMw==,type:str]
metadata:
  name: ENC[AES256_GCM,data:AZP+jxs5kVJQyh5ZcxROzIuuZgTsEQ==,iv:wA2OVYCQ8icb10XIRxTZu+QMILUoORrIOJmh30rmX84=,tag:VGBR8shJQ8x7RQY0R5fMqQ==,type:str]
type: ENC[AES256_GCM,data:fqP1lGtK,iv:bzhdcaZ1WyJpgy4v3Q2MS0J6q3XNLRtC2qbdWHkoqtk=,tag:dGbR3gWt54lnRRIYtq7i9w==,type:str]
data:
  password: ENC[AES256_GCM,data:ihVGHIa/SqDxC64wzFRvtFcKtk3WPmpjIWUh3HxCo60=,iv:gcxL6u2JNh+T7lXb5VbfZS9aKun8ZOAK+X93uJ4Vd6M=,tag:/y5UTFa3mIiAaV6RPif9mQ==,type:str]
sops:
  kms:
    - arn: arn:aws:kms:ap-southeast-2:036762315531:key/46b7ee9d-d11a-4a7e-83a5-c83fe5c93e8f
      created_at: "2021-11-12T06:28:22Z"
      enc: AQICAHguJRDZ0cg53Sh5Mus9w8WLD236AYz81m6wFTHAa6ObgQFSNXL+AHX+kn+akWNtP7aQAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMKaUlIgOrUMmOA/LzAgEQgDs62h0/zahsnr+4z1trkI+Euk5WkWqkQBnBh3KijqPEJJnKnPE9v41vSGJLbfeI8QOruvR6YwU2V3G7LQ==
      aws_profile: kmsuser
  gcp_kms: []
  azure_kv: []
  hc_vault: []
  age: []
  lastmodified: "2021-11-12T06:28:23Z"
  mac: ENC[AES256_GCM,data:Lwo28isqP6hA2nxjXDTnkglZjj8Ip1+W+erYlV/dq7r7YoJWAE+vFbWdiKIm4wE7bhSsoNQiIFGbQVqRx7VoGjwAE8A//0BCfrd7i5dTS5+/c0BOiLLrpNSqdTxRiNTUMGcvvWWnmkf+uBmMN/pOhyXwhdB+z9h0ST6Y3rR+zHE=,iv:l01KhN0a6BeoIIn45lbUamNKBNWX2eTMo7ToA2OsF/I=,tag:jfuPs6lS913B7Yb0jMjefA==,type:str]
  pgp: []
  unencrypted_suffix: _unencrypted
  version: 3.7.1
```

As you can see here, we have a regular secrets manifest, which is encrypted and can then be checked in or shared freely.

SOPS encrypts all the values, not just secrets, specifies metadata such as profile and kms key used. 


### CI

There are a number of ways to use sops encrypted secrets in your CI workflow. 

The most basic way is to install sops, decrypt and apply the decrypted file to your cluster.
For example:
```
sops -d secrets.enc.yaml | kubectl apply -f -
```

However, it's most like you're using some kind of manifest management tool and will want secrets to work within that ecosystem. To achieve this there are some wrappers for sops: 
- [helm-secrets](https://github.com/jkroepke/helm-secrets)
- [ksops](https://github.com/viaduct-ai/kustomize-sops)

### Final thoughts
SOPS is a great tool to get started with a GitOps style of secret management. However, there are some consideration you should take into account before committing to this solution: 
- Key rotation
- Lack of control over who can see secrets once in the cluster
- Scalability for large teams, or a large number of secrets