Help using systemd units to launch the ssh agent and add keys to the agent on KDE

1. Problem

I’ve been working on trying to get the SSH agent running and the keys added to the agent using systemd units. However, I can’t get the SSH keys added to the agent after login. Ideally, I’d also like to define all required environmental variables within the systemd units, but I can’t seem to do the for $SSH_AUTH_SOCK.

So far I have the following:

2. Environmental variables

ssh-askpass.sh

cat /etc/profile.d/ssh-askpass.sh
#!/bin/sh

export SSH_ASKPASS=/usr/bin/ksshaskpass

.zshenv

I’ve set the following variable in my ~/.zshenv file, as I couldn’t get it to work when it was set as Environment=SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"/ssh-agent.socket in the [Service] section of the ssh-agent.service systemd unit:

cat ~/.zshenv
# [... TRUNCATED ...]

### SSH Auth Sock ###
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"/ssh-agent.socket

3. Systemd units

ssh-agent.service

cat ~/.config/systemd/user/ssh-agent.service
[Unit]
Description=SSH key agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
# DISPLAY required for ssh-askpass to work
Environment=DISPLAY=:0
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

ssh-add.service

cat ~/.config/systemd/user/ssh-add.service
[Unit]
Description=Add private key identities to the SSH agent
PartOf=ssh-agent.service
After=ssh-agent.service

[Service]
Type=oneshot
ExecStart=/home/benjamin/.local/bin/systemd-ssh-add after

[Install]
WantedBy=ssh-agent.service

4. Scripts

systemd-ssh-add

My homebrewed script to add SSH keys to the agent is as follows:

cat ~/.local/bin/systemd-ssh-add
#!/bin/sh

### Find Keys ###
DIR_SSH="${HOME}"/.ssh
[[ ! -d "$DIR_SSH" ]] && exit 1
KEYS=$(
    grep -zlP \
        --exclude="authorized_keys*" \
        --exclude="config*" \
        --exclude="known_hosts*" \
        --exclude="*.pub" \
        -- \
        '-----BEGIN OPENSSH PRIVATE KEY-----(.*\n.*){1,}-----END OPENSSH PRIVATE KEY-----' \
        "$DIR_SSH"/*
)

### Add Keys to Agent ###
[[ ! -n "$KEYS" ]] && exit 1
ssh-add -q $KEYS < /dev/null

exit 0

5. Output

systemctl --user status ... output

The ssh-agent.service launches and runs without error:

systemctl --user status ssh-agent.service
● ssh-agent.service - SSH key agent
     Loaded: loaded (/home/benjamin/.config/systemd/user/ssh-agent.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-08-23 18:00:00 BST; 1min 24s ago
   Main PID: 1171 (ssh-agent)
      Tasks: 1 (limit: 4307)
     Memory: 904.0K
        CPU: 13ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/ssh-agent.service
             └─1171 /usr/bin/ssh-agent -D -a /run/user/1000/ssh-agent.socket

Aug 23 18:00:00 Scatha systemd[1164]: Started SSH key agent.
Aug 23 18:00:00 Scatha ssh-agent[1171]: SSH_AUTH_SOCK=/run/user/1000/ssh-agent.socket; export SSH_AUTH_SOCK;
Aug 23 18:00:00 Scatha ssh-agent[1171]: echo Agent pid 1171;

However, the ssh-add.service throws errors that appear to indicate that it’s running before the ssh-agent.service is ready:

systemctl --user status ssh-add.service
○ ssh-add.service - Add private key identities to the SSH agent
     Loaded: loaded (/home/benjamin/.config/systemd/user/ssh-add.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2021-08-23 18:00:00 BST; 1min 24s ago
   Main PID: 1172 (code=exited, status=0/SUCCESS)
        CPU: 42ms

Aug 23 18:00:00 Scatha systemd[1164]: Starting Add private key identities to the SSH agent...
Aug 23 18:00:00 Scatha systemd-ssh-add[1176]: Could not open a connection to your authentication agent.
Aug 23 18:00:00 Scatha systemd[1164]: Finished Add private key identities to the SSH agent.

If I run systemctl --user start ssh-add.service after login, the process runs as intended, albeit, while taking over 8s to add six keys to the agent:

systemctl --user start ssh-add.service
systemctl --user status ssh-add.service
○ ssh-add.service - Add private key identities to the SSH agent
     Loaded: loaded (/home/benjamin/.config/systemd/user/ssh-add.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2021-08-23 18:04:07 BST; 5s ago
    Process: 2329 ExecStart=/home/benjamin/.local/bin/systemd-ssh-add after (code=exited, status=0/SUCCESS)
   Main PID: 2329 (code=exited, status=0/SUCCESS)
        CPU: 8.538s

Aug 23 18:03:58 Scatha systemd[1164]: Starting Add private key identities to the SSH agent...
Aug 23 18:04:07 Scatha systemd[1164]: Finished Add private key identities to the SSH agent.
Aug 23 18:04:07 Scatha systemd[1164]: ssh-add.service: Consumed 8.538s CPU time.

6. Misc

printenv | grep -i 'ssh'
SSH_ASKPASS=/usr/bin/ksshaskpass
SSH_AUTH_SOCK=/run/user/1000/ssh-agent.socket
pgrep -a 'ssh'
835 sshd: /usr/bin/sshd -D [listener] 0 of 10-100 startups
1170 /usr/bin/ssh-agent -D -a /run/user/1000/ssh-agent.socket
pacman -Qs kwallet
local/ksshaskpass 5.22.4-1 (plasma)
    ssh-add helper that uses kwallet and kpassworddialog
local/kwallet 5.85.0-1 (kf5)
    Secure and unified container for user passwords
local/kwallet-pam 5.22.4-1 (plasma)
    KWallet PAM integration
local/kwalletmanager 21.08.0-1 (kde-applications kde-utilities)
    Wallet management tool
local/signon-kwallet-extension 21.08.0-1 (kde-applications kde-network)
    KWallet integration for signon framework