In order to use ssh agent forwarding with emacs in daemon mode, running on a remote server, I've come-up with the following.

I have an alias for the client like so:

alias emacsclient="update_agent;/usr/local/bin/emacsclient -nw"

Which is calling the following which will update a soft-link to the current agent socket each time the emacs client is started (it is not used in any other circumstance):

alias update_agent='if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then ln -sfv "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock; fi'

Providing I don't run 2 emacs clients simultaneously, and then kill the 2nd client before the 1st, this works fine.

In order to make the daemon use the updated socket I must set SSH_AUTH_SOCK to the soft link at daemon creation time.

I came up with 2 ways of doing this.

This way works:

 alias emacs="SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock /usr/local/bin/emacs --daemon"

This way does not work:

alias emacs="/usr/local/bin/emacs --daemon --eval '(setenv \"SSH_AUTH_SOCK\" \"~/.ssh/ssh_auth_sock\")'"

Both return the same value when getenv is called on SSH_AUTH_SOCK from within an emacs client.

But any attempt to use Dired on a remote directory eg C-x d /ssh:servername: or to ssh from M-x shell returns the following using the 2nd alias:

Failing with `Permission denied (publickey).`

My question is why doesn't the 2nd alias for emacs daemon allow ssh agent to be used for authentication?

Note - the use of the soft-link is necessary to make sure that not only the emacs daemon environment is updated, but all spawned M-x shells within the daemon are also updated. Otherwise it would be a trivial case of just updatng the daemon's SSH_AUTH_SOCK environment variable each time you connect to the daemon with setenv to the value of the current terminal's socket? Although if anyone has a better/different way of using ssh agent forwarding with emacs daemon, then I'm keen to hear it too!





1 Answer 1


Both return the same value when getenv is called on SSH_AUTH_SOCK from within an emacs client.

That looks unlikely. One would return ~/.ssh/ssh_auth_sock and the other would return /path/to/HOME/.ssh/ssh_auth_sock, no?

Have you tested whether SSH_AUTH_SOCK can actually contain ~ as a substitute for your HOME directory? Usually that would be expanded by a shell.

  • 1
    Thanks, I don't know how I missed that - to clarify the following works fine alias emacs="/usr/local/bin/emacs --daemon --eval '(setenv \"SSH_AUTH_SOCK\" \"/home/username/.ssh/ssh_auth_sock \")'"
    – Phil
    Oct 7, 2018 at 21:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.