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.