I am having trouble getting git ssh authentication to work with multiple users. Initially, it would always try to authenticate with my home-key
~/.ssh/home-key
,
untill I found this answer
I ran that command and success. It worked, however now I have the opposite issue, and it always tries to autenticate with
~/.ssh/work-01
Despite having that and
~/.ssh/home-01
I know the git config file is correct because in my work repo, when I run
gitconfig user.email
I get
rob@Robs-MBP test % git config user.email
[email protected]
and likewise when in my home-repo
I get
rob@Robs-MacBook-Pro ~ % git config user.email
[email protected]
As far as I am aware, my ~/.ssh/config file is correct
#Default GitHub
Host github.com-home
HostName github.com
User git
IdentityFile /Users/rob/.ssh/home-01
IdentitiesOnly yes
#wearenv-git
Host github.com-work
HostName github.com
User git
IdentityFile /Users/rob/.ssh/work-01
IdentitiesOnly yes
and my global git config file is this
[user]
name = home-username
email = [email protected]
[includeIf "gitdir:~/work-repos"]
path = /work-repos/.gitconfig
[init]
defaultBranch = main
[color]
ui = auto
[core]
editor = code --wait
the includeIf
points to this
[user]
name = work-username
email = [email protected]
[init]
defaultBranch = main
[color]
ui = auto
[core]
editor = code --wait
and even setting a local config file
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = [email protected]:wearenv-digital/test.git
fetch = refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
[user]
name = work-username
email = [email protected]
I have checked, double checked and triple checked I have the correct key files uploaded to git.
Git can authenticate using work.key, as shown in this:
rob@Robs-MacBook-Pro ~ % ssh -i~/.ssh/work-01 [email protected]
PTY allocation request failed on channel 0
Hi work-username! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
rob@Robs-MacBook-Pro ~ %
It seems that when I only have work01
in ssh-agent
, it always tries to authenticate with [email protected]
Vice versa with home-01
Then when both keys are in the ssh-agent
, it always tries to use the first one added.
EDIT I can provide the verbose output of
ssh -i ~/.ssh/work-01 [email protected]
eg
ssh -i ~/.ssh/work-01 -v [email protected]
However StackOverflow detected it as spam in the original question :(
CodePudding user response:
This part:
#Default GitHub Host github.com-home HostName github.com User git IdentityFile /Users/rob/.ssh/home-01 IdentitiesOnly yes #wearenv-git Host github.com-work HostName github.com User git IdentityFile /Users/rob/.ssh/work-01 IdentitiesOnly yes
is correct, assuming the identities are in the named files, i.e., .ssh/home-01
and .ssh/work-01
in your home directory which is /Users/rob
. You can make this simpler by writing:
IdentityFile ~/.ssh/home-01
for instance as ~
means "my home directory" and hence this is automatically the right ~/.ssh/
directory and all you have to get right is the file name.
But this part is wrong:
ssh -i~/.ssh/work-01 [email protected]
Well, wrong is too strong: it works fine, it's just overkill. What you want is much simpler:
ssh github.com-home
to "log in" to [email protected]
using your home identity, and
ssh github.com-work
to "log in" to [email protected]
using your work identity. That is, instead of github.com
we use the faked up "host name". I would spell this gh-work
and gh-home
for short myself:
Host gh-work
User git
[etc] so that the "host name" is the unqualified string gh-work
or gh-home
, which is shorter and easier to type.
On your Mac, you may first need to run:
ssh-add ~/.ssh/work-01
and:
ssh-add ~/.ssh/home-01
(though just once after you've rebooted).1 Use ssh-add -l
to list the IDs that your agent knows about.
1This makes use of the fact that macOS starts the ssh agent for you when you log in, providing the right environment variables to each shell opened in each terminal window. This way every terminal window opened from the time you log in shares a single agent process. There's no need to start one. Linux systems typically require you to start one as you log in, which in turn requires some fancy footwork in a .bashrc
or .profile
or other startup file. The macOS environment makes this much easier.
Making Git uses the right URL
Once the above works—you can easily test it with ssh -Tv github.com-home
and so on, as you've written things—you simply need to convince Git to clone from, and push to, repositories stored on ssh://github.com-home/personal/repo
and ssh://github.com-work/work/repo
for instance.
This is where this kind of trick comes in:
[includeIf "gitdir:~/work-repos"] path = ~/work-repos/.gitconfig
(Note that I have added a ~
character that I think you dropped).
What we can do with includeIf
is:
- set
user.name
anduser.email
for work vs personal repos - make Git use an
insteadOf
rule forssh://github.com/
URLs
and (this is the reason for the includeIf
part) make the actual substitution conditional on whether this is a "work" or "home" repository based on where it lives in our home directories.
If you put your work repositories in ~/work-repos/*
(as indicated here) and your personal ones elsewhere (perhaps ~/home-repos/? use whatever you like; as you've set this up only the
~/work-repos/ones get the work treatment), *and* add these lines to
~/work-repos/.gitconfig`:
[url "ssh://github.com-work/"]
insteadOf = ssh://github.com/
Now if you run:
git clone ssh://github.com/company/repo.git
Git will take that and change it to read:
git clone ssh://github.com-work/company/repo.git
This in turn will cause Git to run:
ssh github.com-work git-upload-...
That is, Git will ask ssh to connect to a host named github.com-work
and run the smart protocol to access the company repository in company/repo.git
.
We already know (and have tested) that ssh github.com-work
actually connects to github.com
, not github.com-work
, and logs in as the work user using the work-user public-key so that your ssh command is correctly identified as "you-at-$company". This user therefore has access to the company repo and can clone it.
If you don't mind typing in the "wrong" URL (including the home/work distinction) in the first place, you don't need the insteadOf
trick. The fact that you're using a fake host name will trigger ssh into using the desired identity on the real (github.com
) host. But adding the insteadOf
trick makes this even more convenient.
Since many people may use [email protected]:user/repo.git
instead of ssh://github.com/user/repo.git
, or add git@
in front of github.com
to get ssh://[email protected]/user/repo.git
, you may want multiple insteadOf
rules here, e.g.:
[url "ssh://github.com-work/"]
insteadOf = ssh://github.com/
insteadOf = ssh://[email protected]/
insteadOf = [email protected]:
There are many ways to work this, of course. Pick one that suits you best. Start by getting ssh
to work the way you want, without adding Git into the mix at all. Then add Git, knowing that ssh is working the way you want.