How to use multiple GitHub accounts when only HTTPS is allowed

ยท

4 min read

It was relatively simple when I could use GIT+SSH...

I have separate GitHub user accounts for my personal and company use, and I could configure Git to use specific SSH keys for different URL patterns using includeIf as below.

~/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-company.com
[core]
    excludesfile = ~/.gitignore_global
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status
## my work github org path in git+ssh
## You can skip this sction to make your work account the default for all GitHub access in your work machine
[includeIf "hasconfig:remote.*.url:git@github.com:my-work-org/**"]
    path = ~/.config/gitconfig/work/.gitconfig
## my personal github org/user path in git+ssh
[includeIf "hasconfig:remote.*.url:git@github.com:my-account/**"]
    path = ~/.config/gitconfig/personal/.gitconfig

~/.config/gitconfig/work/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-company.com
[core]
  sshCommand = "ssh -i ~/.ssh/my-work-private-key"

~/.config/gitconfig/personal/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-personal.com
[core]
  sshCommand = "ssh -i ~/.ssh/my-personal-private-key"

However, the company has configured a company-wide security proxy on our computers, which blocks TCP port 22. This means I can no longer use Git with SSH and must switch to using Git with HTTPS.

You can obviously clone or set remote URL with HTTPS using a Username and Password. If you attempt to clone via HTTPS for the first time, you will be prompted to enter a username and password.

The password to enter is PAT(Personal Access Token).

You won't be asked for these credentials again when cloning another repository accessible with the same username.

This is because git uses the osxkeychain gitcredential helper by default when you're using HTTPS on MacOS

The issue is it will fail if you try to clone another repository that is accessible only by a different account

Solution

So, you should let git know which credential in Keychain needs to be used for each Git URL

# hey Git, use `my-personal-github-id` as username
# when git url is starting with https://github.com/my-account
git config --global \
  credential.https://github.com/my-account.username \
  my-personal-github-id

# hey Git, use `my-work-github-id` as username
# when git url is starting with https://github.com/my-work-org
git config --global \
  credential.https://github.com/my-work-org.username \
  my-work-github-id

As a result, the credential configuration is added in ~/.gitconfig as below, given that we use the --global option.

[user]
    name = Sunggun Yu
    email = sunggun@mycompany.com
[core]
    excludesfile = ~/.gitignore_global
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status

[credential "https://github.com/my-work-org"]
    username = my-work-github-id
[credential "https://github.com/my-account"]
    username = my-personal-github-id

As shown below, Git will utilize the associated username when the URL pattern is matched.

Now, you will see that another GitHub.com internet account has been added to Keychain

We can leverage includeIf with a URL pattern similar to what we did for git+ssh. but please be aware of the format difference between git+ssh and https

git@github.com:my-account vs.https://github.com/my-account

~/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-company.com
[core]
    excludesfile = ~/.gitignore_global
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status
## my work github org path in git+ssh
## You can skip this sction to make your work account the default for all GitHub access in your work machine
[includeIf "hasconfig:remote.*.url:https://github.com/my-work-org/**"]
    path = ~/.config/gitconfig/work/.gitconfig
## my personal github org/user path in git+ssh
[includeIf "hasconfig:remote.*.url:git@github.com:my-user/**"]
    path = ~/.config/gitconfig/personal/.gitconfig

~/.config/gitconfig/work/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-company.com
[credential "https://github.com"]
    username = my-work-github-id

~/.config/gitconfig/personal/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-personal.com
[credential "https://github.com"]
    username = my-personal-github-id

You may noticed individual config doesn't include path in credential host.

[credential "https://github.com"]

Additionally, I use git-credential-manager for more alternative authentification methods.

# Install git-credential-manager
brew install --cask git-credential-manager
# Configure global ~/.gitconfig, to use git-credential-manager
git credential-manager configure

Set a default account

You may be wondering how I can set my personal GitHub account as the default while having my work account as an option in my personal environment or on my personal devices.

It is possible but it might be tricky. the most important step is to log in to your personal account or the one you intend to set as the default account first ๐Ÿ˜›. You may also consider cleaning up existing github.com accounts in Keychain Access.

How to remove keychains

  1. open Keychain Access > select Open Keychain Access if select dialogue pops up

  2. search github.com

  3. remove github.com internet accounts

Configure gitconfig

~/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-personal.com
[core]
    excludesfile = ~/.gitignore_global
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status

## my work github org path in git+https
## You can skip this sction to make your work account the default for all GitHub access in your work machine
[includeIf "hasconfig:remote.*.url:git@github.com:my-work-org/**"]
    path = ~/.config/gitconfig/work/.gitconfig
## use git-credential-manager as credential helper
[credential]
    helper = /usr/local/share/gcm-core/git-credential-manager

~/.config/gitconfig/work/.gitconfig file:

[user]
    name = Sunggun Yu
    email = sunggun@my-company.com
[credential "https://github.com"]
    username = my-work-github-id

Login to personal first

Login to a personal account by cloning some GitHub repository

Then, login to the work account

Login to a work account by cloning the GitHub repository in the work organization

References

ย