# SOPS Encryption Workflow Rules
## Rule
Secret files MUST be encrypted before committing. CI MUST verify all secret files are encrypted. Never store decrypted secrets on disk in production. Use sops exec-env or exec-file for runtime access.
## Workflow
```bash
# 1. Create/edit secrets (opens in $EDITOR, saves encrypted)
sops secrets/production.enc.yaml
# 2. Verify file is encrypted before committing
sops --decrypt secrets/production.enc.yaml > /dev/null 2>&1
# Exit 0 = valid encrypted file
# 3. Commit encrypted file
git add secrets/production.enc.yaml
git commit -m "chore: update production database credentials"
# 4. Runtime decryption (never to disk)
sops exec-env secrets/production.enc.yaml 'node server.js'
# Secrets available as environment variables during execution
```
## Good Examples
```bash
# Edit in-place (encrypts on save)
sops secrets/staging.enc.yaml
# Decrypt to stdout (pipe, never to file)
sops --decrypt secrets/production.enc.yaml | kubectl apply -f -
# Runtime: inject as env vars
sops exec-env secrets/production.enc.yaml './start-server.sh'
# Runtime: inject as temporary file
sops exec-file secrets/production.enc.yaml 'cat {}'
# Rotate encryption keys
sops --rotate --in-place secrets/production.enc.yaml
# Verify encryption in CI
for f in secrets/*.enc.yaml; do
if ! sops --decrypt "$f" > /dev/null 2>&1; then
echo "ERROR: $f is not properly encrypted"
exit 1
fi
done
```
## Bad Examples
```bash
# BAD: Decrypting to a file on disk
sops --decrypt secrets/production.enc.yaml > secrets/production.yaml
# Plaintext secrets now on disk — can be accidentally committed
# BAD: Committing decrypted secrets
git add secrets/production.yaml # PLAINTEXT!
# BAD: No CI verification — encrypted status not checked
# A developer could accidentally commit an unencrypted file
```
## Enforcement
- Pre-commit hook: verify all *.enc.* files are encrypted
- CI: validate encryption status of all secret files
- .gitignore: ignore all non-.enc secret file patterns
- Use sops exec-env instead of decrypting to disk