I have 2 Github accounts: a personal one, and a professional one. If you have more than one account on Github, you've probably experienced this before:
ERROR: Permission to user2/repo.git denied to user1. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
To better understand what's going on, let's assume we have 2 users:
user1is the main profile, associated with
user2is a secondary profile, associated with
First, let's get some debugging info. In
Host github.com LogLevel DEBUG
Then try again a
git push in a repository owned by
debug1: Connecting to github.com [126.96.36.199] port 22. debug1: Connection established. [...] debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: ~/.ssh/id_rsa [...] debug1: Authentication succeeded (publickey).
The key used for authentication is
id_rsa attached to
user1. This is the problem. SSH tries keys in a certain order, and
id_rsa occurs first. The authentication succeeds at the SSH level (there IS a user attached to this key), but fails at the git level because
user1 is not a member of the repository we are trying to push to, owned by
Now that we understand what the problem is, let's try to fix it.
Since SSH allows for custom configuration per host, the first idea that comes to mind is to create a special host with a preferred key. In
~/.ssh/config, let's add a section for
Host github-user2 User git Hostname github.com IdentityFile ~/.ssh/id_github_rsa
We will also need to update our github repository. We need to change the current
origin from its default
cd ~/projects/user2/project git remote set-url origin github-user2:user2/project.git
Great! Let's try to push again:
ERROR: Permission to user2/project.git denied to user1. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
Mmmm.. Looks like that didn't do it. Let's increase our log level to the maximum:
Host github-user2 LogLevel DEBUG3 User git Hostname github.com IdentityFile ~/.ssh/id_github_rsa
And push again:
debug2: ssh_connect: needpriv 0 debug1: Connecting to github.com [188.8.131.52] port 22. debug1: Connection established. [...] debug2: key: ~/.ssh/id_rsa (0x700100200300), debug2: key: ~/.ssh/id_github_rsa (0x700200300400), explicit [...] debug1: Next authentication method: publickey debug1: Offering RSA public key: ~/.ssh/id_rsa [...] debug1: Authentication succeeded (publickey).
And so here is where weirdness happens:
id_github_rsa key seems to be recognized from our git config (marked as
explicit), but somehow
id_rsa is still used first. Why?
It took me a minute to figure this one out. I spent some time searching and eventually found
this blog post by Drew Crawford. The problem comes from the way
IdentityFile works. From the man:
Specifies a file from which the user's DSA, ECDSA or RSA authentication identity is read. The default is
~/.ssh/identityfor protocol version 1, and
~/.ssh/id_rsafor protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication. [...]
So despite specifying a preferred key for authentication, SSH will
first try keys already loaded in the agent. Since
id_rsa is our main key and we use it everywhere, chances are it's loaded in the agent first, therefore overriding our configuration.
With this new information in hand, let's update our SSH config.
So we need to tell SSH to ignore any keys already loaded in the agent, and just use the one we specify. Thankfully, there is an option for that,
Specifies that ssh(1) should only use the authentication identity files configured in the ssh_config files, even if ssh-agent(1) or a PKCS11Provider offers more identities. The argument to this keyword must be
no. This option is intended for situations where ssh-agent offers many different identities. The default is
Let's update our
Host github-user2 User git Hostname github.com IdentitiesOnly yes IdentityFile ~/.ssh/id_github_rsa
And try one last push:
$ cd ~/projects/user2/project $ git push Everything up-to-date
So to successfully authenticate on Github with a secondary user, you need to:
originURL of every repo to use the SSH config:
Not that complicated, but not easy to figure out either. It certainly took me a minute, especially since my keys were not always loaded in the same order in the SSH agent, which confused things a bit. So I hope this will avoid you some headaches :)
That's it for today, cheers!