Multiple SSH keys for different Github accounts

Connecting to a Github account via SSH is my go to approach. It's easy, secure and allows me to avoid logging in every time I pull or push to a repo. Recently, I got into a situation where I had to use different Github accounts, accessing different Github organizations and of course I had an urge to authenticate my machine with the same SSH key for those accounts as well.

And since we all know that using one password for multiple accounts is not a good idea, I'd assume that using the same ssh key-pair for authentication in several places is not a good practise either.

Ok, then generating several keys and naming those accordingly is one thing, but how to make sure that Github will be able to pick up the right one based on the remote repo I'm dealing with? Well, the solution turned out to be not so complicated.

Let's have a look:

To solve the issue we will be using ssh-keygen and ssh-agent cli commands and if you're on Mac or a Linux machine there should be no issue with that, Windows users might need to install those tools, or use other tools.

Now in this situation I have my personal Github account syntax-punk and two other accounts foo-as and bar-as. So let's start with generating keys first:

Navigate to the .ssh folder in your home folder in your cli (if the folder doesn't exist, create one) and generate key pairs for each account:

$ cd ~/.ssh

$ ssh-keygen -t ed25519 -C "your_email@example.com"

> Enter a file in which to save the key (/Users/YOU/.ssh/id_ALGORITHM): [Press enter]
> Enter passphrase (empty for no passphrase): [Type a passphrase]
> Enter same passphrase again: [Type passphrase again]

Note: if your system doesn't support ed25519 algorithm, then you can use rsa instead.

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Now in my case I've generated 3 pairs of public and private keys and named them accordingly:

> id_ed25519_syntax-punk
> id_ed25519_foo-as
> id_ed25519_bar-as

Now we need to run ssh-agent in the background in order to add private keys to it later on:

$ eval "$(ssh-agent -s)"
> Agent pid 51337

Next, we need to update our ~/.ssh/config file (if the file doesn't exist, create one) this will help our machine to correctly identify which key to use for the given account. Here is what we want to have in the config file:

Host github-<account-name>  # <account-name> is the name of your account
    HostName github.com     
    User git
    IdentityFile ~/.ssh/<your_private_key>s  # path to your private key

In my case the config would looks like this:

Host github-syntax-punk
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_syntax-punk

Host github-foo-as
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_foo-as

Host github-bar-as
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_bar-as

And finally, let's add our private keys to the ssh-agent:

$ ssh-add ~/.ssh/id_ed25519_syntax-punk
$ ssh-add ~/.ssh/id_ed25519_foo-as
$ ssh-add ~/.ssh/id_ed25519_bar-as

If you're on Mac and have entered a passphrase in the previous step, you might want to store the passphrase in the keychain, so you don't have to enter it every time you use the key. Then the command will look like this for you:

$ ssh-add --apple-use-keychain ~/.ssh/your_key_name

And now we are all set to navigate to each Github account and add relevant public key to the account. I assume you know how to do that, but if not, here is a link to the Github docs.

P.S. When you restart your machine you might want to start ssh-agent again, you can either run the

$ eval "$(ssh-agent -s)"

command again or add the command to your ~/.bashrc, ~/.bash_profile or ~/.zshrc file (depends on the bash you're using).

Cheers!

🌍