Configure git to use a specific SSH key for a repository permanently.

You can have git use a specific SSH key per repository.

This is great if you have — or would like to use — different SSH keys for each one of your clients, allowing for limited exposure between them.

The code.

When in the desired repo on your terminal, configure git by specifying the private key to use:

git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_clientX"

In this case, you’re directly configuring git. What is git doing under the hood? It uses an SSH environment variable to execute commands based on your config.

The abstraction is great because:

  • No need to set environment variables on your shell.
  • It is a set-it-and-forget-it style configuration. You do not need to supply the env every time you run a git command.

Elegant!

Dealing with conflicts from ~/.ssh/config

If, like me, you do not use the default identity key expected by your SSH client, you have likely configured SSH to consider another key as a default, as follows:

// ~/.ssh/config
Host *
        IdentityFile ~/.ssh/id_ed25519_personal

Key to note here is when you configure git to use a separate identity file than what is the default one

…it adds or appends to the list of IdentityFiles to try when authenticating.

Your per-repo SSH key may actually come in second, or third — and whatever the actual position — depending on if the SSH agent can find any matches in the config file for the current host being attempted to be connected with.

After configuring git, the order of keys to be tried could be, for example:

  • ~/.ssh/id_ed25519_personal
  • ~/.ssh/id_ed25519_clientX

You can see this in action by using the verbose flags: -vvv.

If you’ve got an account on the same service where your personal key is configured, SSH will happily use that key first, call it a day, and you will run into the following error:

Forbidden
Please make sure you have the correct access rights and the repository exists

It’s because your SSH client never attempted the second key (which is what you need)!

To work around this, a solution I’m happy with is passing a config file to the ssh command as follows:

git config core.sshCommand "ssh -F /dev/null -i ~/.ssh/id_ed25519_clientX"

Introduced in git 2.10

Please note this works on git 2.10 + — released in late 2016.

You should be covered, but if you wish to check your currently installed version of git, run:

git --version

You can find the 2.10.0 release notes here.

Quote for convenience:

A new configuration variable core.sshCommand has been added to specify what value for GIT_SSH_COMMAND to use per repository.

Last updated on 11 September 2021. Join the discussion by writing me an email.