Using ssh on OSX

This document describes how I setup ssh to be usable on OSX. The main thing I want to have a workable ssh-agent setup.

Setting environment variable

The first step is to set the SSH_AUTH_SOCK variable, so that any ssh based programs can find the ssh agent. However, to set an environment variable that is inherited by all the user processes a bit of magic is required, as things are a bit different to Linux. On startup OS X reads the file ~/.MacOSX/environment.plist. This describes which environment variables should be set. The format is Apples standard property list format which ends up with some verbose XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "">
<plist version="1.0">

So this has set things up so that every process has SSH_AUTH_SOCK set to /Users/benno/.ssh/ssh_agent. The next step starting ssh-agent when I login.

Running things on startup

Before we can get to running ssh-agent we need to sort out how to run things on startup in general. What we want to have is a login shell script that is executed on startup.

Mac OSX supports running applications when a user logs in. This is controlled through: System Preferences -> Accounts -> Login Items. This UI lets you add arbitrary programs to run on login, unfortunately it seems that a simple shell script just doesn't work, and instead we need to have a GUI application. To get around this we call on AppleScript.

Open the AppleScript editor from Application -> AppleScript -> Script Editor. We can now create a simple AppleScript application. The application is really simple and just consists of:

do shell script "/Users/benno/local/bin/login"

All this application does is run the shell script /Users/benno/local/bin/login. You should obviously change this to reflect your setup.

You should then save it is When you save it be sure to change the format to Application. Make sure you save it somewhere where can you easily find it again. I put all my user application into ~/local/bin

Now that you have a GUI application, you can add this to your Login Items as described above.

login shell script

We now have a setup so that a login shell script is run whenever we login. Now the trick is to get it to run ssh-agent for us.

My login scripts looks like this:


killall ssh-agent > /dev/null;
ssh-agent -a $SSH_AUTH_SOCK > /dev/null

Firstly we use killall to ensure that we don't have any extra copies of ssh-agent around. Then we remove the socket file, in case it is stale. Note that we use the SSH_AUTH_SOCK environment variable that was set in environment.plist. Finally we run ssh-agent with the -a option to get it to use a specific authentication socket, rather than creating a random one.

Scripting ssh-add

So far, so good, however the one remaining piece is to get it such that on login we run ssh-add so that we can add our key to the ssh-agent keychain. This is slightly tricky, because usually ssh-add expects to get input from stdin, which unfortunately doesn't exist.

ssh-add has a way of calling an external program to get the passphrase string, but Apple doesn't provide an Aqua based program to do this. Luckily there is a program SSHPassKey which provides an Aqua based program key program.


killall ssh-agent > /dev/null;
ssh-agent -a $SSH_AUTH_SOCK > /dev/null

export SSH_ASKPASS=/Users/benno/local/bin/
export DISPLAY="" ; 
ssh-add < /dev/null

So we set SSH_ASKPASS to the SSHPassKey program, so that ssh-add will call it instead of trying on the console. Unfortunately we need to do a bunch of other seed to actually make ssh-add do what we want. The first it setting DISPLAY to trick it into thinking it has X running, and then we need to redirect input from /dev/null to fool it into thinking it doesn't have a terminal.


And after all that I now have a setup so that when I login I can type in my passphrase and have ssh just work.

Of course the above steps might not work for you for any number of reasons, in which case you can try e-mailing me.