Last updated

GPG Sign Your Git Commits

I have written and talked before about GPG and the need for trust on the internet.

Getting started with GPG and using it on a daily basis is, when you’re using the right tools, not all that hard, but still quite technical. Today Google announced they are working on a Chrome extention to enable end-to-end encryption using OpenPGP.

As a developer, I do more than dispatching emails all day. On occasion I write code. And that code gets committed to a repository that will remember that commit forever.

Just as with emails it is remarkably easy to fake your identity when committing code.

1git commit -a -m "Meh" --author "Chuck Norris <chuck@example.com>"

In theory, this would allow anyone to commit (malicious) code under your name. Meaning that you’ll get the blame for the back door you committed.

Git seems to offer a resolution by adding a Signed-off-by field, to allow a second developer to sign off on code that gets merged into the project. But this field suffers from the same trust issues as the Author field.

You cannot trust the git Author and Signed-off-by fields.

Again, GPG offers a solution to the problem of trust. By establishing trust based on public keys, wouldn’t it be cool if you could sign a git commit just the same way you’d sign an email?

Well, you can.

Signing commits

1git commit -a -m "Cool new feature" --gpg-sign=F713697B

This will attach your signature to the git commit message, allowing others to validate your signature. Validating this signature is quite easy as well.

1$ git log --show-signature
2commit 3d53a4be3f6f955007dc056347d926067bbfa8de
3gpg: Signature made zo  1 jun 20:42:58 2014 CEST using RSA key ID F713697B
4gpg: Good signature from "Ariejan de Vroom <ariejan@ariejan.net>"
5Author: Ariejan de Vroom <ariejan@ariejan.net>
6Date:   Sun Jun 1 20:42:58 2014 +0200

Any other developer (or your CI) can now validate your commit as coming from you, based on the trust they assigned to your public key.

Optionally to using --gpg-sign you can use -S. If you don’t specify a specific key, git will try to figure out what key to use based on your email address. It’s also possible to set a default signing key globally.

1git config --global user.signingkey F713697B

Signing tags

Besides signing every commit you make, it’s also good idea to sign tags. That way you can be sure that the created tag was actually created by a trusted person.

1git tag -s 1.2.3 -m "Release 1.2.3 including bug fixes."

Signing merges

If you are responsible for integrating features and bug fixes into the main branch of a project, you’d probably like to sign the merges you make. You have two options here.

The first is to merge and manually commit a sign the merge.

1git merge feature-awesome --no-commit
2git commit -m "Merge feature-awesome" -S

The second is merging and signing directly.

1git merge feature-awesome -S

Be sure to check out this in depth guide by Mike Gerwitz.

Where to go from here?

Trust is a hard thing to come by on the internet and it really bites you when things go wrong. Just as with email, creating a web of trust can be helpful and someday save you from disaster.