Organizing SSH Keys and setting up an SSH config file
Summary: I wanted to use multiple GitHub accounts with separate emails and separate SSH keys. I was able to do this, but it was tedious, until I discovered how to use an SSH config file to register Host aliases and specify which SSH IdentifyFile to use with each Host. I ultimately built a simple tool to help me generate a correctly configured SSH Config file and Git commands to copy/paste/configure each specific git project.
Problem: Too many SSH keys
Over time, I’ve generated dozens of SSH keys in my ~/.ssh/ directory. Some are reused in multiple services, and others are generated once for a single project on a single platform. It has become a headache to manage them, remember what services they belong to, what projects rely on them, or know if I can delete them. Many of my keys are generated more than a year ago, and I just can’t quite remember if I need them.
Solution 1: Named Folders
When I recently had to generate new SSH keys for a service, I had the idea to put them in a named folder in the .ssh folder. I did that, and updated a few additional services. Here’s an example of what it looked like:
~/.ssh/github/keys
~/.ssh/aws/keys
~/.ssh/other-github-account/keys
All SSH keys were in a folder named for the service those keys were used for. This made a lot of sense to me, and it was visually pleasing and easy to parse when I navigated to my ~/.ssh/ folder. But there was still a problem.
Problem: It was tedious to instruct each project to use the correct key file. I had to update the local shell variable to reference the correct key for every new session. I did so like this:
GIT_SSH_COMMAND="ssh -i ~/.ssh/project-name/id_ed25519 -o IdentitiesOnly=yes"
This worked fine, but it was annoying and tedious, I had to do it every single time I entered a shell in that project. I wanted something more automatic.
Solution 2: SSH Config File
Finally, after weeks of the previous solution, I discovered that I could register an SSH config file at the location ~/.ssh/config and in it I could specify Host aliases.
A Host alias is a variable name I can assign to a specific URL, and under that host alias I can specify what key to use. This makes it trivial and automatic to assign a specific project to a specific .ssh key. Here’s what an example ~/.ssh/config file would look like:
# ── GitHub Personal ────────────────────
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/github-personal/id_ed25519
IdentitiesOnly yes
# ── GitHub Work ────────────────────────
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/github-work/id_ed25519
IdentitiesOnly yes
# ── Azure Account-A ────────────────────────
Host azure-account-a
HostName github.com
User git
IdentityFile ~/.ssh/azure-account-a/id_ed25519
IdentitiesOnly yes
A few notes:
- Comments are only included for organization and readability.
- White-space is inconsequential. The two column layout is done manually for readability.
- The field
Hostis the Alias name you will use in each project. - The field
HostNameis the actual URL that gets resolved. - The
IdentityFilefield is the SSH key that will be used when this Host Alias is invoked.
Hopefully it is clear how this solves the problem. If I have multiple SSH keys in various locations, and I want to specify that a project uses that key, I just need to assigned the git origin of the project to use a specified alias, and all SSH commands to that alias will use the specified key.
A new problem: The Host alias solution works, but it’s now tedious to update every project on my computer to use the correct SSH Host alias. I have to copy/paste/edit/copy/paste commands in the root directory of every project on my computer to set the proper Host alias for that repo. Ugh…
Solution 3: Make a tool
I wanted to make a tool that would allow to me to add new Host aliases, edit existing ones, and provide me with copy/paste commands that I can take to each project to properly configure it to use the Host alias I want it to use.
So I built that tool! SSH Config Generator
The tool is pretty basic, and here’s what it does:
- Register a Host Alias: Fill in the Host Alias, Hostname, user, and location of the IdentifyFile.
- Optionally, input the Identity name and email.
- Test the connection, by copy/pasting the test connection command.
- Update projects to use the alias in their SSH commands a. Copy the git URL of the repo into the input field b. Copy/paste the commands to configure the project to use the new SSH Host Alias
I hope this helps you manage multiple SSH keys and accounts.
This article was written by hand, by me, Trevor Blackman, a real human. <3