Encrypting your files using Mozilla SOPS
Published: 2022-09-15 15:41: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. 

## Installing
- [stable releases](https://github.com/mozilla/sops/releases)
- `brew install sops`

## Encrypting using PGP
#### 1. Generate a key 
```sh
export GPG_NAME="my-key"
export GPG_COMMENT="sops secrets"

gpg --batch --full-generate-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 4096
Subkey-Type: 1
Subkey-Length: 4096
Expire-Date: 0
Name-Comment: ${GPG_COMMENT}
Name-Real: ${GPG_NAME}
EOF
```
- Retrieve the key name
```sh
gpg --list-secret-keys "${GPG_NAME}"
sec   rsa4096 2022-09-15 [SCEA]
      0076DA32A6523CABC384933A8C755EF5C4FB4CC5
uid           [ultimate] my-key (sops secrets)
ssb   rsa4096 2022-09-15 [SEA]
```
- Store the GPG key fingerprint as an environment variable
```sh
export GPG_ID=0076DA32A6523CABC384933A8C755EF5C4FB4CC5
```
If your team need to use SOPS to encrypt or decrypt the secrets locally 
> public key using for encrypt
private key using for decrypt

- To export key
```sh
gpg --export -a "${GPG_ID}" > public.key
gpg --export-secret-key -a "${GPG_ID}" > private.key
```
- To import key 
```sh
gpg --import public.key
gpg --import private.key
```
#### 2 Let's encrypt a dummy kube secret 
secret.yaml
```yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
``` 
#### Encrypt
```
sops -e secrets.yaml > secrets.enc.yaml
```

If there are multiple GPG keys, [there are 3 ways] (https://github.com/mozilla/sops#211using-sopsyaml-conf-to-select-kmspgp-for-new-files)
- Use the `SOPS_PGP_FP` env variable 
```
export SOPS_PGP_FP=0076DA32A6523CABC384933A8C755EF5C4FB4CC5
```
- Set up a .sops.yaml (root level of your project dir)
```yaml
creation_rules:
        - pgp: '0076DA32A6523CABC384933A8C755EF5C4FB4CC5'
```

- Specify GPG key id to encrypt
```
sops -e -p 0076DA32A6523CABC384933A8C755EF5C4FB4CC5 secrets.yaml > secrets.enc.yaml
```
#### Decrypt
```
sops -d secrets.enc.yaml > secrets.yaml
```

## Encrypting using AWS KMS
Pre-requistes for this are:
- A ready to use KMS key.

![AWS KMS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fgl04ndmbs0jtzk43b2.png)

- [Correctly configured AWS credentials] (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html), 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>
```
#### Set up your sops configuration
[There are 3 ways] (https://github.com/mozilla/sops#211using-sopsyaml-conf-to-select-kmspgp-for-new-files) to set up your sops configuration, which means telling sops which key to use, possibly what profile and what role to use. 

- Use the `SOPS_KMS_ARN` env variable 
```
export SOPS_KMS_ARN="arn:aws:kms:us-east-2:270179619257:key/d8bf4685-590e-49b6-8c05-abfabff7aa96"
```
- Set up a .sops.yaml (root level of your project dir)
```yaml
creation_rules:
        - kms: 'arn:aws:kms:us-east-2:270179619257:key/d8bf4685-590e-49b6-8c05-abfabff7aa96'
```

- Specify kms arn to encrypt
```
sops -e --kms "arn:aws:kms:us-east-2:270179619257:key/d8bf4685-590e-49b6-8c05-abfabff7aa96" secrets.yaml > secrets.enc.yaml
```
#### Encrypt
```
sops -e secrets.yaml > secrets.enc.yaml
```
#### Decrypt
```
sops -d secrets.enc.yaml > secrets.yaml
```

##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. [Simple Demo here](https://github.com/kittipat1413/sops-demo)
#### Github action 
```yaml
- name: Sops Binary Installer
  uses: mdgreenwald/mozilla-sops-action@v1.4.1
  with:
    version: '<version>' # default is latest stable
  id: install
```
Then
```sh
run: |
  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)

## Argo CD Integration 
- [helm-secrets] (https://github.com/jkroepke/helm-secrets/wiki/ArgoCD-Integration)
- [ksops] (https://github.com/viaduct-ai/kustomize-sops#argo-cd-integration-)

#### Ref
- SOPS https://github.com/mozilla/sops#sops-secrets-operations
- Secrets With SOPS https://dev.to/aarushikansal/secrets-with-sops-2h5e
- KSOPS https://github.com/viaduct-ai/kustomize-sops#ksops---a-flexible-kustomize-plugin-for-sops-encrypted-resource