# git-secret: encrypted files in a git repo, keyed to each collaborator

> A bash tool that keeps secrets encrypted inside the repository itself, with access granted by whose public key is in the repo's keyring.

**sobolevn/git-secret** — :busts_in_silhouette: A bash-tool to store your private data inside a git repository.

- Repository: https://github.com/sobolevn/git-secret
- Website: https://sobolevn.me/git-secret/
- Stars: 4,058 · Forks: 213
- Language: Shell
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/sobolevn-git-secret

## What it means to store secrets in the repository

The README defines `git-secret` as a bash tool which stores private data inside a git repo. The mechanism it describes is encryption with public keys: files are encrypted with permitted users' public keys, and the people you trust decrypt using pgp and their own secret keys.

That framing matters because it inverts the usual secret store. There is no server, no API token to manage and no vault to keep running. The encrypted ciphertext lives in ordinary commits, travels through ordinary remotes, and is reviewed in ordinary diffs. Access is decided entirely by which keys are present.

The repository reports itself as a Shell project under the MIT license, with topics covering encryption, git, git-addons, gpg and secret management. The tree shows a `src/` directory, a `man/` directory for the man pages, a `tests/` directory, a `utils/` directory for install and test scripts, an `RFC/` directory, `docs/`, and a `vendor/` directory that carries a testing framework called out as bats-core in the Makefile.

## Revoking access is removing a line from the keyring

The most interesting claim in the README is about revocation, and it is worth reading closely because it is the part most secret management tools do badly.

The README says that when someone's permission is revoked, secrets do not need to be changed. You remove their key from the repository's keyring with `git secret removeperson their@email.com`, re-encrypt the files, and they can no longer decrypt the secrets.

```bash
git secret removeperson their@email.com
```

The README is careful to add the caveat that matters: if you think the person might have copied the secrets or keys while they had access, you should also change the secrets. That is not a flaw in the design, it is an admission that rotation is a separate problem from authorization, and it is the same truth every key-based system lives with.

The re-encrypt step is what makes this work. Because the ciphertext is regenerated against the new keyring, old commits still contain data the removed person could decrypt with their old private key. Anyone evaluating this should decide in advance whether their threat model cares about repository history.

## The hide -m option and its documented weakness

The README has a Security section that is unusually candid, and it concerns the `-m` flag.

In order to encrypt files only when they are modified, the path mappings file tracks sha256sum checksums of the files that were added. The README acknowledges that the odds of a checksum collision are low, but recommends padding files with random data for greater security, or avoiding the `-m` option altogether. It adds that if a secret file holds more than just a single password, these precautions should not be necessary.

So the tool documents its own weaker path. That is a good sign about the project's honesty, and a useful thing to know operationally: if you adopt `git secret hide -m` because re-encrypting on every save feels slow, you are accepting a checksum-based staleness check as the thing deciding whether a file needs encrypting again.

The README also asks that security issues not be disclosed publicly and gives mail@sobolevn.me as the contact, with a `SECURITY.md` file at the repository root and a `SECURITY.md` mention in the tree alongside the other policy documents.

## Building from source by concatenating shell scripts

The Makefile shows what this project actually is at the artifact level: a set of shell script fragments assembled into one executable.

```bash
build:
	@cat src/version.sh > git-secret
	@cat src/_utils/*.sh src/commands/*.sh >> git-secret
	@cat src/main.sh >> git-secret
	@chmod +x git-secret; sync
```

There is no compiler and no dependency resolution. The version file comes first, then the utility and command implementations in glob order, then the main entry point, and the concatenation is made executable. Installation runs a script with a prefix and destination directory:

```bash
install:
	"${SHELL}" ./utils/install.sh "${DESTDIR}${PREFIX}"
```

That also explains the runtime requirements list, which is longer than you would expect for a bash script: bash since 3.2.57, gawk since 4.0.2, git since 1.8.3.1, gpg from gnupg 1.4 through 2.X, and sha256sum since 8.21, with shasum used instead on FreeBSD and macOS. Gawk in particular is a real constraint on unusual systems, and the macOS note about shasum is the kind of detail that only appears after someone fixed a bug.

## Testing through docker and a vendored bats framework

The Makefile's test target is more interesting than the usual one line call, because it sets up an environment before running anything:

