SSH Agent¶
Overview¶
The SSH agent holds your private keys in memory, so you don't need to enter passphrases repeatedly.
┌──────────────────────────────────────────────────────────────────────────┐
│ SSH Agent Flow │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ SSH │ │ SSH │ │ Remote │ │
│ │ Client │◀───────▶│ Agent │ │ Server │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ │ │ │ │
│ │ 1. Request sign │ │ │
│ │──────────────────────▶ │ │
│ │ │ │ │
│ │ 2. Return signature│ │ │
│ │◀────────────────────── │ │
│ │ │ │ │
│ │ 3. Send signature │ │ │
│ │─────────────────────────────────────────────▶ │
│ │ │ │ │
│ │
│ Key never leaves agent - only signatures are sent │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Starting the Agent¶
Check if Running¶
Start Manually¶
Output:
Start in Shell Profile¶
Add to ~/.bashrc or ~/.zshrc:
Systemd User Service (Recommended)¶
# ~/.config/systemd/user/ssh-agent.service
[Unit]
Description=SSH Authentication 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
Enable:
systemctl --user enable ssh-agent
systemctl --user start ssh-agent
# Add to shell profile
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
Adding Keys¶
Add Default Key¶
Add Specific Key¶
Add with Timeout¶
Key removed from agent after timeout:
Add from Config Automatically¶
Keys added automatically on first use.
Managing Keys¶
List Keys in Agent¶
Output:
List Keys with Full Public Key¶
Remove Specific Key¶
Remove All Keys¶
Lock Agent¶
Unlock Agent¶
Agent Forwarding¶
Forward your local agent to remote servers.
Enable Forwarding¶
How It Works¶
Local Machine Server A Server B
┌────────────┐ ┌────────────┐ ┌────────────┐
│ │ │ │ │ │
│ SSH Agent │◀─────────▶│ Forwarded │◀───────▶│ Uses │
│ (keys) │ forward │ Socket │ uses │ Keys │
│ │ │ │ │ │
└────────────┘ └────────────┘ └────────────┘
From Server A, you can SSH to Server B using your local keys.
Security Warning¶
Agent Forwarding Risk
Anyone with root access on the intermediate server can use your forwarded agent to authenticate as you.
Only forward to trusted servers.
Safer Alternative: ProxyJump¶
Instead of agent forwarding:
# Don't do this (agent forwarding)
ssh -A bastion
ssh internal-server
# Do this instead (ProxyJump)
ssh -J bastion internal-server
ProxyJump tunnels the connection without exposing your agent.
Keychain (Persistent Agent)¶
Keychain manages ssh-agent across sessions.
Install¶
Configure¶
Add to ~/.bashrc:
With Multiple Keys¶
Options¶
keychain --eval \
--agents ssh \
--timeout 480 \ # Minutes before key timeout
--quiet \ # Suppress output
id_ed25519
macOS Keychain Integration¶
macOS can store passphrases in system Keychain.
Add Key to Keychain¶
Load from Keychain on Login¶
GNOME Keyring (Linux Desktop)¶
GNOME Keyring often runs as SSH agent automatically.
Check¶
Disable (if using ssh-agent instead)¶
# Disable GNOME Keyring SSH component
mkdir -p ~/.config/autostart
cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/
echo "Hidden=true" >> ~/.config/autostart/gnome-keyring-ssh.desktop
Hardware Keys (YubiKey, etc.)¶
FIDO2/U2F Keys¶
# Generate key on hardware
ssh-keygen -t ed25519-sk -C "yubikey"
# The -sk suffix means "security key"
# Key requires physical touch to use
Add to Agent¶
Resident Keys¶
Store key ON the hardware device:
Load from device:
Agent Sockets¶
Default Socket¶
Custom Socket Location¶
Sharing Agent Across Sessions¶
# In ~/.bashrc
SOCK="/tmp/ssh-agent-$USER"
if [ -S "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK" != "$SOCK" ]; then
ln -sf "$SSH_AUTH_SOCK" "$SOCK"
fi
export SSH_AUTH_SOCK="$SOCK"
Debugging Agent Issues¶
Check Agent is Running¶
Check Socket Exists¶
Test Key¶
Verbose¶
Common Issues¶
| Problem | Solution |
|---|---|
| Agent not running | eval $(ssh-agent) |
| Key not added | ssh-add ~/.ssh/mykey |
| Wrong key offered | Use IdentitiesOnly yes in config |
| Passphrase asked every time | Add to agent, use keychain |
| Agent forwarding not working | Check ForwardAgent yes, server allows it |
Best Practices¶
- Use agent - Don't type passphrases repeatedly
- Set key timeouts -
-tflag for sensitive keys - Limit forwarding - Only to trusted servers
- Prefer ProxyJump - Over agent forwarding
- Use keychain - Persist across sessions
- Hardware keys - For high-security needs
- Lock agent - When stepping away