158

I understand that since Mac OS X Leopard the Keychain has supported storing SSH keys. Could someone please explain how this feature is supposed to work.

I have some RSA keys that I've generated stored in my ~/.ssh directory for accessing various servers. I don't have passphrases set on those keys. Currently in order to log in to those servers I use the following commands in the Terminal:

eval `ssh-agent`
ssh-add ~/.ssh/some_key_rsa
ssh user@server

(I've written some Bash functions to make this easier.)

Is there a better way to do this using the Keychain?

John Topley
  • 1,728
  • 3
  • 18
  • 22
  • I do these to solve it, ref: https://unix.stackexchange.com/a/560404/388990 Hope it works, thanks – Toni Firnandes Jan 05 '20 at 03:35
  • 1
    The answers here are long and confusing and need editing. There's a short and sweet 2-step answer here https://apple.stackexchange.com/questions/48502/how-can-i-permanently-add-my-ssh-private-key-to-keychain-so-it-is-automatically#250572 that is better for Bears of Very Little Brain. – Robert P. Goldman Aug 04 '20 at 22:13

10 Answers10

278

As of the Leopard release of OS X, ssh-agent is more tightly integrated with Keychain. It is possible to store the passphrases of all of your SSH keys securely in Keychain, from which ssh-agent will read them on startup. The bottom line is that it is simple to secure your keys with passphrases, but never have to type the passphrase to use them! Here is how:

Add the pass phrase to each ssh key to keychain: (option -k loads plain private keys only, skips certificates)

ssh-add -K [path/to/private SSH key]

(note that's a capital K)

Whenever you reboot your Mac, all the SSH keys in your keychain will be automatically loaded. You should be able to see the keys in the Keychain Access app, as well as from the command line via:

ssh-add -l
jackr
  • 113
  • 5
jeffmcc
  • 2,891
  • 2
  • 14
  • 4
  • `ssh-add -l` doesn't list any keys when connecting remotely (where $DISPLAY is not set). Special tricks need to be employed here to use the keychain (e.g. in https://superuser.com/questions/141044/sharing-the-same-ssh-agent-among-multiple-login-sessions) – Ether Mar 06 '15 at 21:04
  • 2
    https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/ssh-add.1.html You also need -K option to store passphrases in keychain. – Neeme Praks Apr 24 '15 at 08:27
  • You need to use a capital "K" when you do this instead of lowercase. If you load the ssh-add help info it will show that the capitol version is what stores it in the Keychain. – Patrick Jun 29 '15 at 16:36
  • 6
    If you installed another version of SSH through a package system like Homebrew, then it is necessary to use an absolute path like `/usr/bin/ssh-add`. – Ludovic Kuty Feb 14 '16 at 08:04
  • The comment of @LudovicKuty should be part of the answer... OS X uses a custom version of `ssh-add` – n1000 Oct 03 '16 at 19:46
  • I have edited the answer to add it but I forgot to log in before. Will be peer reviewed... :p – Ludovic Kuty Oct 04 '16 at 07:59
  • 2
    Interestingly in my macOS Sierra it doesn't ask for the password after a reboot but `ssh-add -l` returns "The agent has no identities." (`ps aux` includes `/usr/bin/ssh-agent -l`). – Halil Özgür Nov 23 '16 at 09:54
  • 4
    For macOS Sierra, things have changed. See https://github.com/jirsbek/SSH-keys-in-macOS-Sierra-keychain – schieferstapel Dec 29 '16 at 21:05
  • 1
    `ssh-add -K` .. yet another thing to remember or add to start scripts :-) – user260758 May 08 '17 at 08:27
  • thanks, ssh-add -K worked for me nicely on macOS Mojave =) – Pirkka Esko Nov 05 '19 at 06:49
94

As of macOS Sierra, ssh-agent no longer auto-loads previously loaded ssh keys when you log in to your account. This is intentional on Apple part, they wanted to re-align with the mainstream OpenSSH implementation. [1]


As explained here, this is the recommended method since macOS 10.12.2:

  1. Add the following lines to your ~/.ssh/config file:

    Host *
        UseKeychain yes
        AddKeysToAgent yes
    
  2. Any key you add to the ssh-agent using the ssh-add /path/to/your/private/key/id_rsa command will be automatically added to the keychain, and should be autoloaded upon reboot.


The following is deprecated (kept for reference).

