Solving ‘UseKeychain’ Not Working for Password Protected SSH Key Logins on macOS

My Problem

Using macOS 10.15, attempting to automatically load a password protected SSH key into ssh-agent by using the SSH configuration option UseKeychain was not working. I had the SSH key’s password stored in the macOS Keychain, and if I manually ran ssh-add -K /path/to/private/key it would load the key without asking me to input a password, proving that they key’s password did exist in the keychain. However, when attempting to SSH to a host that required that private key, I was still being asked for the password to the private key. This is in direct opposition to the intended behavior of using UseKeychain in one’s SSH config file.

I did not want to put ssh-add -A or some variant of ssh-add in my .bashrc file, even though that would have “solved” the problem. The version of OpenSSH that macOS uses has a configuration option provided for just such a desire, and that option is UseKeychain.

My Solution

Of course, first make sure that your SSH config file includes the following:

  UseKeychain yes
  AddKeysToAgent yes

Then, when adding the key to Keychain with ssh-add -K, use the full filesystem path to the key file, not a relative path.

For example, do not use ssh-add -K ~/.ssh/private.key, rather you should use ssh-add -K /Users/username/.ssh/private.key. You may also want to remove all relative pathed entries to the same SSH key from Keychain:

The Long Story

Let’s sort out some terms and get a few things straight. If you’re going to use SSH with public / private keypairs, you have the option of password protecting the private key in the pair. This means that you cannot decrypt the private key to then authenticate your identity to other systems without being in possession of the password. Without a password on the private key, mere possession of the file is good enough to prove your identity, which isn’t really comfortably secure. Any person or software that has access to your filesystem could theoretically snatch that file and masquerade as you. A password protected private key is a type of two-factor authentication. You must have possession of the file and knowledge of the password.

This is great, except if you perform tasks that require the repetitive use of the private key. Such as shelling into a remote system (Ansible, anyone?) or using git. Just an hour or two of using git pull, git push, or git fetch will wear out your keyboard and have you reconsidering your career.

This is where ssh-agent comes in, which keeps track of your private SSH key identities and their passwords. You’d then use ssh-add to stick the identities into ssh-agent. A fuller discussion of these tools is beyond the scope of this post, but suffice it to say that in theory this should reduce your need for typing SSH key passwords to an absolute minimum per reboot.

Apple’s Keychain can store SSH key passwords securely, and Apple’s version of OpenSSH includes an option that you can include in your config file named UseKeychain. This will further reduce your need for typing passwords, even across reboots. It’s possible to virtually never need to type your SSH key’s password again. Except when it doesn’t work.

Some people, myself included, have had an issue where no amount of UseKeychain under any Host * or Host hostname heading in one’s SSH config file would seem to work. After a reboot, ssh-add -l shows now known identities, which is expected. However, ssh user@host should trigger UseKeychain to find the proper key file’s password in keychain and simply allow one to log in to the remote system without providing the local private key’s password. After the first access to a host that needs your private key identity, ssh-add -l should show that the identity is now loaded even though you didn’t type the password.

Opening up the “Keychain Access” application on macOS and then searching for any login with the word ssh in it may reveal that the SSH key identities that are known are all referred to with relative paths. It’s common to see ~/.ssh/private.key or even ../.ssh/private.key depending on where you were in your filesystem when you realized you needed to add the key to Keychain. For some people, this appears to work. Not for me (and others) however.

You may want to try first adding your key with ssh-add -K using the full filesystem path to the key. Then you may want to remove any other references to the key file in Keychain Access that use relative paths.