Back

How to Sign Git Commits Using OpenPGP

In this article, I’m going to show you why and how you can sign your Git commits using public-key cryptography.

Why should you want to sign your Git commits? Because it is ridiculously easy to fake an identity. See for yourself. In the following command, replace the name John Doe with any name you like, e.g., Barack Obama.

git config --global user.name "John Doe"

All your future commits will now appear to be authored by the name you provided. You can verify that like so:

git config user.name

Now you can fork anyone’s Git repository, open a new pull request, and what the maintainer in our example would then see is that the commit was authored by Barack Obama himself. Under that illusion, the maintainer could think, “Holy cow, Barack Obama wants to improve my code?!? I better merge that pull request immediately.” He’d then proceed to integrate your potentially malicious code into his codebase, unaware of the damage he’s doing—all because he put trust in something that can so easily be faked.

The same way, someone could impersonate you. For instance, a co-worker who dislikes you could intentionally write crappy code or even malicious code under your name, so that you then get the blame or are disgraced. That’s why you should sign your Git commits. All your commits will then have a little green “Verified” next to their hash. This has two advantages:

  • people will know that it really was you who authored that code
  • when there’s always that green “Verified” stamped onto your code, and then one day a crappy commit, lacking that “Verified”, comes pretending to be authored by you, you have better chances arguing that it wasn’t you who authored that garbage

I hope you’re convinced to sign all your commits from now on. Here’s how you do it.

Requirements

I assume that you’ve already set up Git appropriately (see here). Specifically, that you’ve configured your global user name and user email. If not, do it like so:

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

(In case you played along with my silly example and changed your name to someone else’s, you’d need to undo that at this point.)

Install GnuPG

First, you need to get GnuPG (or short, GPG). GnuPG is the implementation of the OpenPGP standard. In case you’re using macOS and you’ve followed my guide on how to install software using Homebrew, you can install the GPG Suite like so:

brew install --cask gpg-suite

Configure Your Own Computer

To sign commits, you first need a key pair. Generate one with this command by following the presented instructions:

gpg --full-generate-key

Choose (1) RSA and RSA (default), i.e., enter 1 or simply press Enter. Next, type in 4096 to generate a RSA key pair with 4096 bits. In case you need help with generating the key pair, follow this guide by GitHub.

Now that you have a key pair, i.e.

  • a private key to sign your commits and
  • a corresponding public key for others to verify that it really was you who signed that commit and not somebody else,

you need to get the ID of your private key. This can be very confusing, but these next two commands make it very, very easy. They eliminate all the guesswork and automatically set up your configuration file with the right value.

signingkey=$(gpg --list-secret-keys --keyid-format LONG "`git config --get user.email`" | grep sec | awk '{print $2}' | awk -F'/' '{print $2}' | tail -n 1)
git config --global user.signingkey $signingkey

To understand the following command, you need to know that signing commits is optional, i.e., despite all the efforts so far, commits will not be signed unless you specifically say so (by adding the -S flag to the git commit command). Since we don’t want to have to do that with every single commit, we configure Git with the following command such that all future commits are signed by default.

git config --global commit.gpgsign true

In case you use Git through applications with a graphical user interface, e.g., the highly recommended Git Tower or the free Github Desktop, you may need to point Git to the gpg2 executable on your system:

git config --global gpg.program $(which gpg2)

Great! Now you’re done with the configuration on your end. Let’s move on to the remote counterpart, e.g., GitHub.

Configure GitHub

So far, we’ve checked off the “private half” of public-key cryptography. That is, signing the commits on your end with your private key. Now we need to check off the “public half”. After all, if there’s no way for GitHub to verify that this incoming signed commit was actually signed by you, then there’s no value in signing the commit in the first place. The following command will copy the necessary public part of your key pair to your clipboard.

gpg --armor --export `git config --get user.signingkey` | pbcopy

Since that key is public, i.e., specifically meant to be read by others, you can unhesitatingly copy and paste it wherever you want. There’s no need to fear for your privacy when we copy that part into the clipboard, since it’s public. What you now need to do is paste that snippet into the appropriate section in the GitHub settings. This next command will open the right place in your web browser where you can then paste that snippet:

open https://github.com/settings/keys

In case you use GitLab, the procedure is exactly the same. Paste the snippet here too:

open https://gitlab.com/profile/gpg_keys

Good news. You’re finished! Everything’s done and your commits should from now on have that shiny green “Verified” tag next to their hash.

Note: in order for everything to work, the same email address you used earlier when you typed the following command must be added to your GitHub / GitLab. In GitHub’s words, “your GPG key must be associated with a GitHub verified email that matches your committer identity.”

git config --global user.email johndoe@example.com

Final Words

Let me know whether everything worked out or whether you still need help. Hope you find this guide helpful and you consider following me on Twitter so that you will get notified the next time I publish a useful tutorial like this one. Cheers!

As an Amazon Associate I earn from qualifying purchases.
Built with Hugo
Theme Stack designed by Jimmy