TIL how to set up multiple SSH keys (for multiple Github accounts)
⋅ 4 minute read
Setting up SSH keys is one of these things I need to do every couple of months. Inevitably, I don’t remember how to do it and then follow some tutorial, e.g. the Github Docs . It kind of always works but I haven’t fully internalized how to properly manage those different SSH keys.
Disclaimer: This learning was provoked by setting up multiple SSH keys for different Github accounts (I know how to do that) and then being able to git clone {private-repository} a private repository with the correct ssh key (I didn’t know how to do that). An example use case could be a personal and professional Github account that don’t have access to the same private repositories. So ideally when we git clone we want to automatically pick the right ssh key.
1. Generate the SSH keys for each account
Let’s assume we want to generate new separate ssh keys for each account. I like to have them all in my ~/.ssh folder.
We can use the key generation command
$ cd ~/.ssh
$ ssh-keygen -t ed25519 -C "your_email or your_name"
where we specify the encryption type (-t) as ed25519 which is
Edwards-curve Digital Signature Algorithm
and generally
recommended over RSA-based keys
. The comment (-C) argument allows us to optionally add a comment that is added at the back of the key so that you remember who it created. People often use their email address. However, this is not used anywhere to select the key.
$ Generating public/private ed25519 key pair.
$ Enter file in which to save the key (/Users/youruser/.ssh/id_ed25519): /Users/youruser/.ssh/github_personal
$ Enter passphrase for "github_personal" (empty for no passphrase):
This generates both the private and public key github_personal (private) and github_personal.pub (public) in the specified path. If we entered a passphrase the private key will be encrypted as well using
3DES
. We can check out what the keys look like:
$ cat github_personal.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDycaSFXnekEe32AZFhhDp3Q14JRXF7bu8CNfGf7Z6hN your_email
and
$ cat github_personal
-----BEGIN OPENSSH PRIVATE KEY-----
somegibberylongkeyperhapsfurtherencryptedusingpassphrase
-----END OPENSSH PRIVATE KEY-----
Let’s also use the same method to create a keypair for work (github_work, github_work.pub). Once we have these keys, we can add them to our two Github accounts.
2. Associate the public keys with the Github accounts
In both Github accounts, navigate to Access:SSH and GPG Keys -> New SSH key and add the public key as an Authentication Key to the account. Github now has the ability to verify messages that were signed by the corresponding private key of the pair.
3. Set up OpenSSH client config file
The file ~/.ssh/config allows us to configure “Host” specifications that we can refer to when using SSH (e.g. when git clone uses the SSH protocol for data transfer). The file looks like this:
Host hostname1
SSH_OPTION value
SSH_OPTION value
Host hostname2
SSH_OPTION value
In our case, we define the two different github identities that we want to be able to select:
Host github-personal
User git
PreferredAuthentications publickey
Hostname github.com
IdentityFile ~/.ssh/github_personal
Host github-work
User git
PreferredAuthentications publickey
Hostname github.com
IdentityFile ~/.ssh/github_work
This defines which keys to use when we connect using SSH via user@host. So when we the test the config by running ssh -T git@github-personal SSH will use the SSH key ~/.ssh/github_personal as specified in the file. (Note: We can name the host and user whatever we want.)
4. Use the right hostname when cloning repositories
Let’s say we want to git clone a repository that only our work account has access to, then I can use the git clone command git clone {user}/{host}:{repo_path}.git:
$ git clone git@github-work:/org1/project1.git
or more explicitely:
$ git clone ssh://git@github-work/org1/project.git
git/ssh will look into the config file and select the configured private key for the provided host.
GitHub will send a challenge (message) to our machine for authentification. The private key will be used to sign this challenge and our machine then sends the signed message back to the Github server. The Github server will use the stored public key (from step 2) to verify the signature and allow a connection.
Note: If in step 1) we decided to encrypt the private key with a passphrase we will be prompted to provide it. Normally, at that point MacOS will offer us to add this passphrase to our Keychain .
If you have any thoughts, questions, or feedback about this post, I would love to hear it. Please reach out to me via email.
Tags:#ssh #git