Commit signing for portable OpenSSH

Damien Miller djm at
Wed Aug 31 22:58:46 AEST 2022


We are in the process of converting the portable OpenSSH repository
to require signed commits, tags and pushes, using git's recent ssh
signature support. So far it's gone very smoothly, and we hope to have
it enforced for all commits soon.

We maintain our own git repository for portable OpenSSH, that is
automatically mirrored to github. We use "pre-receive" and "update"
hooks to check for signed pushes and tags/commits respectively, using
an in-repository allowed_signers file.

Github doesn't support signed push, but it does support signed commits
and, as of last week, now supports SSH signatures on commits and
tags[1], so recent changes[2] should all show up as verified in their

If you check out OpenSSH locally and want to verify signatures, then
you'll need to configure the path to the list of trusted keys. This is
checked in to the repository and also cross-signed with the release
PGP key.

The following commands, when run from the root of checked-out
repository, will check the signature on the allowed_signers file (this
assumes you have already trusted the OpenSSH release signing PGP keys),
configure git to use it for the current repository and (hopefully) show
a good signature on the most recent commit:

$ gpg --verify .git_allowed_signers.asc
$ git config --local gpg.ssh.allowedSignersFile .git_allowed_signers
$ git show --show-signature HEAD

Contributing to portable OpenSSH remains the same. You can still send
us patches or pull requests as normal. The developer who merges them
will sign them as they commit them to the repository.

One thing to note is that we'll no longer be using PGP to sign Git
tags as we have done in the past. We'll be using one of the keys in
the .git_allowed_signers file. We may also sign release tarballs
using one of these keys (in addition to PGP).

If you're curious on how to configure git signing using SSH keys
for your own repositories, this is basically the recipe:

$ KEY=~/.ssh/id_ecdsa_sk
$ git config --local gpg.format ssh
$ git config --local user.signingkey $KEY
$ git config --local tag.gpgsign true
$ git config --local commit.gpgsign true
$ git config --local push.gpgsign if-asked

(You can substitute --global for --local if you want to turn it on for
all your repositories)

Note that this recipe uses a passwordless FIDO private key directly,
since that is what I use everywhere. If you're using a software key,
then you should instead configure git to look for the key in your
ssh-agent, by specifying the full public key in the user.signingkey
configuration, i.e.

$ git config --local user.signingkey "ssh-ed25519 AAAAC3N..."

Using ssh-agent is more secure than using a passwordless software key
and much more usable than having to type your passphrase for each
signature operation. 

I should note one rough edge using FIDO keys with git: the
touch-required notifications seem to be sent to /dev/null by git, so if
it looks like git is hanging when you are attempting a commit, tag or
push then check to see if your FIDO token is plaintively blinking to get
you to notice and touch it.

If anyone is interested in the repository hooks that we're using to
enforce signatures, then let me know and I'll tidy them up and share
them. Forewarning: they are pretty basic and adapted for how we run
our repository - in particular they support a fast-forward only
repository, i.e. they don't handle merge commits.



More information about the openssh-unix-dev mailing list