When a coding agent needs to reach a server, the easy options are both bad. You can leave a key where the agent can read it, or you can tell it to use your normal ssh setup and hope it only does what you meant.
I build Styx, a free and open-source desktop app that runs coding agents and makes them ask before they touch production. This is how it handles SSH, what the agent actually gets, and where the protection ends.
A target, not a key
An SSH target in Styx is a host, a user, a port (22 by default), an optional jump host (user@bastion:22, comma-separated for several) and an environment: prod, staging or preview. Agents don't get a special tool. They run plain ssh <host>, scp, sftp or rsync, and Styx applies the target's user, port and jump host for them. If the agent gives itself a user or a port, its choice wins.
That is the 0.4.19 change: connecting SSH servers with their saved user and port, by key, password or your own setup.
Three ways to sign in
Key file. Styx stores the key's path and passphrase in the OS keychain. It does not store the key. Each time a grant is issued it reads the key from disk. The agent never gets the key file: it gets a forwarded SSH agent socket that works for the lifetime of the grant.
Password. The password lives in the keychain. When you grant access, Styx signs in to the server itself and the agent uses that connection, so it never sees the password. This isn't available on Windows, whose ssh can't share a signed-in connection. There you use a key file or your own setup.
My SSH setup. Nothing is stored. ssh uses your own agent and ~/.ssh/config, so 1Password, hardware keys, certificates and keys you already use all keep working. Since Styx stores nothing in this mode, what your own agent and config can reach is up to them.
Test connection signs in the way an agent will
The form has a Test connection button that signs in exactly the way an agent will. If the server only accepts passwords and you chose a key, it says so, and says how to add your key to the server. I'd rather find that out on the form than in the middle of an agent's task.
Asking, and who decides
A connected target doesn't mean the agent can use it. It has to ask, say why, and you choose what it gets: once, for an hour or for the session. For SSH on a prod target the grant hands over your whole credential whatever scope was asked, so Styx turns any auto-approval into an ask with Touch ID, Windows Hello or your system password, reads included. Every request, grant, use and revoke goes into an append-only audit log.
Where it stops
Styx is a guardrail, not a sandbox. Agents run as you, on your machine. The ssh command the agent runs by name hits a shim that asks first, but an agent that calls the real binary by its full path goes around it. Claude Code and Codex get a warning in the chat when Styx sees it, not a block. What Styx guarantees is that it never hands an agent your key and that every grant it gives is scoped, timed and written down.
The code is at https://github.com/NicholasFlemmer/styx-app and the page on connecting targets is https://heystyx.com/docs/access/connect-a-target.
How do you let an agent reach a server today: a separate key, your own agent, or something else?
Top comments (0)