To go back to the previous behavior, you'd want to run the ssh-add -A command (which auto-loads all the ssh keys that have pass-phrases on your keychain) when you log in. To do that, follow these steps:

  1. First, add all the keys you want to auto-load to the ssh-agent using the ssh-add -K /absolute/path/to/your/private/key/id_rsa command. The -K argument ensures that the key pass-phrase is added to macOS's keychain. Make sure you use the absolute path to the key. Using a relative path will make the auto-launched script not to find your key.

  2. Make sure all of your keys are shown as added when you type ssh-add -A.

  3. Create a file called com.yourusername.ssh-add.plist in ~/Library/LaunchAgents/ with the contents below. Plist files such as this one are used by launchd to run scripts when you log in. [2] [3]

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>Label</key>
      <string>com.user.loginscript</string>
    <key>ProgramArguments</key>
      <array>
        <string>ssh-add</string>
        <string>-A</string>
      </array>
    <key>RunAtLoad</key>
      <true/>
    </dict>
    </plist>
    
  4. Tell launchd to load the plist file you just created by executing: launchctl load ~/Library/LaunchAgents/com.yourusername.ssh-add.plist.

And you should be all set.

Ricardo Sanchez-Saez
  • 1,365
  • 1
  • 11
  • 18
  • Related: https://apple.stackexchange.com/questions/48502/how-can-i-permanently-add-my-ssh-private-key-to-keychain-so-it-is-automatically – slm May 15 '17 at 14:09
39

There is a simpler way than Ricardo's answer to persist your password between sessions/restarts of your Mac running 10.12 Sierra.

  1. ssh-add -K ~/.ssh/id_rsa
    Note: change the path to where your id_rsa key is located.
  2. ssh-add -A
  3. Create (or edit if it exists) the following ~/.ssh/config file:

    Host *
      UseKeychain yes
      AddKeysToAgent yes
      IdentityFile ~/.ssh/id_rsa
    

    Now the password is remembered between restarts!

Apple purposely changed the behaviour for ssh-agent in macOS 10.12 Sierra to no longer automatically load the previous SSH keys, as noted in this OpenRadar, Twitter discussion, and Technical Note from Apple. The solution above will mimic the old behaviour of El Capitan and remember your password.

