Caution!

This is an old post. Information here may be out-dated, or the post may re­flect opin­ions or be­liefs I no longer share.

You can have git use a spe­cific SSH key, per repo.

This is great if you have - or would like to use - dif­fer­ent SSH keys for each clients. To limit ex­po­sure, I try and use sep­a­rate GitHub/GitLab/BitBucket ac­count + SSH key for each client.

If one key is com­pro­mised, none of your other work is ex­posed.

Show me the code

When in the de­sired repo on your ter­mi­nal, con­fig­ure git by spec­i­fy­ing the pri­vate key to use:

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

In this case, you’re di­rectly con­fig­ur­ing git.

What is git do­ing un­der the hood? It uses an SSH en­vi­ron­ment vari­able to ex­e­cute com­mands based on your con­fig.

The ab­strac­tion is great be­cause:

  • You don’t need to mess with the en­vi­ron­ment vari­ables on your shell.
  • It is a set-it-and-for­get-it con­fig­u­ra­tion. You do not need to sup­ply the env vari­able to each git com­mand.

Simple and el­e­gant.

Dealing with con­flicts from ~/.ssh/config

If, like me, you do not use the de­fault iden­tity keys ex­pected by the SSH client, you have likely con­fig­ured SSH to read a de­fault key, as fol­lows:

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

Key to note here is when you con­fig­ure git to use a sep­a­rate iden­tity file than what is the de­fault one, it adds or ap­pends to the list of IdentityFiles to try, with the cus­tom key spec­i­fied com­ing in sec­ond, or third — and so on — de­pend­ing on if SSH can find any matches in the con­fig file for the cur­rent host be­ing at­tempted to be con­nected with.

After con­fig­ur­ing git, the or­der of keys to be tried could be:

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

If you’ve got an ac­count on the same ser­vice where your per­sonal key is con­fig­ured, SSH will hap­pily use that key, call it a day, and you will run into the fol­low­ing er­ror:

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

It’s be­cause your SSH client never at­tempted the sec­ond key!

To work around this, a so­lu­tion I’m happy with is pass­ing a con­fig file to the ssh com­mand as fol­lows:

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 + –- re­leased in late 2016.

You should be cov­ered, but if you wish to check your cur­rently in­stalled ver­sion of git, run:

git --version

You can find the 2.10.0 re­lease notes here.

Quote for con­ve­nience:

A new con­fig­u­ra­tion vari­able core.ssh­Com­mand has been added to spec­ify what value for GIT_SSH_COMMAND to use per repos­i­tory.