hardware🔐Hardware-backed identities
Your private key is generated inside hardware and cannot be read, copied, or exfiltrated: the Secure Enclave of an Apple Silicon Mac (Touch ID), or a YubiKey PIV slot (PIN and a touch) on Intel Macs and Linux. Only the public recipient is ever shared.
init📦One-command bootstrap
sopsy init installs missing tools, then writes .sops.yaml, .env.example, an encrypted .env.encrypted, .gitignore safety rules, and .sopsy.yml, and sets up the break-glass key. Idempotent — re-running is always safe.
stores🗝️Key stores & repo policy
Four stores, strongest first: enclave, yubikey, keychain (macOS Keychain or Linux Secret Service), and a plaintext file as a last resort. --store auto picks the best one your machine has; sopsy init --allow-stores decides which ones members may use, hardware only by default. Hardware always beats software, whatever order the list is in.
diagnostics🩺doctor health checks
macOS, Apple Silicon, Secure Enclave, Touch ID, YubiKey, every external tool, and repo health — a colorful report you can paste straight into an issue. sopsy deps is the remedy: it installs whatever doctor found missing, ykman included.
edit✏️Friendlier edits
Open an encrypted file through SOPS with automatic file-type detection and nicer errors. Your $EDITOR, your workflow — none of the flag-juggling.
secrets🔁Scriptable encrypt / decrypt
One-shot, no-editor crypto for scripts and CI. sopsy encrypt .env -o .env.encrypted and sopsy decrypt .env.encrypted (to stdout, or -o a file). Structured .env / JSON / YAML / INI encrypt values only; everything else becomes one binary blob. Pipe decrypted values straight into your shell — via direnv in .envrc or a wrapper around your app — with no plaintext ever hitting disk:eval "$(sopsy decrypt .env.encrypted | sed -E '/^#/d; /^$/d; s/^([A-Z])/export \1/g')"
recipients👥Recipient management
Add, remove, list, and rotate who can decrypt. Every change re-wraps existing secrets via sops updatekeys, so the key set never drifts from the ciphertext. The data key itself stays the same: sopsy rotate-data-key replaces it.
run / set🚀Secrets straight into a process
sopsy run -- bin/rails server decrypts into one command's environment and writes nothing to disk. sopsy set API_KEY and sopsy unset change one value without an editor, and the value never shows up in a process listing.
check🧪A CI gate that bites
Seven hygiene invariants, a pass/fail checklist, and a non-zero exit the moment a plaintext secret is tracked. Needs no key — runs on Linux runners too.
join / approve🤝Self-service onboarding
Newcomers sopsy join to mint a key and record a pending request — no access granted yet. Any active member sopsy approves: vouch for the key, promote it, re-key. Requests expire after 72h by default.
provenance🧾A built-in audit trail
Every member carries their name, username, when they requested access, and who granted it — approved_by recorded as "Grace Hopper (grace)". sopsy recipient list shows it all in one table.
integrity🛡️Tamper-evident config
.sopsy.sha — a SHA-256 checksum of .sopsy.yml plus the admin public key — is refreshed on every write and verified on every read, so hand edits are surfaced instead of silently trusted. sopsy doctor repairs it.
ci🤖One-secret CI decryption
sopsy recipient ci runs a guided ceremony that provisions a portable decryption key for your pipeline. Store one CI secret — SOPS_AGE_KEY — and a Linux runner with nothing but sops installed can decrypt.