Secret Management (SOPS + Age)¶
Key Concepts¶
- Age generates a keypair. Public key goes in
.sops.yaml. Private key stays local (~/.config/sops/age/keys.txt). - SOPS encrypts/decrypts files using the Age public key. Encrypted files are safe to commit.
.secrets/is gitignored — decrypted values live here only during active sessions.
Key Lifecycle¶
Generate operator key¶
bash
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
cat ~/.config/sops/age/keys.txt # note the public key line
Add key to .sops.yaml¶
Edit .sops.yaml and replace age1REPLACE_WITH_... with your public key.
Encrypt a new secret file¶
bash
cat > /tmp/mysecret.yaml <<EOF
my_key: my_value
EOF
sops --encrypt --age age1YOURPUBLICKEY /tmp/mysecret.yaml > secrets/local/mysecret.sops.yaml
Decrypt for use¶
```bash bash scripts/decrypt-secrets.sh local
Output: .secrets/local/mysecret.yaml¶
```
Edit in-place¶
bash
sops secrets/local/cluster.sops.yaml
Rotate key¶
```bash sops updatekeys secrets/local/cluster.sops.yaml
Add new recipient to .sops.yaml first¶
```
CI Key¶
Store the CI Age private key as SOPS_AGE_KEY GitHub Actions secret.
Add the corresponding public key to all path_regex entries in .sops.yaml.
Rules¶
- Never commit
.secrets/— it is gitignored - Never hardcode secrets in HCL, YAML, or shell scripts
- All secret files must end in
.sops.yaml detect-secretspre-commit hook will block plaintext leaks