CoursesSOPSBeginner

Partial encryption & structure

Values encrypted, keys readable.

Intermediate12 min · lesson 3 of 12

Partial encryption is SOPS’s signature feature: in a structured file it encrypts the values but leaves the keys (field names) and overall structure in cleartext. This is deliberate and valuable — a reviewer can see that db_password and api_token exist and that a change touched db_password, and Git produces a real diff, all without exposing the secret values. It keeps secrets reviewable and version-controlled in a way a fully-opaque blob cannot.

secrets.enc.yaml
database:
host: db.acme.internal # not sensitive -> left readable
password: ENC[AES256_GCM,data:9f2a...,type:str] # sensitive -> encrypted
api:
endpoint: https://api.acme.internal # readable
token: ENC[AES256_GCM,data:k8Fw...,type:str] # encrypted

Controlling what gets encrypted

By default SOPS encrypts all values, but you can scope it with --encrypted-regex (encrypt only keys matching a pattern, e.g. password|token|key) or --unencrypted-regex (leave some readable). This lets you keep non-secret config plainly visible while encrypting just the sensitive fields — useful for a mixed file where most values are safe and a few are secret. The regex lives in .sops.yaml (next lessons) so it applies consistently.

terminal
# encrypt only keys that look secret; leave the rest readable
$ sops -e --encrypted-regex '^(password|token|.*_key)$' --age $AGE_PUB config.yaml
A too-narrow encrypted-regex leaks secrets in plaintext
If you scope encryption with --encrypted-regex and a secret field does not match the pattern, SOPS leaves it in cleartext — and it gets committed exposed. Prefer encrypting everything by default, or make the regex generously match anything remotely sensitive, and review the encrypted file to confirm every secret value shows ENC[...]. A partial-encryption misconfiguration is a silent plaintext leak.