1. Overview

In this tutorial, we’ll learn how to use a specific private SSH key when running Git commands that establish an SSH tunnel with the remote host.

2. Scenario

Let’s say we have two different GitHub accounts, one for work and another for personal usage. Furthermore, both of the accounts require different private SSH keys for authentication when performing commands such as git clone.

The private key to authenticate the work account is stored as ~/.ssh/id_rsa_work. On the other hand, the private key for our personal account is stored as ~/.ssh/id_rsa_personal.

Let’s look at the two different ways we can specify the different private keys to use when running the git clone command.

3. Using SSH Config File

One way we can specify a specific private key during the git clone is through the SSH config file.

Specifically, we can create two separate hosts for different private keys in the ~/.ssh/config file. Then, we can specify the different hosts in our SSH connection string during the git clone depending on which key we want to use.

Using the example we discussed earlier, here’s how the config file would look like:

$ cat ~/.ssh/config
Host github-work
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_work

Host github-personal
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_personal

The config file defines github-work and github-personal as two different host settings.

We can see that the HostName directives are both resolving to github.com since that’s the server we’ll connect to ultimately. Then, we use the IdentityFile directive to point to the different private key files for different accounts.

Now, to run the git clone on a repository that’s only accessible with the id_rsa_work private key, we can specify the SSH connection string with github-work as its host:

$ git clone git@github-work:corporateA/webapp.git

The underlying SSH client looks at the ~/.ssh/config file and resolves the github-work host to use the private key ~/.ssh/id_rsa_work.

Similarly, if we want to clone a repository that’s only accessible through the id_rsa_personal private key, we specify the github-personal host in our connection string:

$ git clone git@github-personal:bob/blog.git

4. Using core.sshCommand

The Git repositories offer a configurable option core.sshCommand. This configuration overrides the default SSH command when running any commands that require an SSH tunnel.

In this section, we’ll see how to use core.sshCommand to solve our problem.

4.1. Configuring core.sshCommand

Using the core.sshCommand configuration, we can customize the SSH command to include private key information for different repositories.

For example, we can clone the corporateA/webapp repository using the id_rsa_work private key in a one-liner:

$ git clone -c "core.sshCommand=ssh -i ~/.ssh/id_rsa_work" [email protected]:corporateA/webapp.git

In our example, we override the core.sshCommand at runtime using the -c option. Concretely, we change the SSH command to point to the private key we want to use using the -i option.

4.2. Persisting core.sshCommand on Repository Level

Instead of repeating the configuration override every time, we can persist it on a repository level using the git config command:

$ git config core.sshCommand "ssh -i ~/.ssh/id_rsa_work"

This command persists core.sshCommand configuration to the repository. This means Git will use this SSH command for any subsequent invocations.

To verify the configuration, we can retrieve it using git config –get to make sure it returns the new value:

$ git config --get core.sshCommand
ssh -i ~/.ssh/id_rsa_work

5. Summary

In this article, we discussed the problem of authenticating to GitHub using two different pairs of private SSH keys.

Then, we saw how we can preset SSH hosts with different private keys which we can refer to during our usual Git commands.

Finally, we also looked at the core.sshCommand which overrides the default SSH command used by the Git client.