As a developer, you often use code written by others. To ensure that upstream changes don’t break your code, you rely on release numbers. Libraries like Bootstrap use git tags to track releases and make them available for download.
This approach is so common that GitHub provides a handy release page where you can download the zip/tar.gz file of the tag you need.
But even with the tarball in hand, how can you be sure you have the right code? Could the NSA have tampered with it? Could your internet service provider? Could GitHub? That release passes through many hands between the developer’s hard drive and yours.
What if we cloned the repository directly? Commits are hashed, and you can examine the history.
$ git clone --branch v3.3.0 https://github.com/twbs/bootstrap
Unfortunately, it’s possible to alter git history, which means a sneaky individual could hide a malicious change in the project history. Fortunately, git can help. Signed tags use Gnu Privacy Guard (GPG) to verify that a tag was made by the project’s developers and that the contents are correct.
$ cd bootstrap
$ git tag --verify v3.3.0
error: 16dbdbd7a2c6cfa3be4e5dcc52249e577c02c84a: cannot verify a non-tag object of type commit.
error: could not verify the tag 'v3.3.0'
Unfortunately, it looks like Bootstrap doesn’t sign their tags. Let’s try a project that does.
Now you can see the key fingerprint it was signed with and check that the key is valid. The simplest way to do this is to search pgp.mit.edu for the email address and compare the key ID to confirm it’s signed by the right person. While this method isn’t foolproof, as anyone can upload any key, it’s better (in theory) than downloading unsigned code. Ideally, you should verify the key through the GPG web of trust, in person, through another secure medium, or a combination of these methods. The more verification you can get, the more you can trust the integrity of the signed tag.
Note: Version 1.7.9 of Git introduced the ability to sign commits as well as tags.
How Can You Sign Your Releases?
To sign tags in your own project, you’ll need a GPG key. Follow this tutorial to get set up if you don’t already have a key. If you have multiple keys, you need to configure your signing key.
git config --global user.signingkey you@email.domain
Now you can make a release as usual, but with a signed commit.
git tag -s v0.1 -m "the best version yet"
The only difference here is the -s flag. Before you upload the tag, be sure to check your signature with:
git tag --verify v0.1
If your project has multiple developers, there are a few ways to handle signing releases. The project can have a release-signing key with subkeys for each developer, or developers can use their personal keys. Both methods work, but document which method you choose. Users need to know what to expect when they check the release signature.
Just signing releases is a great start, but they’re useless if your users don’t check them. Make sure to include a note in your README stating that you sign releases and where to find the public key your project uses.