How to Sign Your Git Commits with a GPG Key

How to Sign Your Git Commits with a GPG Key

Have you noticed on GitHub that some git commits have a green box that says "Verified," while other commits do not? Have you ever read a contributing.md file that talks about signing commits? Or maybe you know someone that made a pull request that did not pass a continuous integration pipeline because a commit was not signed?

In this article, I discuss why it is good practice to sign git commits. Then I describe how to sign git commits by setting up a GNU Privacy Guard (GPG) key, and linking it to GitHub. Finally, I give an example of how to sign a commit.

Why Sign Git Commits?

In an age where computer software powers so much of our world, we might not always think about who wrote a particular piece of software. However, when we first create a git repository, we have the option to configure our own name and email. Imagine for a moment what might happen if a malicious software engineer created an application, but claimed to be someone else? With git, this could be as easy as

git config user.name "Tim Cook"
git config user.email "tim@apple.com"

After pushing some code to GitHub on an open source project, the username and email would show that Tim Cook wrote this code. Although a repository maintainer would likely be dubious that Tim Cook from Apple wrote the code for their project, this example illustrates how easy it is to falsely impersonate a different identity. Fortunately however, the above example would not show up as a "signed" or "verified" commit on GitHub (unless a user with access to tim@apple.com created their own GPG key, linked it to GitHub, and signed the commits).

In another more realistic example illustrating the utility of signing git commits, CNN Reported in 2013 that a software developer outsourced his own job, and hired other software developers for years to write his own code while he watched cat videos online. If the companies that employed this individual required that everyone sign their commits, then this would have been a lot more difficult to outsource and take credit for someone else's work.

Now eight years later, in a world where many companies and open source projects require developers to sign their commits, you might ask, how do I do that? This rest of this article will describe signing git commits with a GNU Privacy Guard (GPG) key.

Setting up a GPG Key on Your Local Machine

To sign your git commits, you first need to create a GPG key on your local machine that associates your GitHub username and email with you. In the command line, first check if you have gpg installed with

gpg --help

You should see this command print options to the terminal. If you do not, you need to either download gpg from the GNU website, or install it with apt-get install gnupg. Next, you should check that you have the right permissions on your local machine to create your own GPG key with

gpg --list-keys

If output from this command says anything about a permissions error, then see the permissions section below, otherwise, skip to the generating a key value pair section.

Dealing with a Permissions Error

The permissions error is sometimes caused when the super user has ownership of the folder containing GPG keys, but you as the current user do not. To fix this, you can create a new directory and have the GPG program look for your keys there instead.

First, create a new directory to store your own GPG keys with something like

mkdir my-gpg-keys

Then, open your .profile, .bashrc, or bash_profile file and add a line that that gives the path to the directory you just created like this

GNUPGHOME=/home/YOURNAME/my-gpg-keys

Save, and close the file, and re-source the current terminal with something like

source .bashrc

Generating a GPG Key Value Pair

To generate a GPG key value pair, you should check what version of gpg you are using with

gpg -v

If you are on gpg 2.1.17 or greater, you should run

gpg --full-generate-key

If you are on a version less than 2.1.17 (but still greater than 2), then you can run

gpg --default-new-key-algo rsa4096 --gen-key

For people on really old versions (like gpg version 1.4.20), you can run gpg --gen-key.

In all cases, if prompted, we want to select the default options, 4096 keysize, and something like 1y (or whenever you want your GPG to expire) for expiration. I recommend not having your GPG key expire more than a year into the future.

Next, you will be asked to enter your username, and email. It is important to have these exactly match the name and email you use for GitHub. After you enter this, you need to enter a password that you will remember (or that you can add to your password manager).

After you have entered this information, the gpg program will generate a key value pair. Depending on how old your computer is, this might only take a few seconds, or it could take several minutes. It might also ask you to do things like move the mouse or work on something else, as this helps the gpg program generate enough random information to build the GPG key.

Linking Your GPG Key with GitHub

Now it's time to link your GPG key to GitHub. As described on GitHub, you should first type this into the terminal:

gpg --list-secret-keys --keyid-format=long

The key you just generated will show up with the "4096" keysize and the expiration date you chose as something like

sec   4096R/3BB5634371567BD9 2021-09-01 [expires: 2022-09-01]

In this fictitious example, you should copy the 3BB5634371567BD9 part, and use it in this command:

gpg --armor --export 3BB5634371567BD9

This will print out a very long GPG key. You need to copy all of it, including the

-----BEGIN PGP PUBLIC KEY BLOCK-----

through the

-----END PGP PUBLIC KEY BLOCK-----

parts.

On your GitHub account page, select the options on the top right-hand side, select Settings, then SSH and GPG keys, and click "New GPG key".

You can then paste in the long key you just copied, and click "Add GPG key".

Signing a Commit

Now that you've generated your own GPG key, and linked it to GitHub, signing a git commit is easy. For example, suppose you just make some changes to some code. You can add them all with

git add -A

Then you can commit them with a message and sign them at the same time with something like this

git commit -S -m 'this fixes blah blah...'

The capital S above means sign.

After you hit enter, you will have to input the password you used when setting up your GPG key. Once you've done with that, you can push your code to GitHub.

You can also check locally that the commit was signed with

git log --show-signature

If you've made it this far, congratulations! You now know how to sign git commits.