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

This is a draft post. Find out more about what that means. Get in touch if this post could use an improvement.

You can have git use a specific SSH key, per repo.

This is great if you have – or would like to use – different SSH keys for each clients. To limit exposure, I try and use separate GitHub/GitLab/BitBucket account + SSH key for each client.

If one key is compromised, none of your other work is exposed.

Show me 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:

  • You don’t need to mess with the environment variables on your shell.
  • It is a set-it-and-forget-it configuration. You do not need to supply the env variable to each git command.

Simple and elegant.

Dealing with conflicts from ~/.ssh/config

If, like me, you do not use the default identity keys expected by the SSH client, you have likely configured SSH to read a default key, 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, with the custom key specified coming in second, or third — and so on — depending on if SSH 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:

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

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

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

It’s because your SSH client never attempted the second key!

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.