Using Unique SSH Keys for Multiple GitHub Accounts
As a software engineer and all-around nerd, I’m pretty picky about computers. The Mac Mini provided by my company is fine, but, let’s face it, my custom-built desktop gaming rig and my Dell XPS 15 laptop (MacBook power at half the price — seriously, you should check it out!) both blow it out of the water in terms of performance.
Windows Subsystem for Linux (WSL) and the VS Code ecosystem have both matured to the point where I can use Windows for development (without dual-booting Linux!). Since the pandemic started, I‘ve been using my personal equipment for work, and it’s been fabulous. So I was excited to start working on some new side projects this week during my vacation.
People, IT SUCKS. Seriously. It’s painful. I have separate GitHub accounts for work and personal projects, each of which requires a unique SSH key. Since I already had my work SSH key set up on my machine, I couldn’t actually work with any of my personal repos.
Googling “how to use different ssh keys for different GitHub accounts” led to a lot of instructions for messing with my SSH config that didn’t even work, and actually broke the GitHub SSH connection on my work account.
Luckily, a random sighting in the comments of an SO thread, plus a deep dive into the git config documentation led to an epiphany: includeIf. This innocuous-looking command was the key to my GitHub conundrum.
With a single GitHub account, you have a single .gitconfig
file. This is usually located in your home directory. It defines things like your name, email address, and other random git settings. However, if you’re like me and need to juggle multiple GitHub accounts, it’s not quite enough. This is where includeIf
comes in. By adding it to my main .gitconfig
, I was able to conditionally include other config files based on the current directory. Combined with the core.sshCommand
option, this was the perfect fix for my GitHub woes. Here’s how I did it:
(Note: the commands below worked on my WSL setup powered by Ubuntu 20.04. If you’re using macOS or a different Linux distro, you might need to tweak them a bit. And if you’re using plain ol’ Windows, I’m sorry.)
Start by copying your current .gitconfig
file, once for each profile you need to create. Since I have work and personal profiles, I made two.
cp ~/.gitconfig ~/.gitconfig-work
cp ~/.gitconfig ~/.gitconfig-personal
You should now have three separate files. Open them all in your editor of choice. If you’re using VS Code (and you’ve added it to your path), you can open them all in one shot like this:
code ~/.gitconfig ~/.gitconfig-work ~/.gitconfig-personal
In your main .gitconfig
file, remove any account-specific settings. I left anything that would be the same across both accounts, like my pull.rebase
setting. At the top of your cleaned-up file, add the following block once for each profile. Make sure to edit your paths and file names as necessary:
[includeIf "gitdir:~/work/**"]
path = ~/.gitconfig-work
In your .gitconfig-work
and .gitconfig-personal
files, remove any shared configuration, and edit the user name and email. Add the following snippet to each, making sure to change the key names accordingly.
[core]
sshCommand = ssh -i ~/.ssh/id_rsa -F /dev/null
My final files look like this:
Now, close your terminal, open a new one, and test it out! You should be able to push and pull all your repos, as long as they are below the directory that matches your includeIf
statement for the account that has access to them.
Doesn’t it feel good to solve a problem?
Have you solved any interesting problems recently? I’d love to hear about them!