Integration with ssh-agent

Back to Emacs

In case any Emacsen herders out there want to more tightly couple their `ssh-agent` to `emacs`, here is a nicely working solution. For questions, reach out to Gary:

1. Add this to your `~/.bash_profile` (or equivalent login shell config file):

export SSH_ASKPASS="ssh-askpass.sh"

2. Create a script called `ssh-askpass.sh` somewhere on your PATH and make it executable. It should contain this code:

#!/bin/sh

emacsclient -e "(password-read \"$1\")" | tr -d '"'

3. Add these lines to your `init.el`:

;; Launch ssh-agent and cache your passphrases for this Emacs session once Emacs finishes starting up
(add-hook 'after-init-hook (lambda () (start-process "start-ssh-agent.sh" nil "start-ssh-agent.sh")))

;; Listen for connections from emacsclient
(server-start)

4. Create a script called `start-ssh-agent.sh` somewhere on your PATH and make it executable. It should contain this code:

#!/bin/sh

# Kill any running ssh-agent processes
pkill -x ssh-agent

# Launch ssh-agent and evaluate the bash code that it returns (sets SSH_AGENT_PID and SSH_AUTH_SOCK)
eval `ssh-agent` > /dev/null

# Prompt for private key passphrase with $SSH_ASKPASS and cache it on the ssh-agent
ssh-add > /dev/null < /dev/null 2>&1

# Set the ssh-agent environment variables in Emacs' global process-environment variable
emacsclient -e "(setenv \"SSH_AGENT_PID\" \"$SSH_AGENT_PID\")" > /dev/null
emacsclient -e "(setenv \"SSH_AUTH_SOCK\" \"$SSH_AUTH_SOCK\")" > /dev/null

5. Profit!

At this point, the `ssh-agent` will be reinitialized each time you start Emacs. (You only do this once each day and just keep it running, right?) You will be prompted in the minibuffer for your SSH passphrases, and afterwards the relevant environment variables for communicating with `ssh-agent` will be stored in Emacs and inherited by any subprocesses that run under it. As long as you remember to run your shells from within Emacs (eshell, shell, term, ansi-term, vterm, ...), you should be able to use passwordless `ssh` everywhere. This will also automatically integrate with `magit`, so you don't have to ever type your passphrase again (at least until you restart Emacs, you silly person...).

Have fun, and happy hacking!