I started in a new job today, where they use bitbucket, and they have created me an account using my new work email address.
However, when I pasted my SSH key in, Bitbucket complained that the key was already in use (my personal account), so I had to set up another key.
My SSH config looked like this, but it didn't work and seemed to pick up the wrong key:
Host work
HostName bitbucket.org
User git
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_work
IdentitiesOnly yes
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
then I tried git clone work:path/to/some.git
but got "could not read from repo."
I had to edit away my normal id_rsa
before it would work, so now it looks like this:
Host *
HostName bitbucket.org
User git
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_work
IdentitiesOnly yes
What did I do wrong?
Using your initial config file (the one with Host work
and Host *
), you can do a
ssh -Tv work
You will see what key is actually used. If it is id_rsa
, that means what is specified in Host *
takes precedence over Host work
.
If you want to use your personal key for everything except work, you would need to use a pattern:
Host * !work
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
I assumed the wildcard host was a "fallback" option with the lowest precedence. I guess that's not true?
In an SSH configuration files (~/.ssh/config
), the options are applied based on the order they appear in the file, not just based on the specificity of the Host
patterns:
Host
block, SSH checks if the target host matches the pattern specified. Multiple Host
blocks can match the same target host.Host
block matches, SSH applies the options within that block. Options are cumulative, meaning they can add up, and later options can override earlier ones if they are for the same parameter.Since SSH applies configurations in the order they appear, a general Host *
block that appears after a specific Host work
block can override settings specified earlier for work
. The last matching option for a given parameter is what takes effect.
That is why I excluded work
from the Host *
pattern (Host * !work
)
Alternatively, you could place the Host *
block before the Host work
block, but it is not reliable for IdentityFile
: SSH can still accumulate multiple identity files from matching blocks unless you use IdentitiesOnly yes
.
For more information, see "What SSH identities will be offered to a remote server and when" from Chris Siebenmann.