Set up GPG
You need to use --full-gen-key
or else you get something that doesn't seem to
work right with git crypt:
glock@laptop1$ gpg --full-gen-key
Then export the public key:
glock@laptop1$ gpg --list-secret-keys --keyid-format=long
glock@laptop1$ gpg --armor --export B401B9A0A9E1B1A4
Assuming your GPG key id is B401B9A0A9E1B1A4
. You need to use
--keyid-format=long
or else git-crypt will not be able to find it.
Set up a git repo
Go into a git repo. Then
glock@laptop1$ git crypt init
glock@laptop1$ git crypt add-gpg-user B5CC247C50CB63A3
This will silently commit some new stuff to the repository. Then tell git-crypt
that a file is to be encrypted by creating or editing .gitattributes
:
glock@laptop1$ cat .gitattributes
settings.sh filter=git-crypt diff=git-crypt
Then commit just this .gitattributes
file. Leave the actual file you want
to encrypt alone for now.
glock@laptop1$ git add .gitattributes
glock@laptop1$ git commit -m "add gitattributes"
Then add the file:
glock@laptop1$ git add settings.sh
glock@laptop1$ git commit -m "add file to be encrypted"
The file will be unencrypted at rest, but if you git push
it will be encrypted
before being uploaded.
Add other users to git-crypt
In order to let other users decrypt files, someone who already can decrypt files must add their publickey.
Let's say a second person's (mary
's) laptop is called laptop2
and the person
who initialized the above (glock
) is using laptop1
. The new person should
create their GPG key as above:
laptop2$ gpg --full-gen-key
laptop2$ gpg --list-secret-keys --keyid-format=long
/Users/me/.gnupg/pubring.kbx
-------------------------------
sec ed25519/B5CC247C50CB63A3 2022-03-14 [SC] [expires: 2024-03-13]
2307BF889A46DDE3B4B5C766B5CC247C50CB63A3
uid [ultimate] Mary Berry <mary@berry.com>
ssb cv25519/64776E3CDA70A0A6 2022-03-14 [E] [expires: 2024-03-13]
Then export the public key:
laptop2$ gpg --armor --export B5CC247C50CB63A3
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEYi+PwRYJKwYBBAHaRw8BAQdApHnj8xmTdg+Mh3GE72N5JLXGZvcQ/BGz2WUJ
iXk70OK0LEdsZW5uIEsuIExvY2t3b29kIDxnbGVubmtsb2Nrd29vZEBnbWFpbC5j
b20+iJoEExYKAEIWIQQjB7+Imkbd47S1x2a1zCR8UMtjowUCYi+PwQIbAwUJA8Jn
AAULCQgHAgMiAgEGFQoJCAsCBBYCAwECHgcCF4AACgkQtcwkfFDLY6Pl9wD/UDjV
Ay5EC5uS9SJ2XVOJOt8L4BoUy3rV6FdO7iaASmMA/2t01Vev+l3UnecVvnrA8EjM
iZnV35tnxwMTGgEqBT8JuDgEYi+PwRIKKwYBBAGXVQEFAQEHQKz2qNEB4fOsOoYC
V+Wfw9S0FNbFcbwWmcbWbhGKBwtPAwEIB4h+BBgWCgAmFiEEIwe/iJpG3eO0tcdm
tcwkfFDLY6MFAmIvj8ECGwwFCQPCZwAACgkQtcwkfFDLY6MdpQD+P9kxiGS4rG75
ef6gU1B/JIWuc8mWfatBikO395BPrBYBANfX03lOe/eANRYOEUzqlHq17H8b8O/r
Sld+MjNxYzII
=WipN
-----END PGP PUBLIC KEY BLOCK-----
Mary should then send this public key to glock. Then glock has to first import that public key (e.g., using copy paste):
glock@laptop1$ gpg --import -
<paste the public key here, then ctrl+d>
gpg: key B5CC247C50CB63A3: public key "Mary Berry <mary@berry.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Then this public key can be added to our git repo:
glock@laptop1$ git crypt add-gpg-user --trusted B5CC247C50CB63A3
Note that you have to use --trusted
because we didn't gpg --edit-key
and
issue the trust
command. You can trust the key after importing if you want.
glock then pushes all of this up, and mary can pull it down:
mary@laptop2$ git clone git@github.com:glennklockwood/secret.git
Our encrypted file is still encrypted at this point, but mary can unlock the repository now that it's cloned:
mary@laptop2$ git crypt unlock
This will prompt for a password, but once it's unlocked, it's unlocked for good.
Pitfalls
If mary were to run git crypt add-gpg-user
herself instead of having glock do
it, the repository would throw errors like this:
mary@laptop2$ git crypt unlock
git-crypt: error: encrypted file has been tampered with!
error: external filter '"/usr/local/bin/git-crypt" smudge' failed 1
error: external filter '"/usr/local/bin/git-crypt" smudge' failed
fatal: settings.sh: smudge filter git-crypt failed
Error: 'git checkout' failed
This is because mary can't add her own key to a repository she just cloned; that would allow anyone to just add themself to a repo to decrypt everything in it! See below for how this works.
How it works
When you git crypt init
, a symmetric key is generated used to encrypt files in
the repository. You then use your GPG key to asymmetrically encrypt that key,
and your asymmetrically encrypted version of that symmetric key gets stored in
.git-crypt/keys/default/0/2307BF889A46DDE3B4B5C766B5CC247C50CB63A3.gpg
As you add more users using git crypt add-gpg-user
, you are using the supplied
public key to create a new asymmetrically encrypted version of the symmetric key
which also gets stored in the above directory.