BlogSecrets

Encrypt secrets in Git with SOPS and age

Keep encrypted secrets safely in your repo, decrypt them in CI, and never commit a plaintext credential again.

Mar 3, 2026·8 min readIntermediate

SOPS lets you keep secrets in Git — encrypted. It encrypts only the values in a YAML or JSON file, leaving keys readable, so diffs stay meaningful. Paired with age (a tiny modern encryption tool) there is no KMS bill and no key server to run.

bash — generate a keylive
age-keygen -o key.txt
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8...
keep key.txt out of Git; share only the public key

One .sops.yaml for the repo

.sops.yaml
creation_rules:
- path_regex: secrets/
age: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8...

Encrypt and commit

bash — encrypt in placelive
sops -e -i secrets/prod.yaml
git diff secrets/prod.yaml
db_password: ENC[AES256_GCM,data:9f2a...,type:str]
value encrypted, key still readable — safe to commit
Encrypt before the first commit
Once a plaintext secret is in history, rotating it is the only real fix. Add a gitleaks pre-commit hook so a mistake never lands.

Decrypt in CI

.gitlab-ci.yml
deploy:
variables:
SOPS_AGE_KEY: $AGE_PRIVATE_KEY # from CI secret store
script:
- sops -d secrets/prod.yaml > /tmp/prod.yaml
- kubectl apply -f /tmp/prod.yaml
Go deeper in a courseSOPSEncrypt secrets in Git with SOPS, age, and KMS.View course

Related posts