git-cipher
v2.0.0-pre.3
Published
Manages encrypted content in a Git repo
Downloads
7
Readme
Introduction
git-cipher is a tool for encrypting sensitive files for storage in a public Git repo.
:warning: This documentation refers to version 2.0 of git-cipher, which is a NodeJS package and a complete rewrite from version 1.0, which was a Ruby script and used a different encryption protocol.
For differences between version 1.0 and 2.0, please see UPGRADING. For more on version 1.0, please see the
1-x-release
branch.
Usage
git cipher init
git cipher unlock
git cipher add
git cipher ls
git cipher lock
git cipher help
Commands
git cipher add
git cipher clean
git cipher demo
git cipher diff
git cipher help
git cipher hook
git cipher init
git cipher is-encrypted
git cipher lock
git cipher log
git cipher ls
git cipher merge
git cipher show
git cipher smudge
git cipher textconv
git cipher unlock
How it works
A brief summary follows — for a detailed description, see PROTOCOL.
git-cipher generates secrets that are used to encrypt and decrypt files in the Git repository. In this document we call these "managed files". The secrets are in turn encrypted using GnuPG and stored in the repository itself. Running git-cipher unlock
makes these secrets available in the current repository and uses them to decrypt any encrypted files (provided the person running the unlock command has the appropriate GnuPG private key). Conversely git-cipher lock
removes the local copy of the secrets (while leaving the encrypted copy of the secrets intact) and replaces any decrypted files with their encrypted equivalents.
Files are added to the list of managed files with git-cipher add
. These are added to the .gitattributes
file and instruct Git to use git-cipher to transparently encrypt their contents when they are committed, and decrypt them when they are checked out. This is done using Git's "clean" and "smudge" filtering mechanism. A "textconv" filter is used to show plaintext diffs corresponding to changes made to encrypted files. A merge driver is used to facilitate merging encrypted files (by decrypting them, merging them, then encrypting the result).
Installation
Note: If you install the git-cipher
executable somewhere in your $PATH
, Git will treat it as a subcommand, which means you can invoke it as git cipher
. Otherwise, you will have to provide the full path to the git-cipher
executable.
To install the external prerequisites, use your preferred method. For example, on macOS you might choose to use Homebrew:
brew install git gnupg gpg-agent
Configuration
Usage on Arch Linux
For most of the lifetime of git-cipher
, I've been using it on macOS, where everything works pretty much seamlessly out of the box, especially since moving to GnuPG v2 (see commit fd4c78aeb9d11 for more details of how things were streamlined by v2). On Arch Linux, I have found that I needed to do a bit of additional manual set-up.
The goal is to cache the secret key in the GPG agent so that you don't have to re-enter the password for every file.
First of all, to find out the "keygrip" of the secret key:
gpg --with-keygrip -K
(lists all secret keys)gpg --fingerprint --with-keygrip [email protected]
(lists a specific key; source)
Once you have the keygrip (eg. a string like 0551973D09...
), you can allow it to be added as a "preset" passphrase (ie. cache it in the agent for the duration of the session). To achieve this, the following line:
allow-preset-passphrase
must be present in the ~/.gnupg/gpg-agent.conf
file.
You then need to tell GnuPG how to prompt for a password using a "pin helper". You can see which helpers are available with:
pacman -Ql pinentry | grep /usr/bin/
That will produce a list similar to:
pinentry /usr/bin/
pinentry /usr/bin/pinentry
pinentry /usr/bin/pinentry-curses
pinentry /usr/bin/pinentry-emacs
pinentry /usr/bin/pinentry-gnome3
pinentry /usr/bin/pinentry-gtk-2
pinentry /usr/bin/pinentry-qt
pinentry /usr/bin/pinentry-tty
Configure one to be used by adding to ~/.gnupg/gpg-agent.conf
:
pinentry-program /usr/bin/pinentry-curses
After making any changes, reload the agent:
gpg-connect-agent reloadagent /bye
You can confirm which keys are known to the agent like so:
gpg-connect-agent 'keyinfo --list' /bye
Which will show a list like:
S KEYINFO 9BB6077848... D - - - P - - -
S KEYINFO A05D018ED6... D - - - P - - -
S KEYINFO 26CA5BE9E3... D - - - P - - -
S KEYINFO 4435E5FDCC... D - - - P - - -
S KEYINFO 0551973D09... D - - - P - - -
S KEYINFO 2529B67D84... D - - - P - - -
A 1
before the P
shows that the key is cached in the agent, which means that none of the keys in the example list above are actually cached.
To actually cache the key, you can run:
/usr/lib/gnupg/gpg-preset-passphrase --preset 0551973D09...
If you redo the keyinfo --list
operation, you should now see the expected 1
:
S KEYINFO 9BB6077848... D - - - P - - -
S KEYINFO A05D018ED6... D - - - P - - -
S KEYINFO 26CA5BE9E3... D - - - P - - -
S KEYINFO 4435E5FDCC... D - - - P - - -
S KEYINFO 0551973D09... D - - 1 P - - -
S KEYINFO 2529B67D84... D - - - P - - -
Tips
You may see prompts like the following, depending on the trust level of your signing key:
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
You can avoid these prompts by setting the trust level to "ultimate" like this:
gpg --edit-key [email protected] # or $GPG_USER
> trust
> quit
Author
git-cipher
was hacked together by Greg Hurrell ([email protected]).
Publishing releases
yarn format:check
yarn version --prerelease # Or similar.
yarn compile
git push --follow-tags origin next
yarn publish