Skip to content

Reference

Scope

Look-up facts for SOPS 3.13.x: releases, file formats, key backends, CLI subcommands, environment variables, the .sops.yaml schema, the on-disk format, GitOps integration keys and a hardening checklist. For the reasoning behind these, see Explanation. For step-by-step tasks, see How-to Guides.

Release History

SOPS publishes signed binaries, .deb/.rpm packages, SBOMs and container images for each release. The project has no published LTS or support-window policy. Fixes land in the next patch or minor release of the current line (TBD: no official support policy found as of 2026-09).

Version Release date Highlights
3.13.3 2026-07-23 Fixes a 3.13.2 regression that computed a wrong MAC for YAML lists containing comments. Fixes completion output
3.13.2 2026-06-30 exec-env/exec-file --user resets supplementary groups and sets HOME/USER/LOGNAME. JSON store keeps large int64 values. INI metadata newline fix
3.13.1 2026-05-16 Documentation moves from the README to getsops.io. Fixes the gpg-agent cache key for password-protected age keys
3.13.0 2026-05-08 SOPS_HC_VAULT_ALLOWLIST (Vault/OpenBao URL allowlist). SOPS_GCP_KMS_ENDPOINT and SOPS_GCP_KMS_UNIVERSE_DOMAIN. YAML inline comments preserved. SOPS_AGE_KEY accepts space-separated keys. Drops Go 1.24. cosign v3 signing
3.12.2 2026-03-18 Reverts the GCP quota-project change from 3.12.0 (it needed extra permissions). Cleans up temp files on Ctrl+C/SIGTERM during edit
3.12.1 2026-02-22 Re-release of 3.12.0 with no code changes (the 3.12.0 release failed)
3.12.0 2026-02-19 (tag) HuaweiCloud KMS backend. age hybrid post-quantum identities. SOPS_AGE_SSH_PRIVATE_KEY_CMD. SOPS_GCP_KMS_CLIENT_TYPE (gRPC or REST)
3.11.0 2025-09-28 Security: temp edit file is owner-only, and binary-store encryption-selection options are ignored. sops set --value-file and --value-stdin. Shell completion. Keys as YAML lists in .sops.yaml. Azure key version optional
3.10.2 2025-04-14 YAML store bug fix
3.10.1 2025-03-31 Re-release of 3.10.0 (the Go module cache held a different commit)
3.10.0 2025-03-30 Security: Shamir timing fix (GHSA-vq4h-9ghm-qmrr). age plugins, SSH keys as age recipients, passphrase-protected age identities, SOPS_AGE_KEY_CMD, SOPS_EDITOR, SOPS_CONFIG, set --idempotent, stdin for encrypt/decrypt
3.9.0 2024-06-28 Separate subcommands (encrypt, decrypt, edit, rotate, set, unset, filestatus). --mac-only-encrypted. --decryption-order. Comment-based encryption selection. Key-group merge
3.8.0 2023-09-15 First release under the getsops org: AWS SDK v2, refreshed PGP/Azure/GCP/Vault backends

Dates are the GitHub release/tag dates. See the changelog and releases.

Distribution Artifacts

Artifact Name pattern (3.13.3 example)
Linux binary sops-v3.13.3.linux.amd64, sops-v3.13.3.linux.arm64
macOS binary sops-v3.13.3.darwin.amd64, sops-v3.13.3.darwin.arm64, universal sops-v3.13.3.darwin
Windows binary sops-v3.13.3.amd64.exe, sops-v3.13.3.arm64.exe
Packages .deb and .rpm
Container images ghcr.io/getsops/sops:v3.13.3 and quay.io/getsops/sops:v3.13.3 (Debian-based), plus -alpine tags
Supply chain sops-v3.13.3.checksums.txt, cosign signatures, SPDX SBOMs
Go library github.com/getsops/sops/v3 (the decrypt package). Building from source needs Go >= 1.25

File Formats

The store is chosen from the file extension, or from --input-type / --output-type (yaml, json, dotenv, ini, binary).

Format Extensions What is encrypted Limits
YAML .yaml, .yml Leaf values and comments. Keys stay plaintext No anchors/aliases. No top-level arrays. Multi-document streams share one sops block
JSON .json Leaf values. Keys stay plaintext No top-level arrays. Default indent is one tab
ENV (dotenv) .env Values. Variable names stay plaintext Flat key/value only
INI .ini Values. Sections and keys stay plaintext Metadata is flattened into a [sops] section
BINARY anything else The whole file as one blob, stored base64-encoded under data in a JSON document Encryption-selection options are ignored (since 3.11.0)

