Using your Yubikey for Signed Git Commits
Tags: security, linux, github, devops
Published: 2020-09-10 06:30:39

By signing our Git commits, we can allow folks to verify that they were really written by the author tagged on the commit. If you’ve got a Yubikey set up as per our [Using your Yubikey to get started with GPG Post](https://dev.to/paulmicheli/using-your-yubikey-to-get-started-with-gpg-3h4k), it’s easy to configure.

## Setup

With your Yubikey inserted and unlocked, find the ID of your GPG key:

```
$ gpg --list-secret-keys --keyid-format LONG
/home/paulmicheli/.gnupg/pubring.kbx
------------------------------------
sec   r******/3**************E 2020-07-30 [SC] [expires: 2022-07-30]
      6***************************E
uid                 [ultimate] Paul Micheli <paul@*********.com>
ssb   r******/A***************0 2020-07-30 [E] [expires: 2022-07-30]

sec>  r******/D**************4 2020-07-30 [SC]
      3**************************************4
      Card serial no. = 0006 10300768
uid                 [ultimate] Paul Micheli <paul@*********.com>
ssb   r******/0**************8 2020-07-30 [E]
```

Then, get your public key so that you can tell GitHub about it. The argument here is the long ID from the above command:

```
$ gpg --armor --export  A**********0
-----BEGIN PGP PUBLIC KEY BLOCK-----
m[NOPE NOT HAVING THE MIDDLE]
=ZDdO
-----END PGP PUBLIC KEY BLOCK-----
```

Copy the above public key, including the begin and end blocks, [and then add it as a new key on GitHub](https://docs.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account).


We then need to **tell Git to use GPG to sign commits**, and specifically this key. Use the short ID from the output of the --list-secret-keys command we ran earlier. In my example, it follows rsa3072/A97FDF705EF51C50:
```
$ git config --global commit.gpgsign true

$ git config --global user.signingkey A**********0
```

Nearly there! Let’s now **restart the GPG agent:**

```
$ gpg-connect-agent reloadagent /bye
```

## Testing

Make a commit in any repository, and hopefully you shouldn’t see an error message.

Run git log --show-signature to check that the commit was signed:

```
$ git log --show-signature

commit 925fb1cae8c33c0f7f4fd6b270fc9f4cf6a8ef80 (HEAD -> master, origin/master, origin/HEAD)
gpg: Signature made Thu 30 Jul 2020 13:59:27 BST
gpg:                using RSA key 6**********************E
gpg: Good signature from "Paul Micheli <paul@*********.com>" [ultimate]
Author: Paul Micheli <paul@*********.com>
Date:   Thu Jul 30 13:59:27 2020 +0100

    signed commit test
```

## Push

Assuming that everything has worked thus far, you can now git push and bask in the resplendent glory of a lovely “Verified” badge on GitHub:

## Why Bother?

You might ask what the benefit of all this is. After all, you’re already authing to GitHub with your SSH key, right?

Your SSH key proves that you can talk to GitHub, and that you’re allowed access to the repository in question. It doesn’t prove that the commits you are pushing were really written by the flagged authors though.

It’s trivial to make a commit with a false identity:

```
git commit -m "implement sensible error handling" --author="Robby Bobby <robbybobby@google.com>"
```

You can then push this, authenticating with your SSH key (or HTTP basic credentials), which is of course totally valid.

You’ve then managed to masquerade as a colleague, presumably pushing awesome code to help them get a raise. Or, perhaps, you’ve done something nefarious. But you’d never do a thing like that, would you?