GUIDE · HOW-TO 7 min ·

1Password SSH agent for coding agentsKeep your private key off disk. Let agents push.

Your coding agent needs to push code. Your private key should not sit on disk where the agent can read it. 1Password's SSH agent gives the agent working SSH auth without exposing the key material to its process tree.

TL;DR· the answer, in twenty seconds

What: AI coding agents inherit your shell environment, which usually includes a readable private key at ~/.ssh/id_ed25519. Any process the agent spawns can read that file.

Fix: Route SSH through 1Password's SSH agent. Enable it in Settings → Developer, point ~/.ssh/config at the socket (IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"), store your key in 1Password, add the public key to GitHub, test with ssh -T git@github.com.

Lesson: The agent auth problem and the secret-in-environment problem are the same problem. Keep credentials behind a gate the agent cannot bypass silently.

Most AI coding agents run as child processes of your terminal. That means they inherit your shell environment, your PATH, and your ability to read ~/.ssh/. If id_ed25519 sits at mode 0600 owned by your user, the agent can read it. So can anything else the agent spawns.

This is not a bug in Claude Code or Cursor. It is the default Unix process model. When you run claude or cursor, those processes run as you, with your file permissions. Giving the agent SSH push access today usually means giving it key-read access whether you intend that or not.

1Password's SSH agent changes that. Your private key lives in the 1Password vault. The agent exposes a Unix socket that answers SSH challenges. git push calls ssh, ssh calls the socket, the socket prompts for Touch ID or your system password, you approve, and the push goes through. The raw private key never hits disk in a form the coding agent's process tree can read.

Setup takes about ten minutes and survives across machine migrations without copying key files.

The short version

  • 1Password 8 ships a built-in SSH agent on macOS and Linux. No separate ssh-agent process.
  • The agent socket lives at a stable, documented path you put in ~/.ssh/config.
  • SSH keys live in your vault, not ~/.ssh/. You can import existing keys or generate new ones inside 1Password.
  • git push and ssh -T git@github.com both route through the socket automatically.
  • When a coding agent triggers a push, biometric pops up and you approve. The agent cannot pre-approve or cache that decision.
  • The private key bytes never appear in the agent's process environment or file system.

10-minute setup

Enable the SSH agent in 1Password

Open 1Password 8 on macOS. Go to Settings → Developer. Toggle SSH Agent on. The socket appears immediately.

The macOS socket path is:

~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock

That path is stable across 1Password updates. Do not use $SSH_AUTH_SOCK for this; the 1Password agent sets its own socket and the variable may already point at a system agent.

Point SSH at the socket

Add this to ~/.ssh/config, above any Host * blocks you already have:

Host *
  IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"

This tells every SSH connection to use the 1Password agent for key challenges, regardless of what $SSH_AUTH_SOCK holds.

Add your SSH key to 1Password

In 1Password, create a new SSH Key item. You can:

  • Generate a new Ed25519 key pair inside 1Password. The private key never touches disk.
  • Import an existing id_ed25519 by pasting or dragging the file into the item. After import, consider removing the original from ~/.ssh/.

1Password shows you the public key in OpenSSH format. Copy it.

Add the public key to GitHub

Go to GitHub → Settings → SSH and GPG keys → New SSH key. Paste the public key from 1Password. Give it a descriptive name that includes the machine name.

Test the connection

ssh -T git@github.com

1Password will prompt for Touch ID. Approve it. You should see:

Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.

If it hangs or fails with Permission denied (publickey), check that ~/.ssh/config has no earlier IdentityAgent or IdentityFile line that overrides the new block. Run ssh -vT git@github.com to see which identity the client tries first.

Test a push from your coding agent

Open a Claude Code session in a repo with a GitHub remote. Make a trivial change and run git push. The Touch ID prompt appears in the foreground on your machine. Approve it. The push succeeds.

You approved that push. The agent did not find a key file and silently use it.

What this solves and what it does not

The setup fixes three real problems. With 1Password's SSH agent, there is no raw private key on disk to read. The agent socket answers SSH challenges but does not expose key material to any process, including the coding agent. If your machine is stolen or compromised and someone clears your key from the vault, push access is revoked everywhere, not just on that disk. 1Password also logs every agent authentication: you can pull the activity log and see when the agent reached for the key, which application triggered the request, and whether you approved it.

The scope ends there. The coding agent can still read your code, run arbitrary shell commands, and access any tool you have granted it. SSH key isolation is one layer, not a sandbox. Biometric approval on a push confirms you were present. It does not confirm you reviewed what you pushed. And if you have DATABASE_URL or STRIPE_KEY exported in your shell, the agent inherits those. The SSH agent has no effect on that surface.

