Agent forwarding is not the agent itself. A local agent can answer authentication requests without sending the private key to the server. Forwarding additionally makes that service reachable through a socket on a remote host. Keeping key material local therefore does not mean keeping its authentication capability local.

That distinction matters when choosing a route through a bastion. If the task is simply to log into a private machine, use ProxyJump with forwarding disabled. Forwarding is useful when a program actually running on the remote machine needs your agent, such as a deliberately authorized second SSH connection.

The remote gets a capability

The forwarded socket is normally exposed through SSH_AUTH_SOCK. Processes with access to it, including a sufficiently privileged attacker on that host, can request operations from the originating agent. This is not permission for every unrelated account on the machine, and it is not an export of the private key.

An unconstrained loaded identity can nevertheless authorize unwanted logins while the forwarding channel remains available. Key lifetime, confirmation requirements, destination restrictions, and server authorization all affect what succeeds. Calling this unrestricted ownership of the key overstates the mechanism, but understating socket access is just as dangerous.

An earlier version cited an unexplained 88-byte signature as evidence. Signature length alone establishes neither the OpenSSH agent protocol nor a forwarded authentication exchange. The exercise below instead tests a narrow, observable property with the actual client: its effective forwarding configuration.

Forwarding follows effective configuration

Omitting -A does not turn forwarding off. A matching Host block, an included configuration file, or system configuration can already enable it. Conversely, -A explicitly enables forwarding even when a configuration file says ForwardAgent no. Use -a or an unambiguous -o ForwardAgent=no when disabling it for a connection.

ProxyJump supplies a TCP route to the destination; it does not reset the destination’s forwarding option. The target SSH connection and its authentication still originate locally, so ordinary jump access needs no forwarded agent. Inspect settings for the destination and jump hosts separately, because their configuration is not necessarily identical.

On a remote shell, a subsequent SSH client evaluates its own configuration. Count effective settings, not appearances of -A in command history. Also check connection multiplexing when diagnosing an existing session: printing configuration describes a proposed invocation, not every property of a previously established connection.

Limit the delegation

ssh-add -c requests confirmation through an askpass program; absence of a terminal alone does not explain whether approval works. ssh-add -t limits an identity’s lifetime. Destination constraints, available since OpenSSH 8.9, use known host keys and require cooperating client and server support along forwarded paths. Every cooperating hop must be allowed. A hostile hop can relay the socket again using other tools, while signing remains restricted to permitted destinations.

Server-side AllowAgentForwarding no disables OpenSSH’s built-in facility. It does not prevent a user with unrestricted shell access from arranging another forwarder. Keep that restriction, but do not mistake it for isolation from a hostile shell user.

When it breaks

A compromised bastion can misuse an accessible forwarded agent while the channel and relevant identity remain usable. Replacing the private-key file on disk does not unload the agent’s old identity. Respond by ending the forwarding connection and removing the affected loaded identity; revoke the corresponding server authorization if compromise warrants it. Already established remote sessions need separate handling.

Another failure is enabling forwarding in Host * and forgetting it. Prefer narrow host exceptions and an agent containing only the needed identities. Selecting IdentityFile for one login is not a filter over everything a forwarded agent exposes.

A route ladder is separate from a two-way local-agent and remote-socket capability diagram; four retained effective-configuration rows show no, yes, yes, no before destination and relay limits.
ProxyJump supplies a route; forwarding exposes signing capability. Effective configuration and cooperating destination restrictions need separate checks.

Check it quickly

This disposable configuration prints four settings for manual comparison; it opens no network connection or private key. It has no value assertions or failure/cleanup trap:

f=$(mktemp)
printf 'Host *\n    ForwardAgent no\n' > "$f"
ssh -G -F "$f" target.invalid | grep '^forwardagent '
ssh -G -F "$f" -A target.invalid | grep '^forwardagent '
printf 'Host *\n    ForwardAgent yes\n' > "$f"
ssh -G -F "$f" -J bastion.invalid target.invalid | grep '^forwardagent '
ssh -G -F "$f" -a -J bastion.invalid target.invalid | grep '^forwardagent '
rm "$f"

The retained OpenSSH 10.0p2 record reports no, yes, yes, no; this review did not rerun it. This verifies option handling, not socket permissions, signing, destination constraints, or a live multi-hop connection. For a trusted real configuration, inspect ssh -G destination and jump-host aliases; evaluating Match exec can run local commands and hostname canonicalization can invoke DNS. A forwarding value of yes should have a specific reason and a trusted recipient.

Sources

  • OpenBSD: ssh, command-line forwarding controls, jump connections, and configuration inspection, checked 2026-10-15.
  • OpenBSD: ssh_config, ForwardAgent, ProxyJump, and configuration precedence, checked 2026-10-15.
  • OpenBSD: ssh-agent, agent sockets and authentication without transferring private keys, checked 2026-10-15.
  • OpenBSD: ssh-add, askpass confirmation, lifetimes, and destination-constraint requirements, checked 2026-10-15.
  • OpenBSD: sshd_config, AllowAgentForwarding and the shell-access limitation, checked 2026-10-15.