git-agecrypt
Transparent file-level encryption for Git, powered by age
TLDR
SYNOPSIS
git-agecrypt command [options]git agecrypt command [options]
DESCRIPTION
git-agecrypt is a Git integration that keeps secrets in a repository encrypted at rest while exposing plaintext to the working tree. It is an alternative to git-crypt, swapping GPG for age, with smaller key material and support for SSH keys and age plugin stubs (for example age-plugin-yubikey).After git-agecrypt init, the repository's .git/config contains clean, smudge, and textconv filter entries pointing at the binary. Every file matched by a path pattern in .gitattributes (typically filter=agecrypt diff=agecrypt) is encrypted on its way into the object store and decrypted on its way out. Recipients and per-path scoping live in a committed git-agecrypt.toml, while local private identities live in .git/config so they never leave the developer's machine.Because age encryption is non-deterministic, git-agecrypt records a BLAKE3 hash of each plaintext under .git/git-agecrypt/; if the plaintext has not changed, the previously stored ciphertext is reused so commits do not produce noisy churn.
PARAMETERS
init
Install the clean, smudge, and textconv filters into .git/config so encryption / decryption happen automatically on commit and checkout.deinit
Remove the filter integration from the current repository. Tracked encrypted blobs are unaffected.config add -r recipient -p path...
Register an age recipient (public key) that should be able to decrypt the listed paths. Repeat to grant access to multiple keys. SSH ed25519 public keys and age age1... keys are both accepted.config add -i identity
Register an age identity (private key file) used by the local checkout to decrypt files. Stored in .git/config, never committed.config remove -r recipient [-p path...]
Revoke a recipient, optionally limited to specific paths.config remove -i identity
Forget a local identity.config list
Print the configured recipients (per-path) and registered local identities.status
Report which tracked paths are configured for encryption and whether the working copy matches the encrypted blob.clean
Internal filter entry point: read plaintext from stdin and write ciphertext to stdout. Invoked by Git via the filter.agecrypt.clean hook.smudge
Internal filter entry point: read ciphertext from stdin and write plaintext to stdout. Invoked by Git on checkout.textconv file
Internal helper used by git diff to render encrypted blobs as plaintext for diffing without leaking ciphertext into the working copy.-v, --verbose
Increase logging verbosity.--help
Print help for the chosen subcommand.--version
Print version and exit.
CONFIGURATION
git-agecrypt.toml (committed) declares recipients and the paths they can decrypt:
key = "age1abc..."
paths = ["secrets/*.env", "deploy/*.yaml"]
[[recipient]]
key = "ssh-ed25519 AAAA... user@host"
paths = ["secrets/*.env"]
deploy/*.yaml filter=agecrypt diff=agecrypt
clean = git-agecrypt clean %f
smudge = git-agecrypt smudge %f
required = true
[diff "agecrypt"]
textconv = git-agecrypt textconv
[agecrypt]
identity = /home/user/.config/age/keys.txt
CAVEATS
Both git-crypt and git-agecrypt rely on Git filters, which means git log -p, git blame, and similar tools can leak plaintext through textconv unless tooling is run on a checkout that lacks the identity. age is an authenticated stream cipher rather than a deterministic format, so encrypted blobs change on every encryption unless git-agecrypt's hash cache is preserved - clearing .git/git-agecrypt/ will produce diffs even when the plaintext is unchanged. Revoking a leaked recipient requires rewriting history; like every Git-level encryption tool, git-agecrypt cannot un-publish ciphertext that already left the repository.
HISTORY
git-agecrypt was created by vlaci and is maintained as an open-source project on GitHub. It builds on age, the modern file encryption tool by Filippo Valsorda, and is positioned as a lighter, more flexible successor to git-crypt for teams that already use age or SSH keys for secrets management.
