Multiple GitHub Accounts

Multiple GitHub Accounts

....or how to sit on two chairs

What is the use case?

Recently my company moved all the repositories from a privately hosted git repository to an enterprise GitHub account. That means all the company repositories have now domain github.com, the same as all my private ones. As it soon became evident the company GitHub credentials and associated ssh key would inevitably clash with my private GitHub account on not one, but two fronts. I could not use one instance of my browser to interact with my private and my company's repositories simultaneously. This was easily solved by dedicating one of the browsers (in my case it was opera) to all company matters while I kept Firefox for all my personal related matters. However as most others I also use ssh key to access git repositories rather than credentials and here I run into few challenges.

GIT cli

To make long story short git-cli uses ssh-agent to authenticate to git provider. It looks up the cached ssh keys and tries them one by one from top to bottom.

If the key is not cached it will look into the .ssh directory. That's why it will work even if you delete the key pair from there. More on this is to be found on manual pages of ssh-add.

The first key which manages successful authentication is to be used even if it doesn't match the organization used in the GitHub url.

Here is the URL structure of repository hosted on GitHub:

git@github.com:Organisation/repository.git

If the first ssh key is the private one - none of the company accounts(unless made public) would be accessible.

If the first ssh key is the company one - everything will work apart accessing the private repos under the private account. The public repos under private account will still be accessible to clone, but most likely (depending on the repository setup) GitHub will reject any direct changes. You probably would be able to create a new branch and to open PR albeit not under you private name, but under the name you use on the company account.

Solution 1 - gitconfig

the solution is using the local .gitconfig settings. for private project dedicate a separate folder and create local config file.

if you are on a linux machine the default config might be in your home directory

~/user/home/myname/.gitconfig

and all the private "stuff" will need to have a dedicated .config .

~/my-private-projects/.gitconfig

Although this is not picked automatically by git. Git does not work the same way as e.g. pip in python where it would traverse the current and parents direcotries for config.

It has to be specified in the "main" .gitcofnig file:

[user]
    email = companyID@company.com
[core]
    editor = nvim
    sshCommand = ssh -i ~/.ssh/id_rsa_company
[includeIf "gitdir:~/private-projects/"]
    path = ~/private-projects/.gitconfig

The important bits are user.email and core.sshCommand this way we can instruct github to use specific sshKey for this entire folder and sub-folders.

If the ssh key is not specified the ssh service will match the first available ssh key working with github domain as described above.

Solution 2 - ssh config

This solution is using .ssh/config. Documentation for ssh config. If it doesn't exist (which it probably doesn't if you get this far), create it and add something along these lines

Host github-work
    Hostname github.com
    # Username for remote SSH user (For GitHub, everyone uses the name `git`)
    User git
    IdentityFile /home/user/.ssh/id_rsa_company
    IdentitiesOnly yes

Host github.com
    Hostname github.com
    User git
    IdentityFile /home/user/.ssh/id_rsa_private
    IdentitiesOnly yes

Few things here is worth to mention Remember this?

git@github.com:Organisation/repository.git

and your private git repos are most likely having very a similar form:

git@github.com:your-git-name/repository.git

The host here is github.com in both cases. The host github-work actually could be anything but you would need manually change the github.com to github-work in the .git/config file of the existing repository, or change that part when you are cloning the repository as following:

git clone git@github-work:Organisation/repository.git

I left the other one as github.com as there would be no further actions needed for all the private repositories. You could do it the other way on you work machine or you could use "alias" for both or all organizations you need to access with separate identities.