Default flow:
keyseal addscaffolds and encrypts a new secret document immediately, without writing plaintext starter content to the final.enc.yamlpath.
Keyseal is a small Go CLI that standardizes encrypted file workflows around sops, age, and Git. It was built to solve a real production problem: managing Git-backed SOPS secret workflows at scale.
It helps teams:
- keep encrypted secret files in a repository
- scaffold new secret documents
- open encrypted files in
sops - inspect Git status, diffs, and file history by logical name
- commit and roll back Keyseal-managed changes without staging the whole repo
- render decrypted values into runtime formats
- run commands with decrypted environment variables injected
- validate repository layout and config health
- enforce strict CI verification before release or deployment
Keyseal does not implement encryption itself, replace SOPS, run a server, expose an API, or behave like a hosted secrets platform.
Keyseal uses the official SOPS Go decrypt library for read-only decryption in render, exec, and validation paths. The external SOPS binary is still required for commands that create, edit, or rotate encrypted files.
SOPS already solves encryption and editing well. Keyseal stays one layer above that and makes a repo-backed workflow more predictable:
- consistent file naming and layout
- Git-aware workflows around the encrypted files that already live in the repo
- small config with strong defaults
- repeatable render and exec flows
- clear validation for common mistakes
- Go 1.25+ to build the CLI
- age recipients configured in
.sops.yaml
Developer/admin machines that run keyseal add, keyseal edit, or keyseal updatekeys also need the external sops binary.
Production, CI, or deploy machines that only run keyseal render, keyseal exec, keyseal doctor, or keyseal verify need only:
- the
keysealbinary - the encrypted secrets files/repo
- age private key material, usually through
SOPS_AGE_KEY_FILEorsops.age_key_file
They do not need the external sops binary or the external age binary. Servers need the age key, not the age CLI.
Pre-built binaries and Linux packages are available on the GitHub Releases page. Each release includes tar.gz archives (Linux and macOS, amd64 and arm64), .deb and .rpm packages (Linux amd64 and arm64), and SHA256 checksums.
Linux (Debian/Ubuntu):
sudo dpkg -i keyseal_<version>_amd64.debLinux (RHEL/Fedora/SUSE):
sudo rpm -i keyseal-<version>-1.x86_64.rpmOther platforms: extract the binary from the appropriate tar.gz archive and place it somewhere in your PATH.
make build
./bin/keyseal init
./bin/keyseal add production/platform/app --template laravel
./bin/keyseal edit production/platform/app
./bin/keyseal status
./bin/keyseal commit -m "Add production app secret"
./bin/keyseal render production/platform/app --stdout
./bin/keyseal doctorFor a fuller walkthrough, see the Quick Start guide and the wiki.
make tidy
make check
make build
./bin/keyseal --version
./bin/keyseal --helpkeyseal initbootstraps a repository layout,keyseal.yaml, and.sops.yamlkeyseal add <logical-name>creates and encrypts a starter env secret document, with optional immediate Git commit supportkeyseal edit <logical-name>opens the target file withsops, bootstrapping empty placeholder files first when neededkeyseal updatekeys [logical-name...]syncs SOPS recipients from.sops.yaml, with optional explicit Git commit supportkeyseal status [logical-name]shows Git status for Keyseal-managed fileskeyseal diff <logical-name>showsgit difffor one secret filekeyseal history <logical-name>shows file-scoped Git history for one secret filekeyseal commitstages current Keyseal-managed changes and creates a Git commitkeyseal rollback <logical-name> --to <commit>restores one secret file from Git historykeyseal render <logical-name...>decrypts, merges, and renders secret values, skipping empty placeholder fileskeyseal exec <logical-name...> -- <command...>runs a child process with merged env varskeyseal doctorvalidates config sanity, SOPS CLI availability, age key/deployment context,.sops.yamlreadiness, and common mistakeskeyseal verifyruns strict CI checks and fails on any doctor warning or failurekeyseal versionreports version, commit, and build date metadata
Detailed flags, examples, and behavior notes live in the Command Reference and wiki.
- not a crypto implementation
- not a Vault replacement
- not a secret hosting service
- not a daemon or web UI
- not a Kubernetes controller
keyseal add production/platform/app --template laravel
keyseal edit production/platform/app
keyseal updatekeys production/platform/app --yes
keyseal status production/platform/app
keyseal history production/platform/app --oneline
keyseal commit -m "Update production app secret"
keyseal render production/platform/app --stdout --format json
keyseal exec production/platform/app -- php artisan migrate
keyseal rollback production/platform/app --to <commit> --dry-run
keyseal doctor
keyseal verifyKey workflow details:
-m, --messageimplies commit on mutating commandsgit.auto_commitis off by defaultsops.age_key_fileis used as the default age key path unlessSOPS_AGE_KEY_FILEis already set- read-only decrypt paths use the SOPS Go library and do not require external
sopsoragebinaries - mutating commands check the configured
sops.binarybefore creating, editing, or rotating encrypted files updatekeysuses.sops.yamlas the recipient source of truth and does not rotate secret values or data encryption keyskeyseal commitstages only Keyseal-managed files, not the whole reporollbackrestores the encrypted file from Git history;--dry-runpreviews safely
For exact command behavior and more examples, see the Command Reference, Configuration Reference, and Troubleshooting wiki pages.
keyseal --version
keyseal version
keyseal version --shortRelease builds stamp version, commit, and build date metadata via Go linker flags. Local builds default to dev, unknown, and unknown unless you pass VERSION, COMMIT, and DATE. When Git metadata is available, local builds use the latest v* tag and the short current commit.
make dist VERSION=v1.0.0 COMMIT=$(git rev-parse --short HEAD) DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")make dist builds tar.gz archives, .deb and .rpm packages for Linux (amd64, arm64), and a single SHA256 checksums file covering all artifacts to dist/. Linux packages require nfpm to be installed.
make fmt
make check
make test
make buildContributor-oriented detail is available in the Contributing wiki page.
Keyseal was born out of a real production need: managing encrypted secret files safely and predictably with SOPS-compatible encryption, age keys, and Git. It is a small, focused tool for teams that want Git-backed secret workflows without the overhead of a hosted platform.
This package is licensed under GPL-3.0-only (GNU General Public License v3.0 only).
If you distribute this package, modifications, or derivative works, review the GPLv3 obligations first to make sure your usage and distribution model remain compliant.
See LICENSE for the full license text.
