How to set up SOPS with age keys
This guide walks through setting up the local toolchain needed to create and work with encrypted files in a CoB project. Once set up, you will be able to encrypt new secret files that cob-cli can deploy and have decrypted on the server.
Prerequisites
# macOS
brew install sops age
# Windows
winget install --id FiloSottile.age
winget install --id SecretsOPerationS.SOPSGenerate an age key pair and save it to 1Password
Copy and paste this script to generate the key and store it directly in 1Password without writing it to disk:
age_key_output=$(age-keygen)
age_private_key=$(echo "$age_key_output" | grep -o 'AGE-SECRET-KEY-[[:alnum:]]*')
age_public_key=$(echo "$age_key_output" | grep -o 'age1[[:alnum:]]*')
op item create --category=Login --title="cob-cli key" --vault="Employee" \
"username=$age_public_key" \
"password=$age_private_key"WARNING
The Vault Employee was named Private in older versions of 1password so the command above may give an error for not finding the vault.
This is a known naming inconsistency in 1Password. They renamed Teams and Business "private vaults" to "employee vaults" to reduce confusion between work and personal accounts, but no functionality actually changed — just the name. In this case you can chek that the UUID of the vault is the same but the label changed. Solution is changing Employee to Privatein the command above
The public key (saved as username) is safe to share and will be added to the repository configuration. The private key (stored as password) never touches disk.
Add your key to .sops.yaml
The repository should already contain a .sops.yaml at its root, with the server's key. Open it and add your public key as a new entry:
creation_rules:
- age:
# server
- age1lggyhqjt3nu3tqe5ld8stpkdqe...
# <your name>
- age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7...Replace the second key with your own public key from the previous step, and update the comment to identify yourself. Commit the change — .sops.yaml contains only public keys and is safe to version-control.
TIP
If the file does not exist please contact Cult Of Bits support.
Make the private key available to SOPS
Set SOPS_AGE_KEY_CMD to have SOPS retrieve the private key from 1Password on demand:
export SOPS_AGE_KEY_CMD='op read "op://Employee/cob-cli key/password"'SOPS will run this command each time it needs the private key, prompting 1Password to authenticate if the session has expired.
Add this to your shell profile.
Before relying on the setup, verify that op can retrieve the key correctly:
eval $SOPS_AGE_KEY_CMDThis should print the AGE-SECRET-KEY-... line. If 1Password prompts for authentication, sign in and run it again.
Alternative: key file
If you are not using 1Password, generate the key to a file instead:
age-keygen -o age-key.txtThen point SOPS at it:
export SOPS_AGE_KEY_FILE=/path/to/age-key.txtAdd this to your shell profile. Keep the key file outside the repository directory. Do not set both SOPS_AGE_KEY_CMD and SOPS_AGE_KEY_FILE at the same time.
Verify the setup
Check that SOPS can encrypt and decrypt with your key. In a server_* local repo, with an existing .sops.yaml file:
echo "test: secret" > /tmp/test.yml
sops --encrypt /tmp/test.yml > /tmp/test.yml.enc
sops --decrypt --input-type yaml --output-type yaml /tmp/test.yml.encIf the last command prints test: secret, the setup is complete.
