Setup ssh-agent Systemd Service for Emacs
26 Jan 2025Problem Statement
My personal desktop is not booting (the motherboard is probably dead) so I have been setting my server so I can work while sorting things out.
I got stuck in getting magit working in emacsclient: I thought I could
run ssh-add
inside of Emacs that would allow magic
to access my
git repos using ssh, but apparently, it is not the case.
After some digging, I learnt that the problem I have to solve is to
run one ssh-agent
in the background and then make the Emacs/Magit or
any programs hook onto it. Then once I run ssh-add and type the
passphrase for the first time, either inside of Emacs or in a bash
terminal, everything would work.
Implementation
Drop the following unit file below to ~/.config/systemd/user/ssh-agent.service.
[Unit]
Description=SSH key agent
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
[Install]
WantedBy=default.target
The important things are
- The environment variable
SSH_AUTH_SOCK
is specified. It can be anywhere as long as this environment variable in other programs points to the same location. ssh-agent
is invoked with the-a
option to provide an address specified in the above step.
The $t
is a specifier1 in systemd, it is equivalent to
$XDG_RUNTIME_DIR
variable in Debian. It points to the runtime
temporary directory which apparently is safer2 than the /tmp
directory. The runtime directory was cleaned up after stopping the
ssh-agent so it is non-persistent.
To start the ssh-agent service:
systemctl enable --user ssh-agent
systemctl start --user ssh-agent
After that, update the unit file of Emacs to include this line (follow up my blog post Managing Emacs Server as Systemd Service for the full setup).
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
To make it work for bash shell and all other programs calling from a bash terminal, add this line to ~/.bashrc.
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
Alternatives
There are programs developed to solve this specific problem (see Debian wiki). While using such a program seems like a simpler alternative (e.g. keychain), I prefer to use systemd as the unified approach for managing background services. I have been using it for emacsclient, and I’m adding ssh-agent to it.
What is your preference? How do you solve this problem?
Footnotes
1 All the specifiers are listed here.
2 I am not a security expert but the StackExchange comments seem to make sense.