LLM agents with read access to private ssh keys is the hottest new security mistake since the hardcoded password.
You’ve set up Claude Code (or Cursor, or Copilot) and your coding needs to connect to a remote system.

The prompt asks you: how should the agent authenticate?

What’s going on here?
ssh-keyscan is a tool that gathers the public SSH host keys found on the local system. It reduces some friction in ssh if the user has failed to put a key in an ssh connection request. If you have the public key in your $HOME directory, ssh-keyscan will try to find it.
Claude’s hoping I left a key around for the remote host. It will try to add it to the known_hosts file, which will enable it to make a direct connection to the other system if I have password auth disabled.
For extra safety- it won’t accept any scenario where the remote host’s ssh key has changed. This is “Safe” because the events where a system offers a new key should be very limited- regularly being prompted to accept a new key for a host is an indicator that someone has brought a malicious server online with the same hostname. These solutions are incomplete. In this instance, the agent’s trying to connect to a host even though it doesn’t have the key.
It’s making a valiant effort- but it will fail. I ssh-copy’d a key to this system, but I’m running sandboxed Claude and protecting the agent from access to the ssh key.
Some folks might entertain a dangerous solution: paste in your SSH key, set an environment variable, or hand over your Git credentials. It works… why worry?
You should be wondering:
Where will that secret actually go? Is it logged somewhere? Is the LLM provider training against my private key? Can the agent exfiltrate it? What happens if the agent’s process gets compromised?
The moment you hand a credential to an AI agent, you’ve lost control of it. You can’t audit where it went, you can’t revoke access without rotating secrets, and you’ve given an LLM a secret that can never leak. Chat histories get filled with desirable secrets. This should be concerning.
There is a better way to give your agents access to other systems than giving them a private key. It’s been around for decades. Networking and operations engineers use it all the time- but it seems to be less well known among devs. By the end of this post, you’ll know how to give a coding agent full SSH authentication capability while ensuring agent never knows your private key. You’ll feel greater confidence when access is revocable with a single command. Even a fully compromised agent can’t steal your private keys.
What is SSH-agent?
ssh-agent is a background process that holds your decrypted private keys in memory so you don’t have to re-enter your passphrase every time you use them.
How ssh-agent works:
- Your private key (e.g. ~/.ssh/id_ed25519) is stored encrypted on disk, protected by your passphrase
- You run ssh-add to decrypt the key and hand it to the agent
- The agent holds the decrypted key in memory
- When you ssh somewhere, the SSH client asks the agent to perform the cryptographic signing — the private key never leaves the agent process
Why ssh-agent exists:
- Convenience — type your passphrase once per session instead of every connection
- Security — the decrypted key lives only in memory, never written to disk unencrypted. Programs that need to authenticate
ask the agent rather than accessing the key file directly - Forwarding — with ssh -A, the agent can be forwarded to remote hosts so you can hop between machines without copying your private key around. It’s essentially a secure key wallet that runs in the background for the duration of your login session.
How ssh-agent keeps ssh keys private from AI
ssh-agent implements a delegation without disclosure pattern:
┌─────────────┐ ┌───────────┐ ┌──────────────┐
│ ssh-agent │◄──────-│ Coding │───────►│ Remote Host │
│ (your keys) │ signs │ Agent │ SSH │ (GitHub, │
│ │ data │ process │ conn │ server) │
└─────────────┘ └───────────┘ └──────────────┘
- You start ssh-agent and unlock your key with ssh-add
- The coding agent inherits the $SSH_AUTH_SOCK environment variable — a Unix socket path to where the ssh-agent process is listening.
- When the agent needs to authenticate, SSH asks the agent process to sign a challenge
- The agent process asks ssh-agent (via the socket) to do the signing
- ssh-agent signs the challenge and returns the signature
- The private key never crosses the socket. Only signatures go back.
When you start ssh-agent, it creates a socket file (e.g., /tmp/ssh-XXXXX/agent.12345). It then exports the $SSH_AUTH_SOCK environment variable- which points to that socket. Any process that inherits this variable can communicate with the agent. SSH clients use this socket to ask ssh-agent to sign authentication challenges. The socket is a communication channel- it is not a credential. Reading the variable only gives you a path — without the ssh-agent process behind it, the socket is useless. This gives your agent the ability to ask for the SSH-AGENT to sign it’s requests without ever having access to the account key.
You may ask: how do I keep rogue processes from requesting signatures from the SSH-AGENT? Unfortunately- If they’re running under your user account, you’re going to have challenges. Everything that runs as you has the same access rights as you. You’ll want to move those potentially rogue processes to another user account and apply some ACLs. The nice thing about ssh-agent is you can just kill it when you’re done delegating SSH authentication to agentic processes. But if you need to be cautious:
- Run the agent in a sandboxed environment (container, VM) with its own ssh-agent holding limited-scope keys
- Use deploy keys with read-only access instead of your personal key
- Use short-lived certificates (e.g., via Vault or Teleport) instead of long-lived keys
Why This Matters for AI Agents Specifically
Least privilege by design The agent can authenticate but cannot exfiltrate the secret. Even if the agent’s process is compromised, the attacker gets a socket that only works while your agent session is alive — not a portable credential.
Auditability The agent can’t copy the key and use it later or from another machine. Access is bound to the lifetime of the socket.
Revocability Kill the ssh-agent process or remove the key with ssh-remove, and the agent instantly loses access. No secret rotation needed.
No secret in the environment Compare this to the common pattern of stuffing API_KEY=sk-… into environment variables.
Those can be read by any process, printed with env, leaked in logs. The SSH_AUTH_SOCK only points to a socket. Reading the path to a socket is generally not a security sensitive action.
The Capabilty-based security model
This is an instance of a capability-based security model. Instead of sharing a secret (something you know), you share a capability (something you can do through a controlled channel). The coding agent gets the capability to authenticate as you, scoped to:
- Time — only while the agent process runs
- Mechanism — only through the SSH protocol
- Operation — only signing challenges, not extracting keys
This is the same idea behind hardware security modules (HSMs), smart cards, and FIDO keys — the secret never leaves a trusted boundary, and all consumers interact through a signing oracle.
Practical Example
Start the session
eval "$(ssh-agent -s)"
Add a public key that can be exposed to the agent
ssh-add ~/.ssh/id_ed25519
You'll be prompted to enter your passphrase for the key- and now the ssh-agent will have the ability to sign requests without exposing the private key.
You can now launch your coding agent — it inherits SSH_AUTH_SOCK. Your coding agent can now git pull, ssh deploy, etc. When you're done, kill the agent:
ssh-agent -k # all delegated access revoked instantly

You can see that killing the agent kills the socket. A coding agent can be invoked and have full SSH access without reading a secret.
Agent frameworks should be built using capability delegation. Don’t give ai agents read access to credentials. ssh-agent is a tool you can use to provision access privileges without disclosing secrets. It’s a key tool for granting AI systems access to infrastructure.
Do you need help building secure agentic products and workflows?
Post script:
After a posting on LinkedIn, Luke Hinds observed similar ideas behind a recent pull request by Francois Proulux which added UNIX Domain sockets that supports using Secure Enclave backed ssh-agents in Nono.sh. Worth a look!











