git + gpg, know thy commits
Mike Gerwitz scared the shit out of me, so I wrote this tip to sum his horry story...
Sign Your Commits
How can you be sure that any given git commit of yours is legitimate? Set up GPG and sign your commits.
1) attempt to sign a commit (this is going to error if you've never done this kind of thing before)
$ cd /tmp
$ git init gpg-experiment
$ cd gpg-experiment
$ git commit -S --allow-empty -m "First signed commit."
error: cannot run gpg: No such file or directory
error: could not run gpg.
fatal: failed to write commit object
$
2) fix the above error using $ brew install gpg
3) attempt to sign a commit (for the second time, this is going to error again)
$ git commit -S --allow-empty -m "First signed commit."
gpg: directory `~/.gnupg' created
gpg: new configuration file `~/.gnupg/gpg.conf' created
gpg: WARNING: options in `~/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `~/.gnupg/secring.gpg' created
gpg: keyring `~/.gnupg/pubring.gpg' created
gpg: skipped "My Name <me@myemail.com>": secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object
$
4) fix the above error using $ gpg --gen-key
You're going to have to answer a couple of questions, here they are in order:
- Please select what kind of key you want. I went with what gpg recommended
- What keysize do you want? I went with what gpg recommended
- Please specify how long the key should be valid: I chose to have mine not expire
- It then asks you for your Real Name, Comment, and Email Address: I didn't put a comment.
- Finally, you're asked to provide a passphrase, make it good: I put ... nice try.
5) successfully sign a commit
If you used the same Real Name and Email when generating your gpg key that you use as your git name/email, then the following should work:
$ git commit -S --allow-empty -m "First signed commit."
You need a passphrase to unlock the secret key for
...
[master (root-commit) 881116a] First signed commit.
$
Otherwise, if you've used a different name/email you'll need to first set your signing key with git. Get a list of your keys with the following:
$ gpg --list-secret-keys | grep ^sec
sec 4096R/8EE30EAB 2011-06-16
Take the part where 8EE30EAB is for me, but it's going to be different for you. Then run:
$ git config --global user.signingkey 8EE30EAB
Once you've done this you should be able to successfully sign a commit
$ git commit -S --allow-empty -m "First signed commit."
You need a passphrase to unlock the secret key for
...
[master (root-commit) 881116a] First signed commit.
$
6) View the signature in the commit log
$ git log --show-signature
Export Your Public Key
If you want to share your public key with a friend you'll need to export it:
$ gpg --export -a "Your Name" > me.pgp
Import Public Keys From People You Know
If you want to check the signature of someones commit you can import their public key:
$ gpg --import myfriend.pgp
Trust Friend's Public Key
If you can trust that a public key does indeed belong to a friend of yours you can "sign" it. To sign it you need to run the edit command:
$ gpg --edit "My Friend"
...
You can then sign your friend's public key:
gpg> sign
...
Really sign? (y/N) y
Quit gpg (be sure to run the quit command)
gpg> quit
Save changes? (y/N) y
Conclusion
A lot more can be done with gpg, just ask google.
Written by Michael
Related protips
3 Responses
Thank you for the article.
I think there is no need to sign each commit. Instead signing tags is a good choice.
@patrickniedzielski You are right, I agree with you. Thank you for make it clear to me.
Set your key to expire -- you can always extend it later, and if you lose it then it'll naturally go out of use. https://we.riseup.net/debian/openpgp-best-practices .