Encrypt Your Sensitive Information Before Storing It - Encrypting with Mozilla SOPS and AGE
Committing secrets to your Git Repo can expose information like passwords, access tokens, and other types of sensitive information.Some might think that committing secrets to a private Git Repo is OK, but I am here to tell you it’s not.If you’re going to commit secrets to a git repo, private or public, you should encrypt them first using Mozilla SOPS (Secret Operations) and AGE.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.Age is a simple, modern, and secure file encryption tool, format, and build using Go.It can encrypt and decrypt your files making then safe enough to commit to your Git repos!
A HUGE thanks to Datree for sponsoring this video!
Combat misconfigurations. Empower engineers. https://www.datree.io
Install SOPS
You can install sops by following this guide.
test with
1
sops -v
should see
1
sops 3.7.3 (latest)
Install Age
You can install age by following this guide
test age
with
1
age -version
should see
1
v1.0.0
test age-keygen
with
1
age-keygen -version
should see
1
v1.0.0
configure keys
Now that we have age
installed we need to create a public and private key
1
age-keygen -o key.txt
should see
1
2
age-keygen: warning: writing secret key to a world-readable file
Public key: age1epzmwwzw8n09slh0c7z0z52x43nnga7lkksx3qrh07tqz5v7lcys45428t
let’s look at the contents
1
cat key.txt
should see
1
2
3
# created: 2022-09-26T21:55:47-05:00
# public key: age1epzmwwzw8n09slh0c7z0z52x43nnga7lkksx3qrh07tqz5v7lcys45428t
AGE-SECRET-KEY-1HJCRJVK7EE3A5N8CRP8YSDUGZKNW90Y5UR2RGYAS8L279LFP6LCQU5ADNR
Remember this is a secret so keep this safe! Do not commit this!
move the file and add to our shell
1
2
mkdir ~/.sops
mv ./key.txt ~/.sops
add it to our shell
1
2
nano ~/.zshrc
# or nano ~/.bashrc
add to the end of file
1
export SOPS_AGE_KEY_FILE=$HOME/.sops/key.txt
source our shell
1
2
source ~/.zshrc
# or source ~/.bashrc
Now! Let’s encrypt
A few ways you can do this.You can encrypt in place or encrypt with an editor but we’re going to do an in place encryption.
YAML
This can be kubernetes secrets, helm values, or just plain old yaml
create a secret with the following contents
secret.yaml
1
2
3
4
5
6
7
8
9
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
namespace: default
stringData:
MYSQL_USER: root
MYSQL_PASSWORD: super-Secret-Password!!!!
to encrypt
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml
to decrypt
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml
Kubernetes
If you want to decrypt this secret on the fly and apply to kubernetes
encrypt first
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml
decrypt and pipe to kubectl
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' ./secret.yaml | kubectl apply -f -
check it with
1
k describe secrets mysql-secret-test
then
1
kubectl get secret mysql-secret-test -o jsonpath='{.data}'
then
1
kubectl get secret mysql-secret-test -o jsonpath='{.data.MYSQL_PASSWORD}' | base64 --decode
VSCode
install vscode extension
choose the beta for sops because that supports age + sops
don’t forget to add .decrypted~secret.yaml
to .gitignore
encrypt .env files
make sure extension is installed
.ENV Files
create
secret.env
MYSQL_USER=superroot
MYSQL_PASSWORD="super-Secret-Password!!!!############"
encrypt
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i .env
decrypt
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i .env
don’t forget to add .decrypted~secret.env
to your .gitignore
JSON Files
secret.json
1
2
3
4
{
"mySqlUser": "superroot",
"password": "super-Secret-Password!!!!#######"
}
encrypt
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.json
decrypt
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.json
don’t forget to add .decrypted~secret.json
to your .gitignore
INI Files
secret.ini
1
2
3
[database]
user = superroot
password = super-Secret-Password!!!!1223
encrypt
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.ini
decrypt
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.ini
don’t forget to add .decrypted~secret.ini
to you .gitignore
Files
secret.sql
1
2
3
--- https://xkcd.com/327/
--- DO NOT USE
INSERT INTO Students VALUES ( 'Robert' ); DROP TABLE STUDENTS; --' )
encrypt
1
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --in-place ./secret.sql
decrypt
1
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --in-place ./secret.sql
Flux
If you’re thinking of doing GitOps with Flux, you can check out my video on this topic or see my documentation.You can do cluster decryption and fully automate decryption of secrets.
In cluster decryption with Flux
https://fluxcd.io/flux/guides/mozilla-sops/#configure-in-cluster-secrets-decryption
Join the conversation
People often ask if it's OK to save secrets in code or config to a private git repo. I though this was ok until now...
— Techno Tim (@TechnoTimLive) October 1, 2022
If you're using Secrets in Kubernetes or ENVs in Docker I highly recommend encrypting them with Mozilla SOPS.@mozhacks https://t.co/r1NpBoGWe2 pic.twitter.com/sdPFq06WQM
Links
⚙️ See all the hardware I recommend at https://l.technotim.live/gear
🚀 Don’t forget to check out the 🚀Launchpad repo with all of the quick start source files