Key Backends

Backend CLI flag Env var (encrypt) .sops.yaml creation-rule key Key-group key Authentication
age (X25519, SSH, plugins, post-quantum) --age SOPS_AGE_RECIPIENTS age age Local identity file, SOPS_AGE_KEY, SOPS_AGE_KEY_CMD, SSH key
PGP / GnuPG --pgp SOPS_PGP_FP pgp pgp gpg-agent keyring (SOPS_GPG_EXEC overrides the binary)
AWS KMS --kms (ARN+ROLE_ARN) SOPS_KMS_ARN kms (+ aws_profile) kms (arn, role, context, aws_profile) AWS SDK v2 default chain, profiles, assumed roles
GCP Cloud KMS --gcp-kms SOPS_GCP_KMS_IDS gcp_kms gcp_kms (resource_id) Application Default Credentials, GOOGLE_OAUTH_ACCESS_TOKEN
Azure Key Vault --azure-kv SOPS_AZURE_KEYVAULT_URLS azure_keyvault azure_keyvault (vaultUrl, key, version) DefaultAzureCredential (env, workload identity, managed identity, Azure CLI)
HashiCorp Vault / OpenBao Transit --hc-vault-transit SOPS_VAULT_URIS hc_vault_transit_uri hc_vault VAULT_TOKEN or ~/.vault-token. SOPS_HC_VAULT_ALLOWLIST limits which servers are contacted
HuaweiCloud KMS (since 3.12.0) --hckms (region:key-uuid) SOPS_HUAWEICLOUD_KMS_IDS hckms hckms (key_id) HUAWEICLOUD_SDK_AK/_SK/_PROJECT_ID, ~/.huaweicloud/credentials, instance metadata

PGP status

PGP is not deprecated in SOPS 3.13.3. The docs say "it's recommended to use age over PGP, if possible", and Flux says the same. Nothing in the changelog announces PGP removal.

age Recipient and Identity Types

Type Recipient prefix Identity prefix Since
Native X25519 age1... AGE-SECRET-KEY-1... 3.7.0
SSH (ssh-ed25519, ssh-rsa only) ssh-ed25519 AAAA..., ssh-rsa AAAA... ~/.ssh/id_ed25519, ~/.ssh/id_rsa, or SOPS_AGE_SSH_PRIVATE_KEY_FILE/_CMD 3.10.0
Plugin (for example age-plugin-yubikey) age1<plugin>1... AGE-PLUGIN-... 3.10.0
Hybrid post-quantum (ML-KEM-768 + X25519) age1pq1... (~2,000 characters) AGE-SECRET-KEY-PQ-1... 3.12.0 (needs age >= v1.3.0 keys)

age Identity Lookup

Platform Default keys.txt location
Linux $XDG_CONFIG_HOME/sops/age/keys.txt, falling back to $HOME/.config/sops/age/keys.txt
macOS $XDG_CONFIG_HOME/sops/age/keys.txt, falling back to $HOME/Library/Application Support/sops/age/keys.txt
Windows %AppData%\sops\age\keys.txt

Since 3.11.0, identities from all sources are loaded: the default file, SOPS_AGE_KEY_FILE, SOPS_AGE_KEY, SOPS_AGE_KEY_CMD (it receives SOPS_AGE_RECIPIENT since 3.12.0) and SSH keys.

CLI Subcommands

Subcommand Purpose
sops encrypt / decrypt Encrypt or decrypt to stdout. -i/--in-place writes back. Reads stdin when no file is given (use --filename-override to pick a creation rule)
sops edit Decrypt into $SOPS_EDITOR/$EDITOR (falls back to vim, nano, vi), then re-encrypt. Creates new files from .sops.yaml rules
sops rotate New data key, re-encrypts all values. --add-* / --rm-* flags change master keys at the same time
sops updatekeys Re-sync master keys with .sops.yaml without changing the data key. -y skips the prompt. Accepts several files
sops set / unset Set or remove one tree path ('["a"]["b"]'). Value as JSON, --value-file or --value-stdin (3.11.0). --idempotent (3.10.0)
sops decrypt --extract Print one tree path, for example '["data"]["password"]'
sops filestatus Report whether a file is SOPS-encrypted (JSON output)
sops exec-env / exec-file Run a command with secrets in its environment or in a FIFO/temp file. --user drops privileges. --background is deprecated
sops groups add / delete Manage key groups on a file
sops keyservice Run a gRPC key service (unauthenticated: tunnel it, for example over SSH)
sops publish Re-encrypt and upload files to S3, GCS or Vault KV via destination_rules
sops completion bash/zsh Shell completion scripts (3.11.0)

