SOPS Usage Guide
Setup
Installation
You can install SOPS either by downloading the binary directly or using a package manager.
From Repository or Binary
- Visit the SOPS GitHub Repository.
- Download the binary (ensure you select the appropriate version for your OS and architecture):
curl -LO https://github.com/getsops/sops/releases/download/v3.9.2/sops-v3.9.2.linux.amd64 - Move the binary to your
PATH:mv sops-v3.9.2.linux.amd64 /usr/local/bin/sops - Make the binary executable:
chmod +x /usr/local/bin/sops
tldr:
curl -LO https://github.com/getsops/sops/releases/download/v3.9.2/sops-v3.9.2.linux.amd64 && mv sops-v3.9.2.linux.amd64 /usr/local/bin/sops && chmod +x /usr/local/bin/sops
From a Package Manager (macOS Example)
Install SOPS using Homebrew:
brew install sops
GPG Keys Setup
Check Existing GPG Keys
To list your GPG keys:
- Private keys:
gpg -K - Public keys:
gpg -k
Create a New GPG Key
Follow the GitHub guide for generating GPG keys. Key generation steps include:
- Generate a new key:
gpg --default-new-key-algo ed25519 --full-generate-key - List the public key IDs:
gpg --list-secret-keys --keyid-format=long - Export your public key:
gpg --armor --export ${YOUR_KEY_ID}
Add Your Public Key to GitHub
- Copy your GPG public key. It starts with:
And ends with:-----BEGIN PGP PUBLIC KEY BLOCK----------END PGP PUBLIC KEY BLOCK----- - Follow GitHub's guide to add the key.
Working with Encrypted Files
Basic Operations
Decrypting Files
To decrypt a file, you must have a private key listed in the sops metadata of the encrypted file.
Encrypting Files
To encrypt a file, you need all public keys that will be used for encryption. Add your public key to GitHub so others can import it from your profile.
For advanced use cases (e.g., encrypting with AWS KMS or Age), refer to the SOPS repository documentation.
Editing an Encrypted File
- Edit an encrypted file with your default editor:
sops file.yaml - To use a specific editor:
EDITOR='code --wait' sops file.yaml - Commit changes:
- Add the modified lines to the git index.
Note: If changes are made outside SOPS, the file won't decrypt properly. Use the
--ignore-macoption if needed.
Encrypting a File
To encrypt a file with a GPG key:
sops -e -i --pgp "${GPG_KEY_ID}"
# Options:
# -e: Encrypt
# -i: In-place encryption
# --pgp: Specify public GPG keys for encryption
# "${GPG_KEY_ID}" -- Public key ids separated with comma
Decrypting a File
- Decrypt to stdout:
sops -d file.yaml - Decrypt in place:
sops -i -d file
gpg tty on macos
- Проверить что
which pinentry-macчто-то отдаст иначе установить черезbrew isntall pinentry-mac - Добавить в файл конфигурации
~/.gnupg/gpg-agent.conf
default-cache-ttl 34560000
max-cache-ttl 34560000
max-cache-ttl-ssh 34560000
default-cache-ttl-ssh 34560000
pinentry-program /usr/local/bin/pinentry-mac
export GPG_TTY=$(tty)и добавить эту строку в~/.zshrc- Перезагрузить gpg-agent
gpgconf --kill gpg-agent
Case Setting Up a New Repository for SOPS
Example .sops.yaml
Create a .sops.yaml file in the repository root. This file defines keys and rules for encryption.
# YAML Formatting:
stores:
yaml:
indent: 2
# Encryption Rules:
creation_rules:
- pgp: >- ## List of GPG key IDs for encryption
14E89E005155B68088D72693D7D61759A1EEEB5D,
CD10A854ADDD2402BE1EF5AD075D1B59D139D890,
5EF7079DE682A4BA200A834726EA0666E4FE5472,
713429BA80BCB22675989D3AD1C9A13C324ECE5E
## <devops@occam.fi>,<mikhail@occam.fi>,<ilya@occam.fi>,<yakudgm@gmail.com>
# encrypted_regex: ^SecretEnv ## (Optional) Regex for encrypting specific YAML keys inside files
# path_regex: values.*.yaml$ ## (Optional) Regex to target specific files
Encrupt files with sops
sops -e -i ops/helm-values/dev/app.sops.yaml
Case: decrypt in github actions
- setup secret variable to get ci gpg key into action
export REPO=owner/repo
export VALUE=$(gpg --export-secret-keys 14E89E005155B68088D72693D7D61759A1EEEB5D | base64)
# with a github cli
gh secret set SOPS_CI_KEY --repo ${REPO} --body "$VALUE"
## gh secret set SOPS_CI_KEY --repo https://github.com/badaitech/bad-connector --body "$(gpg --export-secret-keys 14E89E005155B68088D72693D7D61759A1EEEB5D | base64)"
# or in settings of the repo
- make sure that gpg available in github runner
jobs:
job:
steps:
- uses: mdgreenwald/mozilla-sops-action@v1.6.0
- name: import gpg ci key
run: |
echo ${{ secrets.SOPS_CI_KEY }} | base64 -d | gpg --import
# ... do stuff
- name: deploy
run: |
sops -d config.sops.yaml > config.yaml
- name: delete ci gpg key
if: always()
run: |
gpg -K --with-colons | awk -F: '/^(fpr)/ {print $10; exit}' | xargs gpg --delete-secret-and-public-keys --yes --batch
Case: replace one key with another
export oldkey=9585F123A7E98549AD7E88FA300C05FE86177A5C
export newkey=96F339BEC4A967D173406DE0E189CDDBCAF01351
rg "fp: $oldkey" -l | xargs -n1 sops -r -i --add-pgp=$newkey --rm-pgp=$oldkey
Advanced case: with ansible
https://docs.ansible.com/ansible/latest/collections/community/sops/load_vars_module.html
- name: Configure PostgreSQL Role and Database
hosts: psql-prod
become: true
vars:
db_environment: bad_connector_stage
pre_tasks:
- name: Include variables of secrets.sops.yaml into the variable
community.sops.load_vars:
file: ./../secret.sops.yaml
name: secret
- name: Set variables from secret
set_fact:
db_user: "{{ secret['db_environment'][db_environment]['db_user'] }}"
db_password: "{{ secret['db_environment'][db_environment]['db_password'] }}"
db_database: "{{ secret['db_environment'][db_environment]['db_database']}}"
tasks: