This document describes how to configure ssh-agent as a user-level background service using systemctl --user. This modern setup ensures a single, persistent SSH agent runs per user session and manages keys seamlessly across all terminal instances.
Create the required directories and the systemd unit configuration file.
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/ssh-agent.servicePaste the following configuration into the file:
[Unit]
Description=SSH key agent
Documentation=man:ssh-agent(1)
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
# Defines the graphical prompt program if keys require a passphrase
Environment=SSH_ASKPASS=/usr/bin/ssh-askpass
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
# Optional: Automatically loads default keys into the agent on startup
ExecStartPost=/usr/bin/ssh-add
[Install]
WantedBy=default.targetNote:
%tis a systemd specifier that automatically expands to your user's runtime directory (typically/run/user/UID).
Reload the systemd user manager instance configuration, enable the service to start automatically at login, and trigger it immediately.
systemctl --user daemon-reload
systemctl --user enable --now ssh-agent.serviceVerify that the service is active and running correctly:
systemctl --user status ssh-agent.serviceFor SSH clients and terminal tools to communicate with the background agent, the SSH_AUTH_SOCK environment variable must be exported within your shell configuration profile.
Open your shell profile (~/.bashrc, ~/.zshrc, etc.):
nano ~/.bashrcAppend the following line to the absolute bottom of the file:
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/ssh-agent.socket"Apply the changes to your active terminal session:
source ~/.bashrcTo prevent manual ssh-add execution across sessions, choose one or both of the automation strategies below:
Instruct your SSH client to automatically pass unlocked keys into the active systemd agent upon your first connection to any host.
Open or create your local SSH configuration file:
nano ~/.ssh/configAdd the following lines to the top of the file:
Host *
AddKeysToAgent yes
If you included ExecStartPost=/usr/bin/ssh-add in your service file, ensure a graphical passphrase prompt tool is installed on your system to handle password-protected keys at login:
- GNOME / Ubuntu:
sudo apt install gnome-ssh-askpass - KDE Plasma:
sudo apt install ksshaskpass - Generic / Lightweight:
sudo apt install ssh-askpass
Ensure the path assigned to
Environment=SSH_ASKPASS=inside yourssh-agent.servicecorrectly references the chosen binary.
Validate that your terminal can successfully communicate with the active systemd agent wrapper:
ssh-add -l- Success State 1: Returns
The agent has no identities.(Agent is functioning perfectly, keys will populate upon your first SSH connection). - Success State 2: Lists your cryptographic key hashes (Agent has successfully loaded keys proactively via
ssh-add).
By default, once a key is unlocked and added to the agent, it remains in system memory indefinitely until the agent service stops. To reduce the risk of memory-scraping attacks or unauthorized access if your machine is left unattended, you can enforce an automatic expiration timeout.
You can pass the -t flag to the ssh-agent binary inside your service file to specify a maximum lifetime for loaded identities.
- Open the service file:
systemctl --user edit --full ssh-agent.service
- Modify the
ExecStartline to include the-tparameter followed by a time value (e.g.,2hfor 2 hours,30mfor 30 minutes, or1dfor 1 day):ExecStart=/usr/bin/ssh-agent -D -a \$SSH_AUTH_SOCK -t 2h - Restart the service to apply the policy change:
systemctl --user daemon-reload systemctl --user restart ssh-agent.service
If you do not want a global rule, you can specify individual lifetimes when manually adding keys to the agent:
ssh-add -t 1h ~/.ssh/id_ed25519This means your shell configuration cannot find the socket.
- Run
echo $SSH_AUTH_SOCKand confirm it matches the path in yourssh-agent.servicefile. - Confirm the systemd service is active:
systemctl --user status ssh-agent.service.
If you use a custom or minimal window manager (like i3, Sway, or bspwm), systemd may launch before the X11 or Wayland display server is completely initialized.
- Fix: Remove
ExecStartPost=/usr/bin/ssh-addfrom the systemd service file. Instead, handle key unlocking by relying entirely on the Option A: On-Demand Loading (AddKeysToAgent yes) method inside your~/.ssh/config. This triggers the prompt directly in your window environment only when you actively try to connect to a server.