DEV Community

Wenchen (Neo) Li
Wenchen (Neo) Li

Posted on

(Correctly) Telling git about your SSH key for signing commits

GitHub recently added a feature to support SSH commit verification, which in my opinion, should be easier than using GPG. (Git has released signing with SSH key since 2.34.)

After generating your SSH key pair (which you can learn about from here, 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:

// NOT 100% correct example, explanation below
$ git config --global user.signingkey 'ssh-ed25519 AAAAC3(...)'
Enter fullscreen mode Exit fullscreen mode

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:

git config --global user.signingkey ~/.ssh/id_ed25519.pub
Enter fullscreen mode Exit fullscreen mode

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

git config --global user.signingkey "key::ssh-ed25519 (...)"
Enter fullscreen mode Exit fullscreen mode

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. 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?
Enter fullscreen mode Exit fullscreen mode

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:

git config --global user.signingkey "key::sk-ssh-ed25519@openssh.com AAAA(...)"
Enter fullscreen mode Exit fullscreen mode

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 ๐Ÿ˜†

Git config to use SSH for signing:

git config --global gpg.format ssh
Enter fullscreen mode Exit fullscreen mode

Turn on commit and tag signing respectively by default:

git config --global commit.gpgsign true
git config --global tag.gpgsign true
Enter fullscreen mode Exit fullscreen mode

Set the user.signingkey to a pub key generated from a physical security key:

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
Enter fullscreen mode Exit fullscreen mode

You can also set it to automatically use the first available key from your ssh-agent:

git config --global gpg.ssh.defaultKeyCommand "ssh-add -L"
Enter fullscreen mode Exit fullscreen mode

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! ๐ŸŽ‰

Top comments (1)

Collapse
 
li profile image
Wenchen (Neo) Li

Correction

Raw literal key values are only supported when it starts with ssh- for backward compatibility, which is deprecated. So not just physical security keys, other public keys like ecdsa-sha2-abc123 wouldn't work either without the key:: prefix.

Reference: git-scm.com/docs/git-config#Docume...

Related questions from Stack Overflow: