Organisation-specific git authentication and commit signing
Using SSH keys stored in 1Password on MacOS
Recently I wanted to use a separate SSH key for work on repositories in a specific GitHub organisation, but continue to use a single GitHub user account. I already had some organisation-specific git configuration which sets the email address used in commit notes and I've now managed to extend that to incorporate using an organisation-specific SSH key both for authentication with GitHub and for signing my commits.
One complication was that I wanted to continue to manage my SSH keys in 1Password which I use as my SSH agent. I struggled to find a way to make the 1Password SSH agent offer the correct organisation-specific key, but eventually worked out that I could set core.sshCommand in my organisation-specific git config to override the default ssh command and specify the relevant public key using the -i (identity file) option. Although this feels like a bit of a hack, the only downside I can see is that I had to export each of the public keys to my ~/.ssh directory which effectively introduces duplication, but it's duplication that I can live with.
While testing this configuration I came across the gpg "ssh".allowedSignersFile git configuration option which means you can use git log --show-signature to check your commits have been signed correctly.
1Password configuration
And then download the public key for each to:
~/.ssh/github-organisation-1.pub~/.ssh/github-organisation-2.pub
GitHub configuration
Emails
In your GitHub email settings:
- Add & verify
email.address@organisation-1.com - Add & verify
email.address@organisation-2.com
SSH keys
In your GitHub SSH key settings:
- Add SSH key for organisation 1 as authentication key
- Add SSH key for organisation 2 as authentication key
- Add SSH key for organisation 1 as signing key
- Add SSH key for organisation 2 as signing key
SSH configuration
Configure ssh to use 1Password as its agent. And list allowed signers for each organisation to be used as allowedSignersFile.
# ~/.ssh/config
Host *
IdentityAgent <path-to-1password-agent.sock>
# ~/.ssh/allowed_signers_for_organisation_1
email.address@organisation-1.com ssh-ed25519 <ssh-public-key-for-organisation-1>
# ~/.ssh/allowed_signers_for_organisation_2
email.address@organisation-2.com ssh-ed25519 <ssh-public-key-for-organisation-2>
Git configuration
Shared
# ~/.gitconfig
[gpg]
format = ssh
[gpg "ssh"]
program = /Applications/1Password.app/Contents/MacOS/op-ssh-sign
[commit]
gpgsign = true
[includeIf "gitdir:~/Code/organisation-1/**"]
path = ~/.config/git/organisation-1.inc
[includeIf "gitdir:~/Code/organisation-2/**"]
path = ~/.config/git/organisation-2.inc
Organisation 1
- Use SSH key for organisation 1 to authenticate with GitHub
- Use SSH key for organisation 1 to sign commits
- Specify allowed signers for organisation 1 (used by e.g.
git log --show-signature)
# ~/.config/git/organisation-1.inc
[user]
email = email.address@organisation-1.com
signingkey = ssh-ed25519 <ssh-public-key-for-organisation-1>
[core]
sshCommand = "ssh -i ~/.ssh/github-organisation-1.pub"
[gpg "ssh"]
allowedSignersFile = ~/.ssh/allowed_signers_for_organisation_1
Organisation 2
- Use SSH key for organisation 2 to authenticate with GitHub
- Use SSH key for organisation 2 to sign commits
- Specify allowed signers for organisation 2 (used by e.g.
git log --show-signature)
# ~/.config/git/organisation-2.inc
[user]
email = email.address@organisation-2.com
signingkey = ssh-ed25519 <ssh-public-key-for-organisation-2>
[core]
sshCommand = "ssh -i ~/.ssh/github-organisation-2.pub"
[gpg "ssh"]
allowedSignersFile = ~/.ssh/allowed_signers_for_organisation_2