Signing Git Commits

Protect your code commits from malicious changes by GPG signing them.

Often when people talk about GPG, they focus on encryption—GPG's ability to protect a file or message so that only someone who has the appropriate private key can read it. Yet, one of the most important functions GPG offers is signing. Where encryption protects a file or message so that only the intended recipient can decrypt and read it, GPG signing proves that the message was sent by the sender (whomever has control over the private key used to sign) and has not been altered in any way from what the sender wrote.

Without GPG signing, you could receive encrypted email that only you could open, but you wouldn't be able to prove that it was from the sender. But, GPG signing has applications far beyond email. If you use a modern Linux distribution, it uses GPG signatures on all of its packages, so you can be sure that any software you install from the distribution hasn't been altered to add malicious code after it was packaged. Some distributions even GPG-sign their ISO install files as a stronger form of MD5sum or SHA256sum to verify not only that the large ISO downloaded correctly (MD5 or SHA256 can do that), but also that the particular ISO you are downloading from some random mirror is the same ISO that the distribution created. A mirror could change the file and generate new MD5sums, and you may not notice, but it couldn't generate valid GPG signatures, as that would require access to the distribution's signing key.

Why Sign Git Commits

As useful as signing packages and ISOs is, an even more important use of GPG signing is in signing Git commits. When you sign a Git commit, you can prove that the code you submitted came from you and wasn't altered while you were transferring it. You also can prove that you submitted the code and not someone else.

Being able to prove who wrote a snippet of code isn't so you know who to blame for bugs so the person can't squirm out of it. Signing Git commits is important because in this age of malicious code and back doors, it helps protect you from an attacker who might otherwise inject malicious code into your codebase. It also helps discourage untrustworthy developers from adding their own back doors to the code, because once it's discovered, the bad code will be traced to them.

How to Sign Git Commits

The simplest way to sign Git commits is by adding the -S option to the git commit command. First, figure out your GPG key ID with:


gpg --list-secret-keys --keyid-format LONG
sec# rsa4096/B9EF770D6EFE360F 2019-02-06 [SC] 
 ↪[expires: 2021-02-05]
. . .

In this case, B9EF770D6EFE360F is my long key ID. Why use this and not just my email address associated with my key? In the event you have multiple keys with the same ID, you might end up signing with the wrong key. By specifying the long key ID, you can ensure that you use the right key every time.

Once you know the key ID, add it to the -S option when you git commit:


git commit -S B9EF770D6EFE360F

Now when you submit the commit, it will prompt you to unlock your GPG key so it can sign the commit.

Of course, the goal is to sign every commit, and if you had to add this argument every time you committed code, it would be pretty annoying. So instead, add it to your ~/.gitconfig so it signs every time:


[user]
  name = Kyle Rankin
  email = kyle.rankin@puri.sm
  signingkey = B9EF770D6EFE360F
[commit]
  gpgsign = true

In the [user] section of your .gitconfig, after your name and email, add a signingkey option, and set it to the same key ID you used for the -S argument in git commit. Then add a new [commit] section, if it doesn't already exist, and add the gpgsign option set to true. This way, all of your GPG commits will be signed.

The final step once this is all set up, if you use a web-based Git repository like GitLab or GitHub, is for you to go to your shared Git repository, log in to your account, and find the section that lets you upload GPG public keys, so you can add your corresponding GPG public key to your account. This way, when you do sign your commits, the Git repository will be able to verify the signature against your public key and add a handy "Verified" tag that denotes that the commit came from you.

—Kyle Rankin