| This tool provides transparent encryption of files in git repositories using a symmetric key. Its goal is to allow you to store some secret files as encrypted in an otherwise public repo. |
It has been inspired by git-crypt, but written in Rust to have first-class cross-platform support.
- Transparent encryption/decryption: Files are automatically encrypted on commit and decrypted on checkout, thanks to git filters built-in feature
- Symmetric key encryption: Uses AES-256-CTR with deterministic IVs
- Supports key rotation: If your key gets leaked or a coworker leaves your team, you can rotate your secrets and encryption key easily
- Cross-platform: Works on macOS, Linux, and Windows
- After you run
git-conceal initto generate a cryptographic key and configure your working copy, just list the files you want to encrypt on commit in your.gitattributesfile. - At that point, files will be in clear text in your working copy (since you have the key locally)—so e.g. your compiler will be able use them just like any other file—but it will be encrypted on the fly by
gitoncommit—so that only the encrypted content is stored in the repository (object database and remote repos) - On subsequent
git checkout, only if the user doing thecheckouthas the filters and key configured on their machine will the content be decrypted in their local working copy.
You can learn more about technical details of how git filter works in this article.
- Download the pre-build binary suitable for your platform (Linux, macOS, Windows) from the latest GitHub release.
- Rename it
git-conceal(orgit-conceal.exeon Windows) and save it in a directory in your$PATH(e.g./usr/local/bin) - On macOS/Linux, ensure to make it executable (
chmod +x git-conceal) - On macOS, you might need to remove the quarantine attribute too before you can run it:
xattr -d com.apple.quarantine git-conceal
git clone https://github.com/Automattic/git-conceal
cd git-conceal
cargo build --releaseThe binary will be at target/release/git-conceal (or target/release/git-conceal.exe on Windows).
To set up encryption for a git repository that doesn't use this tool yet:
cd /path/to/your/repo
git-conceal initThis will:
- Generate a new 256-bit encryption key
- Store the key in
.git/git-conceal.keywith secure file permissions. - Configure git filters for encryption/decryption
- Display the key so you can share it with your coworkers.
You will only have to do this once.
Important
Save the displayed key securely! You'll need it to unlock the repository on other machines or share it with collaborators.
Create or edit .gitattributes in your repository root to specify which files should be encrypted by adding the filter=git-conceal attribute to them, for example:
# Encrypt specific files
secretfile filter=git-conceal diff=git-conceal
config/secrets.yml filter=git-conceal diff=git-conceal
# Encrypt all files with specific extensions
*.key filter=git-conceal diff=git-conceal
*.pem filter=git-conceal diff=git-conceal
*.p12 filter=git-conceal diff=git-conceal
# Encrypt all files in a directory (use ** to match recursively)
secrets/** filter=git-conceal diff=git-conceal
private/** filter=git-conceal diff=git-conceal
Important
Make sure .gitattributes itself is NOT encrypted! If needed, you can explicitly exclude it:
.gitattributes !filter !diff
At that point, when you will git add a file to that repo that matches one of the filter=git-conceal pattern, that file's blob/content will be encrypted on the fly by git.
Important
Make sure the file pattern is listed in .gitattributes before you git add the file containing secrets, as the git filters are applied at the time you git add.
Tip
If you forgot to add a file pattern in .gitattributes before git add-ing a file, you can either remove the file from the staging area and re-add it again, or use git add --renormalize <file>
To give you peace of mind and validate that files you added to your repo are processed by the git filter, you can use git-conceal status (to list all the files that will go through the encryption filter) or git-conceal status <file> to check a specific file. This command will validate that the file would match a pattern of your .gitattributes that has the filter=git-conceal attribute set.
You can also check what the blob content of the corresponding object looks like in the repository database by using git show :<file> (or git show HEAD:<file> if it's commited into HEAD already).
This will show the raw content as stored in the repository. So even if cat my-secret-file.txt will show you the clear text locally (assuming you have unlocked your working copy with the right key), git show :my-secret-file.txt will show you the raw, encrypted binary data stored in the repository (assuming that file matches a .gitattributes pattern with filter=git-conceal set)
After you freshly clone a repository which contains files which has been encrypted by git-conceal, you need to provide the symmetric key that your coworkers would have shared with you to decrypt it:
# Option 1: Provide the key via an environment variable (base64 encoded)
export GIT_SECRETS_KEY="YOUR_BASE64_KEY"
git-conceal unlock env:GIT_SECRETS_KEY
# Option 2: Provide a path to a from file containing the raw binary, 32 bytes key
git-conceal unlock /path/to/key.bin
# Option 3: Provide it via stdin (expects raw binary, 32 bytes as input)
cat /path/to/key.bin | git-conceal unlock -
# Or convert from base64:
echo "YOUR_BASE64_KEY" | base64 -d | git-conceal unlock -This will:
- Store the key in
.git/git-conceal.keywith secure file permissions - Set up git filters in the git config of this working copy (if not already configured)
- Decrypt all encrypted files in the working directory
To remove the encryption key file from the local working copy and restore the content of the local files to their encrypted content, you can "lock" your working copy:
git-conceal lock
git-conceal lock --force # to ignore local changes if anyTip
This can be useful in the rare case where you need to switch between branches that contain secret files that were encrypted with different keys (see "key rotation" below), to avoid errors during the git operations while git processes files from branch A that were encrypted with keyA and tries to decrypt them with the keyB that was used back in branch B. This is pretty rare to rotate keys though, so should be very uncommon to have to lock a repository in your everyday workflow.
To see the current encryption status:
git-conceal statusThis shows:
- Whether the repository is locked or unlocked
- Whether filters are configured
- Which file patterns are encrypted (from
.gitattributes)
git-conceal status <FILES>This shows the status of each file (i.e. if it will be processed by the files according to the .gitattributes or not)
If you need to show the local symmetric encryption key you are using in your local working copy, typically so you can share it with your coworkers so that they can decrypt their working copy too:
git-conceal key showIf your symmetric encryption key has leaked somehow, or if one of your coworkers leaves your team/company and you want to rotate your secrets to ensure they can't access your new secrets anymore even if they had the key at some point, there's an easy way to rotate the encryption key used by an encrypted repo:
git-conceal key rotateYour working copy has to be unlocked with the current key before you can call this command.
This command will explain the impacts of rotating the key and ask for confirmation, then generate a new key, re-encrypt the encrypted files with the new key, and mark them as changed in the git index, ready for you to commit them, providing you follow-up instructions at the end (share the new key, etc)
Important
- While users with the old key won't be able to decrypt secrets files commited to the repo after that point (unless you share the new key with them, obviously), they will still be able to decrypt the content of files from older commits in the git history that were encrypted with the old key.
- For this reason, when you rotate your encryption key with the
key rotatecommand, you will likely want to also rotate the secrets these secret files contain.
-
Encryption: When you commit a file marked for encryption, git's "clean" filter encrypts it using AES-256-CTR before storing it in the repository.
-
Decryption: When you checkout a file, git's "smudge" filter decrypts it automatically.
-
Deterministic Encryption: The same plaintext always encrypts to the same ciphertext (using a deterministic IV derived from the file content). This allows git to detect when files haven't changed.
-
Key Storage: The encryption key is stored in
.git/git-conceal.key(local to your repository clone). The file is created with secure permissions (read/write for owner only on Unix systems). It is never committed to the repository.
For detailed security information, including key management, deterministic encryption implications, and security best practices, see SECURITY.md.
- No GPG Support: Unlike
git-crypt, only symmetric keys are supported (no GPG key management). - File Metadata: File names, commit messages, and other metadata are not encrypted.
- File Size: Encrypted files are not compressible by git.
Releases are automated by our CI every time we make a git tag on the repo.