Managing Multiple Git Accounts with SSH Config and InsteadOf
As developers, we often find ourselves juggling multiple Git accounts—perhaps a personal GitHub account for side projects and a professional GitLab account for work. Managing SSH keys for these different accounts can quickly become a headache if not handled correctly. In this post, targetting exactly that problem, I'll show you how to set up your system to seamlessly handle multiple accounts without constantly switching keys.
The Scenario
Imagine you have a personal account on GitHub and a work account on GitLab. You want to use different SSH
keys for each to keep things isolated and secure. The challenge is that by default, Git (and SSH) will use
the same default key for every connection to github.com or gitlab.com.
Step 1: Configure SSH (~/.ssh/config)
The first step is to tell SSH which key to use for which "host". We can create aliases in our
~/.ssh/config file. Each alias can point to the same actual hostname (like
gitlab.com) but use a different identity file.
# ~/.ssh/config
# Work GitLab Account
Host gitlab.com-work
HostName gitlab.com
IdentityFile ~/.ssh/id_rsa_work
# Personal GitHub Account
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_personal
# Other server configurations...
Host myserver
User ubuntu
HostName 1.2.3.4
IdentityFile ~/.ssh/id_rsa
PreferredAuthentications publickey
ForwardAgent yes
Here, we've created two aliases: gitlab.com-work and
github.com-personal. When we connect to these aliases, SSH will actually connect to
gitlab.com or github.com but use the specified IdentityFile.
Step 2: Automate with Git insteadOf
Using aliases is great, but it means you have to remember to use them every time you clone a repository or add a remote:
git clone git@gitlab.com-work:username/repo.git
This is where Git's insteadOf feature comes in. You can configure Git to automatically replace
standard URLs with your custom SSH aliases. Add the following to your ~/.gitconfig:
# ~/.gitconfig
[url "git@gitlab.com-work:your-org/"]
insteadOf = https://gitlab.com/your-org/
[url "git@github.com-personal:your-org/example-repo.git"]
insteadOf = https://github.com/your-org/example-repo
[url "git@github.com-personal:your-org/another-repo.git"]
insteadOf = https://github.com/your-org/another-repo
With this configuration, whenever you try to interact with a repository at
https://github.com/your-org/example-repo, Git will automatically use
git@github.com-personal:your-org/example-repo.git. This ensures the correct SSH key is
used without any manual intervention!
Why This Works
- Isolation: Each account uses its own dedicated SSH key.
- Security: If one key is compromised, the others remain safe.
- Convenience: You can continue using standard HTTPS URLs in your documentation or scripts, and Git will handle the translation to the correct SSH host.
- Flexibility: You can easily add more accounts or servers by adding new entries to your SSH and Git configs.
Conclusion
By combining SSH host aliases with Git's insteadOf mapping, you can create a robust and "set and
forget" environment for managing multiple Git identities. No more "Permission denied" errors or accidentally
pushing work code with your personal email!