Myth: SSH Agent Forwarding Is a Safe Bastion Pattern
Engineering teams frequently use jump hosts, or bastions, to segment production environments from direct internet exposure. A common practice among system administrators is enabling SSH agent forwarding to hop through these bastions without manually copying private keys onto intermediate servers.
Myth
The myth states that SSH agent forwarding (invoked via ssh -A or ForwardAgent yes) is an encrypted, zero-trust mechanism that protects private keys from exposure on intermediate jump hosts. Because your private key never physically leaves the local memory of your client machine, the assumption goes, intermediate servers cannot abuse your credentials or impersonate you on downstream targets.
“Agent forwarding does not copy the key file, so the bastion host cannot steal your identity.”
Relying on this assumption leads developers to leave agent forwarding permanently enabled in their SSH configurations, treating bastions as transparent relays that carry zero authentication risk.
Reality
While agent forwarding does not copy your private key bytes to the remote server, it creates an exposed UNIX domain socket on the bastion filesystem, typically inside /tmp/ssh-XXXXXX/agent.<pid>. The remote SSH daemon sets the SSH_AUTH_SOCK environment variable to point to this socket.
Every time you forward your agent, you grant the remote system an open pipe directly back to your local ssh-agent process. Anyone with root access on the bastion host, or any attacker who can read files in that temporary directory, can connect to that socket and request cryptographic signatures on arbitrary challenge payloads.
The attacker does not need to extract your private key to impersonate you. As long as your SSH connection to the bastion remains active, any process on the bastion with appropriate privileges can run standard SSH client requests against your forwarded socket:
# On a compromised bastion, an attacker finds all active agent sockets:
find /tmp/ssh-* -type s -name "agent.*" 2>/dev/null
# The attacker hijacks the victim's socket to authenticate against internal databases:
SSH_AUTH_SOCK=/tmp/ssh-aB3kL9/agent.18241 ssh db-admin@10.0.4.15
If your local agent holds keys for root access across production clusters, git hosting repositories, or database instances, an attacker on the bastion inherits immediate access to all of them without triggering key extraction alerts.
If you hop through multiple intermediate hosts with ForwardAgent yes active, the vulnerability cascades. A compromise on any machine along the chain grants full signing capability over your local identities.
How to protect
The modern, secure replacement for bastion hopping is ProxyJump (the -J flag in OpenSSH), introduced in OpenSSH 7.3. ProxyJump creates an encrypted end-to-end transport tunnel between your local machine and the destination server, passing the traffic through the bastion as raw TCP data.
With ProxyJump, the intermediate bastion acts only as a layer-4 relay. It never receives an authentication socket, never sees decrypted SSH protocol exchanges, and cannot intercept signing operations. Configure your ~/.ssh/config file to enforce this pattern:
# ~/.ssh/config
# Global baseline: disable agent forwarding everywhere
Host *
ForwardAgent no
IdentitiesOnly yes
# Define the bastion host
Host bastion
HostName bastion.internal.net
User sysadmin
IdentityFile ~/.ssh/id_ed25519_bastion
# Target internal servers via ProxyJump
Host db-prod-*.internal
ProxyJump bastion
User dbadmin
IdentityFile ~/.ssh/id_ed25519_prod
To connect from the command line without modifying configuration files, use the -J flag:
ssh -J sysadmin@bastion.internal.net dbadmin@10.0.4.15
If legacy workflows strictly require ssh-agent, constrain key lifetime and enforce confirmation prompts. Adding keys with ssh-add -c forces your local system to require interactive approval before signing any request, preventing background hijacked requests from succeeding unnoticed:
# Add key with a 30-minute expiry and confirmation requirement
ssh-add -c -t 1800 ~/.ssh/id_ed25519
For high-risk environments, switch to FIDO2 hardware-backed security keys such as ed25519-sk. These keys mandate physical presence detection for every signature, blocking remote automated session hijacking entirely.