You are removing one specific attack path, not hardening the agent's full permission surface.

Linux gotchas

The 1Password SSH agent works on Linux but the socket path varies by installation method.

For the native .deb or .rpm package, the socket is at:

~/.1password/agent.sock

Your ~/.ssh/config block becomes:

Host *
  IdentityAgent "~/.1password/agent.sock"

For the snap package, the socket path shifts based on snap's confinement layout. 1Password's own documentation (1password.com/downloads/linux) covers the exact snap path, and it has changed between versions. If you are on snap, check the current path rather than copying a path from a forum post.

For the Flatpak package: Flatpak's filesystem sandboxing breaks the socket entirely in some configurations. 1Password's support page documents this explicitly. The native package is less friction.

The 1Password browser extension and the SSH agent on Linux both require the 1Password desktop app to be running. If you close the app, the socket goes away. A systemd user unit can keep it alive in a headless session:

systemctl --user enable 1password
systemctl --user start 1password

This keeps the agent socket available for automated or overnight agent runs without requiring the GUI to be open.

The case against this setup (and why it holds anyway)

Pushback usually goes like this: "This is more friction than a key file. My key is already 0600. If an attacker reads my private key they already own my machine."

That is partially right. If an attacker has arbitrary file read as your user, they can exfiltrate id_ed25519 to a remote machine. The 1Password agent does not prevent that either, because the attacker can call ssh-add -L or use the agent socket directly.

The threat this setup actually addresses is narrower: a misbehaving or compromised coding agent that reads your private key and exfiltrates it. Not every compromised agent leads to full machine compromise. Some agents have limited tool access. Some operate in sandboxed environments with filtered network egress. In those cases, "no raw key file on disk" is a real constraint the agent cannot trivially work around.

The biometric gate also matters as a behavioral check. When a push happens without you at the keyboard, the Touch ID prompt fails. That is a feature: unattended pushes from an agent session you left running do not silently succeed.

Whether the setup is worth ten minutes depends on how much you trust the toolchain. For most developers using Claude Code or Cursor with full shell access, the agent is already running as them on their machine. The SSH agent isolation is a small improvement. For developers running agents with restricted permissions or in more controlled environments, it is a meaningful one.

Setup checklist

## 1Password SSH agent for coding agents

- [ ] 1Password 8 installed (macOS or Linux native)
- [ ] SSH Agent enabled in Settings → Developer
- [ ] ~/.ssh/config has IdentityAgent pointing at 1Password socket
- [ ] SSH key stored in 1Password vault (generated or imported)
- [ ] Public key added to GitHub SSH keys
- [ ] ssh -T git@github.com passes with biometric prompt
- [ ] git push from coding agent session passes with biometric prompt
- [ ] Original ~/.ssh/id_ed25519 removed or moved off machine (if imported)
- [ ] On Linux: confirmed socket path matches installation method
- [ ] On Linux with snap/Flatpak: tested agent socket is reachable
- [ ] 1Password activity log checked: SSH uses appear in the log

What this means for your stack

SSH key isolation is one piece of a larger question: what can a coding agent access that you did not explicitly grant it this session? The answer is usually "quite a lot." Environment variables, credential files, cloud CLI configs, and SSH keys all sit in the same user context the agent runs in.

The SSH agent pattern narrows the key-read surface. The adjacent problem is secrets in your environment: API keys, database URLs, and provider tokens that the agent inherits because they are exported in your shell. A credential broker holds those in an encrypted local vault and injects them into specific child processes at exec time, so the coding agent context never sees the raw value and nothing persists to the state files the tool writes.

hasp is one working implementation. curl -fsSL https://gethasp.com/install.sh | sh, hasp setup, connect a project, hand the next session a reference instead of a key. Source-available (FCL-1.0), local-first, macOS and Linux, no account.

The underlying principle applies regardless of which tools you use. Credentials should live behind explicit gates, not in ambient environment state that any child process inherits by default.

Sources· cited above, in one place

NEXT STEP~90 seconds

Stop handing the agent your real keys.

hasp keeps secrets in one local encrypted vault, brokers them into the child process at exec, and never lets the agent read the value.

  • Local, encrypted vault — no account, no cloud, no telemetry by default.
  • Brokered run — agent gets a reference, the child process gets the value.
  • Pre-commit + pre-push hooks catch managed values before they ship.
  • Append-only HMAC audit log answers "did the agent touch the prod token?" in seconds.
→ okvault unlocked · binding ./api
→ okgrant once · pid 88421
→ okagent never read

macOS & Linux. Source-available (FCL-1.0, converts to Apache 2.0). No account.

Browse all clusters· eight threads, one index