The legacy top-level flags sops -e, sops -d and sops -r still work in 3.13.3. Combining several of them is deprecated. sops --version checks for updates unless you pass --disable-version-check or set SOPS_DISABLE_VERSION_CHECK=true (3.10.0 deprecated the implicit check).

Environment Variables

Variable Effect
SOPS_CONFIG Path to the config file (instead of searching for .sops.yaml)
SOPS_EDITOR Editor for sops edit (falls back to EDITOR)
SOPS_DECRYPTION_ORDER Comma-separated backend order. Default age,pgp. Offline methods go first, then the rest
SOPS_AGE_RECIPIENTS age recipients for encryption
SOPS_AGE_KEY, SOPS_AGE_KEY_FILE, SOPS_AGE_KEY_CMD age identities: inline, file, or command output
SOPS_AGE_SSH_PRIVATE_KEY_FILE, SOPS_AGE_SSH_PRIVATE_KEY_CMD SSH private key used as an age identity
SOPS_PGP_FP, SOPS_GPG_EXEC PGP fingerprints, and an alternative gpg binary
SOPS_KMS_ARN AWS KMS ARNs (optionally +ROLE_ARN)
SOPS_GCP_KMS_IDS, SOPS_GCP_KMS_CLIENT_TYPE, SOPS_GCP_KMS_ENDPOINT, SOPS_GCP_KMS_UNIVERSE_DOMAIN GCP KMS keys, grpc (default) or rest client, sovereign-cloud endpoint overrides
SOPS_AZURE_KEYVAULT_URLS Azure Key Vault key URLs
SOPS_VAULT_URIS, SOPS_HC_VAULT_ALLOWLIST Vault/OpenBao transit URIs, and a URL-prefix allowlist (all by default, none blocks all)
SOPS_HUAWEICLOUD_KMS_IDS HuaweiCloud KMS key IDs
SOPS_KEYSERVICE, SOPS_ENABLE_LOCAL_KEYSERVICE Remote key service address, and whether to use the in-process one
SOPS_DISABLE_VERSION_CHECK Skip the network version check on --version

.sops.yaml Schema

SOPS looks for .sops.yaml in the current working directory and its parents, not next to the target file. It must be named .sops.yaml. Since 3.10.0 SOPS warns when it finds a .sops.yml. Top-level keys: creation_rules, destination_rules, stores.

Creation-rule key Type Meaning
path_regex string Regex matched against the file path relative to the config file. Omitted = match everything. The first matching rule wins
age, pgp, kms, gcp_kms, azure_keyvault, hc_vault_transit_uri string (comma-separated) or list Recipients for a single key group. Lists since 3.11.0
hckms list HuaweiCloud KMS key IDs
aws_profile string AWS profile for the rule's kms keys
key_groups list of key groups Several groups for Shamir splitting. Overrides the single-group keys
shamir_threshold int 0 (default = all groups required) or >= 2
mac_only_encrypted bool true = MAC covers only encrypted values (default false)
unencrypted_suffix / encrypted_suffix string Select values by key suffix. Default: _unencrypted suffix leaves a value plaintext
unencrypted_regex / encrypted_regex string Select values by key regex
unencrypted_comment_regex / encrypted_comment_regex string Select values by a preceding or trailing comment (YAML)

Only one of the six selection options may be set per rule. Key groups also accept merge (a list of key groups whose keys are concatenated, useful with YAML anchors). destination_rules (for sops publish) accept path_regex, s3_bucket, s3_prefix, gcs_bucket, gcs_prefix, vault_path, vault_address, vault_kv_mount_name, vault_kv_version, recreation_rule and omit_extensions. stores accepts yaml.indent (default 4, range 2-9), json.indent and json_binary.indent (default -1 = tab, 0 = none).

On-Disk Format

Element Format
Encrypted value ENC[AES256_GCM,data:<b64>,iv:<b64>,tag:<b64>,type:<str\|int\|float\|bool\|bytes\|time\|comment>]
Cipher AES-256-GCM with a 256-bit data key and a 256-bit (32-byte) random IV per value
AAD Concatenated key path of the value, which binds each ciphertext to its location in the tree
MAC SHA-512 over the plaintext values (all values, or only encrypted ones with mac_only_encrypted), stored AES-GCM-encrypted in sops.mac
Metadata block sops: with per-backend lists (kms, gcp_kms, azure_kv, hc_vault, age, pgp, hckms) or key_groups + shamir_threshold, then lastmodified, mac, version, and any selection option (encrypted_regex, mac_only_encrypted, and so on)
Per-key entry Backend identifier (arn [+ role, context, aws_profile], resource_id, vault_url + name + version, vault_address + engine_path + key_name, key_id, recipient, fp) plus enc (encrypted data key or Shamir share). All except age also store created_at

