How to Install and Use SOPS on Linux to Encrypt Secrets and Configuration Files

Storing unencrypted API keys, database credentials, and certificates in version control repositories is one of the most common causes of enterprise security breaches. While tools like git-crypt or raw GPG scripts provide basic encryption, they treat files as opaque binary blobs, making code reviews and Git diff inspections impossible. SOPS (Secrets OPerationS, developed by Mozilla) solves this by encrypting only the values inside structured files (such as YAML, JSON, ENV, and INI) while leaving the keys and structure in readable plaintext.

This tutorial explains how to install SOPS on Linux, integrate modern age encryption keys, encrypt and edit configuration files seamlessly, and decrypt secrets within automated CI/CD and GitOps workflows.

Installing SOPS on Linux Distributions

SOPS is distributed as a single statically linked binary with zero external dependencies and is available across major Linux packaging ecosystems.

Method 1: Downloading Official GitHub Release Binaries (Recommended)

Fetch the latest stable x86_64 binary directly from the GitHub releases page:

# Download the latest Linux release
curl -L https://github.com/getsops/sops/releases/latest/download/sops-v3.9.4.linux.amd64 -o /tmp/sops

# Make executable and move to system path
chmod +x /tmp/sops
sudo mv /tmp/sops /usr/local/bin/sops

# Verify installation
sops --version

Method 2: Installing via Native Package Managers

On Arch Linux and Manjaro:

sudo pacman -S sops

On systems running Homebrew on Linux:

brew install sops

Setting Up age Encryption Keys with SOPS

While SOPS supports PGP, AWS KMS, Google Cloud KMS, and Azure Key Vault, the modern lightweight cryptographic standard for local and Kubernetes secret management is age.

  1. Install age on your Linux machine:
    sudo apt install age -y # Debian/Ubuntu
    sudo dnf install age -y # Fedora/RHEL
  2. Generate a dedicated secret keypair:
    mkdir -p ~/.config/sops/age
    age-keygen -o ~/.config/sops/age/keys.txt
  3. Export the key location in your shell environment (add this to ~/.bashrc or ~/.zshrc):
    export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/keys.txt"
  4. Inspect your public recipient key:
    age-keygen -y ~/.config/sops/age/keys.txt
    (The output begins with age1...).

Configuring Declarative Encryption Rules (.sops.yaml)

To avoid typing lengthy key flags for every command, define a root configuration file named .sops.yaml in your project repository:

creation_rules:
  - path_regex: '.*\.encrypted\.ya?ml$'
    age: 'age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p'
  - path_regex: '.*\.env$'
    age: 'age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p'

This declarative rule instructs SOPS to automatically encrypt any file ending in .encrypted.yaml or .env using your designated public age recipient.

SOPS Command Syntax Example Operational Function
sops -e (Encrypt) sops -e secrets.yaml > secrets.enc.yaml Encrypts values in-place or redirects encrypted output to a new file.
sops -d (Decrypt) sops -d secrets.enc.yaml Decrypts file content and prints plaintext to stdout or stdout pipe.
sops <file> (In-Place Edit) sops secrets.enc.yaml Decrypts file in RAM, launches your $EDITOR, and re-encrypts upon save.
sops exec-env sops exec-env secrets.env 'npm start' Injects decrypted environment variables directly into a running process.

Editing Encrypted Files In-Place

One of SOPS’s most powerful features is transparent in-place editing:

  1. Create an initial secret YAML file:
    sops secrets.encrypted.yaml
  2. Your default text editor (defined by $EDITOR, e.g. nano or vim) launches.
  3. Type your configuration keys and values:
    database:
      host: postgres.internal
      username: app_user
      password: SuperSecretDatabasePassword123!
    api_tokens:
      stripe: sk_live_51Nz849129038401
  4. Save and exit your editor.
  5. Inspect the file on disk: cat secrets.encrypted.yaml. The keys (database, host, password) remain completely visible, but the values are replaced with encrypted ciphertext strings (e.g. ENC[AES256_GCM,data:...]) alongside cryptographic integrity hashes.

GitOps & Code Review Advantage

Because keys remain unencrypted in Git diffs, peer reviewers can easily verify that a new configuration key was added or an endpoint URL was altered without requiring access to the production decryption keys.

Deploying Secrets Without Writing Decrypted Files to Disk

To prevent leaking unencrypted secrets to temporary disk logs, inject decrypted variables straight into memory:

sops exec-env .env.encrypted 'python app.py'

In Kubernetes deployments, you can pipe decrypted manifests directly to kubectl:

sops -d k8s-secrets.encrypted.yaml | kubectl apply -f -

Troubleshooting Common SOPS Errors

If SOPS fails to encrypt or decrypt configuration payloads, verify these settings:

  • Error: Could not find key file: If SOPS returns no age keys found, ensure the environment variable SOPS_AGE_KEY_FILE points to your keys.txt file path, or specify the key directly via export SOPS_AGE_KEY=$(cat keys.txt) in CI/CD pipelines.
  • Integrity Check Failed (MAC Mismatch): SOPS embeds a Message Authentication Code (MAC) verifying that keys and unencrypted metadata were not tampered with. If someone manually modifies the encrypted YAML file outside of SOPS, decryption aborts to prevent malicious payload injections.
  • Multiple Recipients / Team Collaboration: To allow multiple developers or CI/CD runners to decrypt the same file, add their public age keys as a comma-separated list under the age: directive in .sops.yaml and re-encrypt the file using sops updatekeys secrets.encrypted.yaml.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.