ChrisJF
  • 510
  • 1
  • 5
  • 9
  • 2
    Awesome, works like a charm, imho a lot cleaner then the others and solved in the right place :) – GerardJP Jan 10 '17 at 15:08
  • 2
    Related: [*After running `ssh-add -K` to add my SSH key to the Apple Keychain, what is the name and type of entry shown in Keychain Access.app?*](https://apple.stackexchange.com/q/345037/17907) – Basil Bourque Dec 08 '18 at 02:54
  • But if you do want to auto-load your keys, you still need the LaunchAgents plist. – David Moles Nov 02 '20 at 17:52
19

For it to work, the $SSH_AUTH_SOCK environment variable should be pointed to /tmp/launch-xxxxxx/Listeners. This is supposed to be done automatically when you log in. The listener on that socket speaks the ssh-agent protocol.

Your bash scripts are starting your own ssh agent (spelled ssh-agent, not ssh_agent) and overriding the existing ssh-agent that is set up for you at login.

Also, the whole point of the keychain is to store the passwords to your ssh keys, but you say that you don't have passphrases set on those keys, so I'm not sure what you are expecting out of the keychain integration.

Finally, when you first log in, you probably won't see a ssh-agent process. That process will be started automatically by launch services the first time something tries to read that socket in /tmp.

Rudedog
  • 1,830
  • 17
  • 8
  • 1
    Thanks. So I'll still have to run `ssh-add` to add my RSA identities to the default ssh agent started at log in? – John Topley Dec 28 '09 at 18:01
  • You don't have to run ssh-add; ssh-agent will ask for the key's passphrase the first time you run ssh. – Rudedog Dec 29 '09 at 05:46
  • 3
    It's prompting me for the password every time I run ssh. The point is that I don't want to have to enter any passwords. – John Topley Dec 29 '09 at 10:40
  • 1
    What is prompting you for the password? I'm beginning to suspect that it's the remote server that's prompting you, which puts your statement that your keys don't have passphrases in better perspective. If you want to bypass the password on the remote server, you need to add your public key to `$HOME/.ssh/authorized_keys` on that server. Mac OS' ssh-agent+keychain is only used to store the passphrase for your local ssh keys; it is not meant to send remote passwords over existing ssh connections. – Rudedog Dec 29 '09 at 16:08
  • I have the public key in the authorized keys file on the remote server. I followed these instructions: http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-1 I guess I'll have to stick with running `ssh-add`. – John Topley Dec 29 '09 at 17:23
  • 1
    use `ssh -v` to diagnose what ssh is doing. also use `sshd -p 8900 -v` on the server side and `ssh -v remote:8900` to diagnose what sshd is doing. – Rudedog Dec 30 '09 at 16:54
  • "This is supposed to be done automatically when you log in." -- this doesn't actually happen for remote logins (where $DISPLAY is not set). – Ether Mar 06 '15 at 21:02
  • Note that if you use *tmux*, you're in significant danger of outdated environment variables (including `$SSH_AUTH_SOCK`). Try restarting the *tmux* server if you're having trouble. – Resigned June 2023 Feb 19 '17 at 00:25
11

Note: for macOS Sierra, please refer to the more recent answer by ChrisJF.

The [answer by Jeff McCarrell][2] is correct, except that the command to add the pass phrase contains an en dash instead of a hyphen, i.e. –K instead of -K, causing a message to the effect of –K: No such file or directory. It should read:

ssh-add -K [path/to/private SSH key]
  • 2
    This should be a comment to the answer you refer to rather than a fresh answer. We're talking about security here. One could suggest you should be carefully typing it out rather than blindly copying and pasting `ssh-add -K` – Phil_1984_ Sep 20 '16 at 21:22
  • 1
    Using a hyphen with K, I get `illegal option -- K`. Lowercase k is listed as an option. – Sam Dutton Nov 10 '16 at 14:16
  • Thanks for the feedback. I just checked on macOS Sierra: `-K`, i.e. dash-capital-K, is still valid – Simon Heimlicher Aug 13 '17 at 15:41
  • If you get `illegal option -- K`, you may be using a different `ssh-add` than the system one. Try `/usr/bin/ssh-add -K ...`. See https://help.github.com/en/github/authenticating-to-github/error-ssh-add-illegal-option----k – monozok Dec 23 '19 at 08:45
6

I had a similar problem while trying to login using a client ssh cert. In this specific case it was for accessing a git repository. This was the situation:

  • Key was saved in ~/.ssh/
  • The private key has a passphrase.
  • The passphrase is stored in the OS X login keychain. ~/Library/Keychains/login.keychain
  • The connection was as follows: my mac -> remote mac -> git/ssh server
  • Mac OS X 10.8.5

When I connected to remote mac using remote desktop, I didn't have a problem. However when connecting with SSH to the remote mac, I was asked for the ssh passphrase every time. The following steps solved it for me.

  1. security unlock-keychain The passphrase is stored in the login keychain. This unlocks it and enables ssh-agent to access it.
  2. eval `ssh-agent -s` Starts ssh-agent for shell use. It will get the passphrase from the keychain and use it to unlock the private ssh key.
  3. Establish the ssh/git connection and do my work.
  4. eval `ssh-agent -k` Kill the running ssh-agent.
  5. security lock-keychain Lock the keychain again.
orkoden
  • 829
  • 8
  • 10
  • 1
    In order for #2 to work for me within an alias, I had to use `eval \$(ssh-agent)` per [Re: remote login and keychain](https://discussions.apple.com/message/10541047#10541047). When not within an alias `eval $(ssh-agent)` works (_without the backslash $_). – Travis Jul 22 '15 at 04:59
6

I suspect you aren't using the default ssh command. Do you have ssh installed via ports? Try which ssh to see which ssh command you are using.

Usually it should display a dialog box asking for you password, if it isn't already stored in you keychain.

Olly
  • 576
  • 4
  • 8
  • 10
4

See also:

security import priv_key.p12 -k ~/Library/Keychains/login.keychain
security import pub_key.pem -k ~/Library/Keychains/login.keychain

... adding this note as more detail was requested: the "security" command is capable of importing keys (and other things) directly into Keychains. The nice thing is that unlike ssh-add, you are able to specify the keychain. This makes it possible to import directly into the system Keychain ("man security" to learn how)

xaphod
  • 171
  • 4
2

Since the release of Monterey OS X the following warning appears:

WARNING: The -K and -A flags are deprecated and have been replaced
         by the --apple-use-keychain and --apple-load-keychain
         flags, respectively.  To suppress this warning, set the
         environment variable APPLE_SSH_ADD_BEHAVIOR as described in
         the ssh-add(1) manual page.

Therefore the new command should be:

ssh-add --apple-use-keychain [path/to/private SSH key]

NOTE - This would be a comment on jeffmmc & jackr's answer but this is a new account and so I suggested it as an edit instead, but people gonna gatekeep without reading things properly, hence its a new answer.

Tom M
  • 21
  • 3
  • To add a passphrase for the the keys to the keychain (done once), use `ssh-add --apple-use-keychain`. And after that load the keys (many times for example after reboot) to your ssh agent using the keychain stored passphrase `ssh-add --apple-load-keychain` - you will be using the last one in your `~/.zshrc` or `~/.bash_profile` to load the keys. Check if your key loaded with `ssh-add -l` – BBK Nov 04 '22 at 01:36
1

The best and Apple intended solution (since macOS 10.12.2) is described here

So just do the following:

echo "UseKeychain yes" >> ~/.ssh/config

Ben
  • 111
  • 2
  • 1
    Using `>>` is at risk if you input the command multiple times. Better do a manual edition of the file, as described by [ChrisJF answer](https://superuser.com/a/1163862/214362). – Cœur Jan 30 '17 at 06:03
  • Yes you right there – Ben Feb 02 '17 at 18:37