Use GPGTools for SSH-logins on Mac OS X

In this post, I show how you set up your shell environment on a Mac to allow SSH authentication with a GPG key.

This solutions works for multiple shell-instances, even if you close them occasionally or if your Mac went to sleep.

What you need:

Setup launch-agent for gpg-agent

The gpg-agent daemon will replace your ssh-agent. It will provide your authentication key to your ssh-client to allow it to authenticate against the ssh-server.

The gpg-agent needs to run in daemon-mode. To automize this process, we create a launch agent. So we start our shell, change into our launch agent directory an create a new agent with vi.

sheldon@mainframe:~$ cd ~/Library/LaunchAgents
sheldon@mainframe:~/Library/LaunchAgents$ vi org.gnupg.gpg-agent.plist 

We put this xml-snippet into the file and replace YOUR_USERNAME with our real username:

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

We save and close vi and go back to our user directory. There we create the directory bin and make it visible only to us.

sheldon@mainframe:~/Library/LaunchAgents$ cd ~
sheldon@mainframe:~$ mkdir bin
sheldon@mainframe:~$ chmod 700 bin

Startup script for gpg-agent

We change into this new directory and create a new shell-script.

sheldon@mainframe:~$ cd bin
sheldon@mainframe:~/bin$ vi 

Now we paste this snippet into the shell-script:

if test -f $HOME/.gpg-agent-info && \
  kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null; then
    GPG_AGENT_INFO=`cat $HOME/.gpg-agent-info`
    export GPG_AGENT_INFO
  eval `/usr/local/bin/gpg-agent --daemon --write-env-file`
export GPG_TTY=`tty`

This script ensures that only one single instance of the gpg-agent is running at a time. We save and close vi. Now, we make this script executable.

sheldon@mainframe:~/bin$ chmod 700
sheldon@mainframe:~/bin$ d ..

Gpg-agent configuration file

We have to tell our gpg-agent to support ssh. This can be done by a single line on the shell:

sheldon@mainframe:~$ echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

Bash profile

Finally, we have to add a couple of lines to our ~/.bash_profile. If this file does not exist, we create it.

sheldon@mainframe:~$ vi .bash_profile

We add append these line to the end of the file:

export GPG_TTY=$(tty)
if [ -f "${HOME}/.gpg-agent-info" ]; then
  . "${HOME}/.gpg-agent-info"

We save and close vi. We make the file executable, if it isn’t already.

sheldon@mainframe:~$ chmod 700 .bash_profile

That’s it. Now, we close the shell and log out of OS X. When we log back in, the gpg-agent is started in the background.


When we open a shell and type in ssh-add -l, we should see the ssh-fingerprints of our gpg-keys:

sheldon@mainframe:~$ ssh-add -l
4096 42:23:30:61:1d:6d:ac:87:9b:f5:2c:de:e5:28:52:e6 cardno:000500001D18 (RSA)
2048 d4:88:84:df:d3:28:d2:75:5e:27:ca:cc:24:12:54:02  (RSA)

We can use the output of ssh-add -L (notice the capital L!) in the file authorized_keys on the server.

sheldon@mainframe:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA...PLN5OjW7w== cardno:000500001D18
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAA...tMA+t0qDQ== 


… go to Dietrich Schmidt who created this how-to in the first place.