You need to git pull on a server, or hop from a bastion to a box behind it, and your key only lives on your laptop. The advice you'll find is ssh -A — agent forwarding. It works, it feels clever, and it quietly hands every server you land on the ability to use your key as you. There's a better default that costs you nothing: ProxyJump.
Here's why forwarding is riskier than it looks, and the one-line replacement.
What agent forwarding actually does
Your SSH agent holds your private key and answers "sign this" challenges so the key never leaves your machine. Agent forwarding (-A) exposes that agent's socket on the remote server so the server can ask your agent to sign things — e.g. to authenticate you onward to a third box.
The catch: while you're connected, anyone with root on that server can use your agent too. They can't copy your key, but they don't need to — they can ask your agent to sign logins to every machine your key opens, as you, for as long as your session is up. On a shared or less-trusted box, that's your entire key's reach handed to whoever controls it.
# Don't reach for this by reflex:
ssh -A bastion
The better default: ProxyJump
Almost every reason people use -A is really "I need to reach box B through box A." ProxyJump does exactly that — but the connection to B is tunneled through A and authenticated from your laptop, so A never sees or touches your agent.
ssh -J bastion db-internal
Or make it permanent in ~/.ssh/config:
Host db-internal
HostName 10.0.0.5
ProxyJump bastion
Now ssh db-internal transparently hops through the bastion. Your key stays on your device, the bastion is just a pipe, and a compromised bastion can't impersonate you onward. Same convenience, none of the exposure.
"But I need git on the server"
The other big use of -A is running git pull (over SSH) on a remote host. Two safer options:
- Deploy keys: a per-repo, read-only key that lives on the server. Scoped to one repo, revocable, and it can't be used to log in anywhere else.
- Clone over HTTPS with a scoped token instead of SSH.
Both keep your personal key off the server entirely.
When forwarding is defensible
Forwarding isn't evil — it's just over-recommended. It's reasonable when you fully trust and control the intermediate host (your own hardened bastion, no other users) and only for the moment you need it. If you must, scope it hard:
- Use
ssh-add -cso the agent asks for confirmation on every use — you'll see it if a server tries to sign something behind your back. - Use
ssh-add -t 300to auto-expire keys from the agent. - Never forward to a shared, managed, or third-party server.
But "trusted, controlled, momentary" describes very few of the servers people forward to.
Doing this from a phone
On mobile the stakes are higher, not lower: the key should sit in the device's secure enclave, and you don't want a tapped-out -A reflex exposing it through some box you SSH'd into from a coffee shop. A good mobile client makes the safe path the easy one — saved ProxyJump hops per host, key in the enclave, biometric confirmation on use. That's the model I build into TermAI: the jump is a saved property of the host, so the safe hop is one tap and the footgun is never the default.
TL;DR
ssh -A forwards your agent, and any root on the remote can use your key as you while you're connected. You almost never need it — ssh -J bastion target (ProxyJump) reaches the same box while keeping your key on your laptop. For git on a server, use a scoped deploy key, not your personal key. Only forward to hosts you fully control, and if you do, add ssh-add -c and a timeout. On a phone, keep the key in the secure enclave and let saved jumps do the hopping.
Do you still use -A anywhere — and is the box on the other end really one you'd trust with your whole keyring?
Top comments (0)