Empty backend lists are omitted from metadata since 3.10.0. SOPS guarantees backward compatibility of the file format within the major version.

GitOps Integration Reference

Tool Mechanism Key/credential delivery
Flux kustomize-controller Native: Kustomization.spec.decryption.provider: sops Secret in .spec.decryption.secretRef with entries *.agekey, *.asc (PGP), sops.aws-kms, sops.azure-kv, sops.gcp-kms, sops.vault-token. Or workload identity via .spec.decryption.serviceAccountName (feature gate ObjectLevelWorkloadIdentity, kustomize-controller >= v1.6.0). OpenBao/Vault Kubernetes auth via --sops-vault-configmap (kustomize-controller v1.9.0, 2026-06-17)
Argo CD + KSOPS Kustomize KRM exec plugin (apiVersion: viaduct.ai/v1, kind: ksops) run by the repo-server Keys mounted into argocd-repo-server. Needs kustomize build --enable-alpha-plugins --enable-exec
Argo CD + helm-secrets Helm plugin that decrypts SOPS-encrypted values files (secrets:// value-file URLs) Keys in the repo-server. See the helm-secrets ArgoCD wiki
Argo CD + argocd-vault-plugin AVP_TYPE: sops backend fills <placeholders> from a SOPS file Keys in the plugin sidecar
Terraform / OpenTofu carlpett/sops provider: data "sops_file", plus an ephemeral resource (provider >= v1.3.0, Terraform >= 1.11) that keeps plaintext out of state Local keys or cloud credentials of the runner

Flux requires apiVersion, kind and metadata to stay plaintext. Use encrypted_regex: ^(data|stringData)$ for Kubernetes Secrets.

Backend Audit Trails

Backend Audit mechanism
AWS KMS CloudTrail logs Decrypt/Encrypt calls with key ARN, principal and timestamp. Encryption context appears in the log
GCP KMS Cloud Audit Logs (Data Access logs must be enabled) for Decrypt/Encrypt
Azure Key Vault Key Vault diagnostic logs (AuditEvent) via Azure Monitor
Vault / OpenBao Audit devices log every transit encrypt/decrypt request
age / PGP No server-side trail. Audit at the file level (Git history, filesystem ACLs)
SOPS itself Optional: logs each decryption to PostgreSQL, configured in /etc/sops/audit.yaml (schema audit/schema.sql)

Performance Characteristics

SOPS has no published benchmark suite. Treat the following as qualitative guidance. Measure on your own workload before capacity planning.

Factor Effect
Local backends (age, PGP) No network call. Data-key decryption is dominated by process start-up and, for PGP, by gpg-agent
Cloud KMS and Vault/OpenBao One network round trip per master key tried. --decryption-order puts the cheapest or most available backend first
Key groups (Shamir) One successful master-key decryption per group up to the threshold
File size Every leaf is encrypted separately (AES-GCM plus a base64-encoded 32-byte IV and 16-byte tag), so ciphertext files are much larger than plaintext ones. Binary files grow by the base64 overhead
Measured latencies TBD: no controlled benchmark with documented conditions found

Hardening Checklist

  • Use age (or cloud KMS) for new files. Keep PGP only where existing workflows depend on it.
  • Configure at least two independent master keys (for example KMS in two regions plus an offline age key) or key groups for separation of duty.
  • Anchor path_regex patterns (^secrets/prod/.*\.yaml$) and put the catch-all rule last.
  • For Kubernetes manifests, set encrypted_regex: ^(data|stringData)$ and keep mac_only_encrypted off unless you need to edit plaintext fields outside SOPS.
  • Store age private keys with 0600 permissions. In CI, inject SOPS_AGE_KEY from the secret store instead of writing a file.
  • Use AWS KMS encryption context and key policies to bind keys to environments.
  • Set SOPS_HC_VAULT_ALLOWLIST when files come from untrusted sources (3.13.0+).
  • After removing a key, run sops updatekeys then sops rotate -i, and then rotate the underlying credentials.
  • Never expose sops keyservice without an authenticated, encrypted tunnel.
  • Pin the SOPS version in CI and verify release checksums/cosign signatures.

Sources