Ssh-agent is probably normally used to handle a single identity key, but it can hold more than one if you want. One of the things that the
ssh-agent
and
ssh
manpages are a bit silent on is what happens if you have multiple SSH keys loaded into a single
ssh-agent
. Since I've been dealing with this as the result of transitioning from one set of SSH keys to another, I'm going to write down what I've learned so far.
(The simple version of why I decided to roll over my SSH keys is that I decided to transition from keys that had once been used without encryption to keys that were created encrypted.)
Before I started loading multiple keys into
ssh-agent
, what I expected to happen is that the choice of which ssh-agent key to use would be controlled by the key that
ssh
itself would normally use. If you had, for example, '
IdentityFile .../key1-rsa
', then I expected
ssh
to ask
ssh-agent
to do operations only with that key. This is not what happens. Instead what happens by default is that ssh tries all keys loaded into ssh-agent, one after another, in the order that they were loaded into ssh-agent .
You can partly override this behavior with the
IdentitiesOnly
configuration directive, which will restrict the keys that
ssh
tries to only the identities listed either as
IdentityFile
directives or supplied on the command line with
-i
. However this is an incomplete override because it doesn't prioritize the
-i
identity the way a normal (agentless)
ssh
will;
ssh
will first ask
ssh-agent
for any
IdentityFile
keys it has and only then fall back to a non-agent key given with
-i
. This implies that if you have a script and you want it to always use a particular restricted identity even if more general ones are available ( as I do in one case ) you need to clear
$SSH_AUTH_SOCK
in the script.
(This can apply any time you have a remote system that accepts multiple identities from you but applies different access permissions or access restrictions to them. Remember that
IdentityFile
directives add together and
-i
stacks with with them too, so even if you have a specific identity configured for something, a general '
Host *
' identity or the like will also be tried.)
There are a couple of interesting uses I can see for this multiple key behavior. One of them is making a transition between old and new SSH keys easier. First off, you can load both your new and your old key into
ssh-agent
; you'll then use your new key on systems that have been updated to accept only it but have a transparent fallback to systems that only have your old key. More cleverly you can use this to uncover systems that haven't been updated to your new key by loading only your new key into
ssh-agent
but leaving your old encrypted key configured as your
IdentityFile
. If you try to
ssh
to somewhere but get prompted to unlock your old key, you've found a host that either prefers your old key to your new key or doesn't have your new key at all.
Another use is encrypting secondary keys (for example your Github key) but still loading them into
ssh-agent
for passwordless use. Since
ssh
with
ssh-agent
will try multiple keys, pushing to Github and other such uses will eventually try the right keys. You can force this to happen earlier by setting
IdentitiesOnly
in
.ssh/config
for the particular hosts involved; this will definitely be necessary if you have a lot of SSH keys, because SSH servers only accept so many key attempts ( cf ).
(Some of this information comes from this stackoverflow answer .)
(Talking of the interaction of
ssh
and
ssh-agent
, it's a pity that as far as I know
ssh
can't be told 'load keys into
ssh-agent
when you unlock them'. This would make it very convenient to incrementally load keys into
ssh-agent
as you turn out to need them while not having them sitting around unlocked in a session if you didn't.)