Scenario
You have two (or more) accounts at GitHub (or some other repo host), say for work and private use, and you want to work with both interchangeably. GitHub have support for multiple accounts through the account switcher, but how do you differentiate between the two accounts when authenticating the git client?
Setting the stage
I prefer using ssh rather than https with git to avoid having to deal with credential managers. I create my ssh keys manually with ssh-keygen
and add my public keys to my GitHub user settings. I work most of the time in macOS, though I sometimes use GNU/Linux or even Windows. All of which support using ssh without any need for a credential manager, great!
Creating ssh keys
The first step is to create key-pairs to use with ssh, one pair for each account on GitHub. I have a private account and an account for work.
ssh-keygen -f ~/.ssh/gh_private
ssh-keygen -f ~/.ssh/gh_work
Then the next step is to go to GitHub settings and add the public key. Remember to switch accounts before adding the second key.
Configuring git (ssh) to use the key
This is where things start to get interesting. We need ssh to understand the difference between our two accounts to know when to use which key. Thankfully GitHub has a wildcard DNS which makes this easier for us. The trick is to use an arbitrary subdomain for repositories that should use a different key, and this is achieved in two parts. The first is the ssh-config which is stored in ~/.ssh/config
and should look something like this:
Host github.com
IdentityFile ~/.ssh/gh_private
Host work.github.com
IdentityFile ~/.ssh/gh_work
As mentioned earlier i use macOS with Keychain and ssh-agent
for managing ssh authentication, so I have some more config for that. Apply as needed.
Host github.com
IdentityFile ~/.ssh/gh_private
AddKeysToAgent yes
UseKeychain yes
Host work.github.com
IdentityFile ~/.ssh/gh_work
AddKeysToAgent yes
UseKeychain yes
Cloning repositories
Now that ssh is configured to use our two different keys based on host name, we must remember to use these host names when cloning repositories (or configuring remotes). When cloning a repository from the private account, no modification is needed and we can use the regular clone command:
git clone git@github.com:me/some-repo.git
And when we're cloning a repo from our work account we need to update the path to make sure we add the subdomain we configured earlier in the ssh-config. Remember, this subdomain is arbitrary, but needs to match what you have in ~/.ssh/config
.
git clone git@work.github.com:Company/private-repo.git
That's it! With the subdomain in the host name, ssh (and thereby git) knows which ssh key file to use and will authenticate as the appropriate user.
Bonus: Separate git-config
When using git, you usually have some global git-config stored in ~/.gitconfig
where you set stuff like your name and email address. You probably want that to be different (at least the email address) for your work repositories. One way of doing that would be to set it in .git/config
for every repo, but that quickly becomes tedious and often forgotten, resulting in commits where you have your private email address - not very nice.
If you organize your repos in common folders for private and work, this can be easily solved once and for all. I have my private repos under ~/github.com/me/
and work repos under, you guessed it; ~/github.com/Company/
. With this setup, I can add this section to my ~/.gitconfig
:
[includeIf "gitdir:~/github.com/Company/"]
path = ~/github.com/Company/.gitconfig
And in ~/github.com/Company/.gitconfig
I can add whatever work-related config I need, but most importantly my email address for work:
[user]
email = myname@work.tld
Conclusion
Having multiple GitHub accounts is no problem, given that you follow these guidelines:
- Create multiple key pairs with
ssh-keygen
- Configure ssh to use different keys based on host name
- Add subdomain to host when cloning repos for work
I hope this made sense and perhaps becomes helpful if you find yourself in a similar situation.
Disclamer
I didn't cover authenticating with https in this post as I personally prefer ssh, and it might be that this issue with multiple accounts is solved in an even easier way with credential managers, but then again it's going to be different for each OS.
Top comments (0)