```bash
test: clean build
	export SECRETS_PROJECT_ROOT="$(shell echo $${PWD})"; \
	export PATH="$(shell echo $${PWD})/vendor/bats-core/bin:$(shell echo $${PWD}):$(shell echo $${PATH})"; \
	"${SHELL}" ./utils/tests.sh
```

Two things are happening. The vendored bats-core directory is prepended to PATH so the tests find their own copy of the framework rather than a system one. And there is a comment explaining the `$(shell echo $${PWD})` construct at length: under Git for Windows, PATH contains Windows-style paths, so the construct is used to recover the raw POSIX form.

The Makefile also documents a `docker-ci` target whose comments describe passing a `SECRETS_DOCKER_ENV` variable, selecting a matching docker image per CI job, and running `make test` inside the container. For a shell tool with this many platform combinations, that is the sensible way to test, and the packaging list in the README matches: Ubuntu bionic, Fedora, Arch, Alpine edge, Debian sid and Void Linux all carry a package.

## Version cadence, semver, and what the release history shows

The README states that `git-secret` uses semver and points at `CHANGELOG.md`, and the repository tree holds a top level `CHANGELOG.md` to match.

The release history is worth reading for what it implies. v0.5.0 was published on 2022-06-05, and its changelog is almost entirely Dependabot bumps of base images, Alpine and Fedora versions in CI directories, plus a typo fix. v0.4.0 came on 2021-05-06 with a release CI script for testing installation, new deb and rpm installation instructions, and a new CI setup, including a security disclaimer explaining what is and is not readable by a user removed from the repository's keyring. v0.4.0.alpha1 exists as a separate tag because bintray was shutting down, and its notes contain a PGP public key block.

So the last several tagged releases are maintenance of the delivery pipeline rather than user visible features, which suits a stable tool. The repository's last push was on 2026-08-24, later than the newest tag, so work continues on the master branch without every change getting a release.

## Conclusion

git-secret solves a specific problem cleanly: letting several people decrypt secrets that live in version control, where the repository itself is the distribution channel and no server holds anything. The keyring file is the whole model, and understanding that a person's access is exactly membership of that file makes revocation a one line change followed by a re-encrypt. Its limits are equally clear. It needs a working gnupg setup on every machine, it cannot protect a secret from someone who was authorized and copied it, and its most recent tagged release, v0.5.0, dates from 2022-06-05 even though the repository was pushed to on 2026-08-24. If your team already runs a secret manager, the comparison is about whether you want a second source of truth. If you do not, `brew install git-secret` and `git secret reveal` on a test file is the shortest way to find out whether the gnupg integration fits your setup.

## FAQ

### How does git-secret handle access revocation?

You remove the person's key from the repository's keyring using git secret removeperson their@email.com and then re-encrypt the files. They can no longer decrypt new commits. The README is explicit that if the person may have copied secrets or keys while they had access, you also need to rotate the underlying secrets, because authorization and rotation are separate problems.

### What does git-secret require to be installed?

The README lists bash since 3.2.57, gawk since 4.0.2, git since 1.8.3.1, gpg from gnupg 1.4 through 2.X, and sha256sum since 8.21, with shasum used on FreeBSD and macOS. Installation itself is available through brew, apt and yum packages, or by running make, which concatenates the shell sources into a single git-secret executable.

### Is encrypting secrets in git as safe as a dedicated secret manager?

It solves a narrower problem well: several collaborators sharing secrets that already live in version control, with no server component. What it does not solve is anyone who was authorized and copied the secret, and the README says as much. The `-m` option also relies on sha256sum checksums to decide when a file changed, which the README flags as a weaker path and suggests padding or avoiding.

### How do I build git-secret from the repository?

Run make. The build target concatenates src/version.sh, then src/_utils/*.sh and src/commands/*.sh, then src/main.sh into a git-secret file and makes it executable, so the result is one shell script rather than a compiled binary. make install then runs utils/install.sh with the destination directory and prefix. Testing uses a vendored copy of bats-core.

## Sources

- [License: MIT](https://github.com/sobolevn/git-secret/blob/master/LICENSE)
- [Project website](https://sobolevn.me/git-secret/)
- [README](https://github.com/sobolevn/git-secret/blob/master/README.md)
- [Releases](https://github.com/sobolevn/git-secret/releases)
- [sobolevn/git-secret on GitHub](https://github.com/sobolevn/git-secret)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sobolevn-git-secret
