(Correctly) Telling git about your SSH key for signing commits
Tags: github, git, ssh, gpg
Published: 2022-08-26 21:30:47

GitHub recently added a feature to support [SSH commit verification](https://github.blog/changelog/2022-08-23-ssh-commit-verification-now-supported/), which in my opinion, should be easier than using GPG. (Git has released signing with SSH key since [2.34](https://github.blog/2021-11-15-highlights-from-git-2-34/#tidbits).)

After generating your SSH key pair (which you can learn about from [here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent), you now need to tell git about it. And the way to do it is through the `user.signingkey` git config.

## Good

However for some reasons, almost all of the tutorials and instructions online are saying you would need to copy and paste the literal public key as the git config value like this:

```sh
// NOT 100% correct example, explanation below
$ git config --global user.signingkey 'ssh-ed25519 AAAAC3(...)'
```

## Better

While it seems to work (actually only with non-physical keys), I found that you could also provide your public key file path like this, which might be better in some ways:

```sh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
```

At the same time I also found that the "proper" way to do literal public key value is to prefix with `key::`, like this:

```sh
git config --global user.signingkey "key::ssh-ed25519 (...)"
```

I found out from what appears to be the git mailing list archive? https://lore.kernel.org/git/20220628162342.ootjobbjtxg7b7ay@fs/t/

## Physical security keys

All the FIDO2 devices (not only the more sophisticated YubiKeys, which can do resident/discoverable keys though) should be able to generate SSH keys since [OpenSSH 8.2](https://www.openssh.com/txt/release-8.2). So I wanted to utilize my physical security keys with this, and that's when I got this error:

```
Couldn't load public key sk-ssh-ed25519@openssh.com AAAA(...)
: No such file or directory?
```

That's actually when I had to search and found out for a SSH key pair generated from a physical security key which has `sk-ssh` prefixed in public key literal string, or `_sk` suffixed in the key file name, a prefix of `key::` is required for the literal public key git config value:

```sh
git config --global user.signingkey "key::sk-ssh-ed25519@openssh.com AAAA(...)"
```

## File path is just easier

So in conclusion, using file path for this config is just easier in many ways and would prevent the prefix missing error (`No such file or directory?`) from the root of it.

## Some lines for copy and paste

Lastly as bonus content, here are some lines for your convenience :laughing:

Git config to use SSH for signing:
```sh
git config --global gpg.format ssh
```

Turn on commit and tag signing respectively by default:
```sh
git config --global commit.gpgsign true
git config --global tag.gpgsign true
```

Set the `user.signingkey` to a pub key generated from a physical security key:
```sh
git config --global user.signingkey ~/.ssh/id_ed25519_sk.pub

// or for an ECDSA key
git config --global user.signingkey ~/.ssh/id_ecdsa_sk.pub
```

You can also set it to automatically use the first available key from your ssh-agent:
```sh
git config --global gpg.ssh.defaultKeyCommand "ssh-add -L"
```

_Note that all of the `--global` git config option shown is optional as it's what you likely want, however you can set all of these as local config._

_Also note that while I don't know whether there's any difference in other OSs, this was tested on macOS 12.3 only._

Enjoy signing commits with your SSH key! :tada: