Signed Commits

How to get the shiny “Verified” badge on GitHub.

Izaak Schroeder
Bootstart
5 min readNov 6, 2018

--

Also known as: “the four easy steps to stopping people from doing fun things like this”:

git commit -am "Destroy production"
git filter-branch --env-filter \
'if [ "$GIT_AUTHOR_EMAIL" = "me@evilguy.com" ]; then
GIT_AUTHOR_EMAIL="unsuspectingvictim@mywork.com";
GIT_AUTHOR_NAME="Unsuspecting Victim";
GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all
git push -f

Signing all your commits with a private key only you hold means other less well-intentioned individuals cannot forge commits on your behalf. This key is different from your SSH keys which only exists to authenticate your identity to GitHub (or other SSH-based origins), not to authenticate the authorship of the commits themselves.

Step 1: Install GPG

First, make sure you have GPG setup. Using pinentry-mac is very handy not to have to enter in your GPG password constantly by storing your GPG password in your macOS keychain.

brew install gnupg pinentry-macmkdir -p "$HOME/.gnupg"
chmod 700 "$HOME/.gnupg"
echo "no-greeting" >> "$HOME/.gnupg/gpg.conf"
echo "use-agent" >> "$HOME/.gnupg/gpg.conf"
echo "use-standard-socket" >> "$HOME/.gnupg/gpg-agent.conf"
echo "pinentry-program /usr/local/bin/pinentry-mac" >> "$HOME/.gnupg/gpg-agent.conf"

NOTE: This assumes a typical homebrew installation; if you have custom settings adjust the /usr/local/bin/pinentry-mac path accordingly. You can find this path by running which pinentry-mac.

Step 2: Create a GPG Key

If you don’t already have a GPG key generate one:

gpg --gen-key

IMPORTANT: The name and e-mail you use must match the name and e-mail you configured in git. You can see the values you’ve configured by running the command: git config --global --get-regexp user..

If you’ve configured everything properly you should be prompted for a password to use with your new key:

NOTE: If you get an error complaining about a missing pinentry program then most likely you just need to restart gpg-agent. You can open “Activity Monitor”, search for gpg-agent, kill it and re-run the commands.

After generating your key, it should print out some information you will need to use in the following steps. The bolded value below will henceforth be referred to as HEXKEYGOESHERE.

pub   rsa2048 2018-04-23 [SC] [expires: 2020-04-22]
08EF873ADD30E043E17FA6B931B825A7737BA24
uid Sir Izaak <izaak@metalab.co>
sub rsa2048 2018-04-23 [E] [expires: 2020-04-22]

Remember to store your key somewhere safe. This will typically be your password manager like 1Password. Remember these are personal identity keys and not machine identity keys, so it is desirable to have them backed up.

gpg --export-secret-keys HEXKEYGOESHERE > backup.gpg

Step 3: Configure Git

Now you can configure git to use that key to sign all the commits you make:

git config --global user.signingkey HEXKEYGOESHERE
git config --global commit.gpgsign true

You can verify this is working by attempting to commit anything and then viewing the log with signatures turned on:

mkdir ~/test
cd ~/test
git init
echo "test" >> test
git add test
git commit -m "test"
git log --show-signature

You should see something that looks like:

commit ... (HEAD -> ...)
gpg: Signature made Mon 16 Apr 03:33:15 2018 PDT
gpg: using RSA key HEXKEYGOESHERE
gpg: Good signature from "Sir Izaak <izaak@metalab.co>" [ultimate]

Step 4: Configure GitHub

Lastly if you’re using GitHub, go to the GitHub key settings page and enter in your GPG public key. The public key string can be displayed in the console using the following command:

gpg --armor --export HEXKEYGOESHERE

Paste everything into the following form:

If you’ve done it all right you should see commits on GitHub that look something like this:

And then simply make sure master (and any other non-feature branches) only allows signed commits.

In The End

Although not foolproof, signed commits provide another layer of authenticity and peace of mind about the authorship of your code (or whatever else you’re putting into git).

Sign your commits. Get the shiny badge. 🙏

‡ Troubleshooting

We include this extra section for those times when something doesn’t go quite right.

Error: “signing failed: No secret key”

This means GPG can’t find the secret key that corresponds to the public key you configured. To see what the current value is, run the following command: git config --global user.signingkey. You can then list your existing keys with gpg --list-keys. The two should match. If they don’t you need to change the key git uses to the one from gpg. You can do so by running the command git config --global user.signingkey NEWKEYHERE.

GitHub GPG Key E-Mail “Not Verified”

All this means is that you haven’t associated the e-mail you chose with your GitHub account. Usually this happens on GitHub enterprise installations that have the default email taken from some kind of federated account system (e.g. LDAP).

And all you need to do to fix it is go into the e-mail settings in your GitHub account and add the e-mail you’ve chosen. This will also fix missing profile photos and links where GitHub displays commits.

--

--