SSH keys in 1Password: eliminating the file juggling ritual
SSH keys scattered across machines create a familiar nightmare—copying files between systems, remembering which key lives where, and the inevitable moment when you need to connect from a new laptop without access to your carefully managed ~/.ssh directory. 1Password's SSH agent transforms this by keeping encrypted keys available everywhere whilst ensuring private keys never touch disk outside the vault.I've been using 1Password for over a decade. Started with passwords, naturally—the original use case. Then secure notes for things too sensitive for plain text files. API keys. Software licences. Credit cards. Over time, it became the central repository for anything that needed encryption and accessibility across devices.
SSH keys, though, remained outside that system for years. They lived in ~/.ssh like they always had—unencrypted private keys sitting on disk, protected only by filesystem permissions. When I got a new laptop, I'd copy the directory over. When I needed to connect from a different machine, I'd either copy keys via USB drive or generate new ones and update servers. The workflow was manual, tedious, and created exactly the kind of key sprawl that causes security teams to wake up screaming.
The moment I discovered 1Password supported SSH agent functionality, the old workflow became obviously obsolete.
The traditional SSH key problem
SSH keys follow a pattern established decades ago. You generate a key pair—one private, one public. The private key stays on your machine, unencrypted, in ~/.ssh/id_rsa or ~/.ssh/id_ed25519. The public key gets copied to servers you need to access. Authentication works through cryptographic signatures proving you possess the private key without ever transmitting it.
This works until you have multiple machines. Your work laptop has one set of keys. Your personal machine has another. That server you occasionally SSH into for deployments has a third. Keeping track of which key authenticates to which server becomes cognitive overhead. Rotating keys means touching every machine where they exist. Losing a laptop means immediately rotating every key that lived on it because those private keys are gone—possibly into someone else's hands.
The standard solution involves copying ~/.ssh directories between machines, often via insecure methods because "it's just this one time." Or generating unique keys per machine and adding all public keys to every server, which solves one problem whilst creating another—now you have N×M relationships to manage, where N is machines and M is servers.
1Password's approach eliminates this entire category of problems by centralizing keys in encrypted vaults whilst providing transparent access through an SSH agent.
How the 1Password SSH agent works
Traditional SSH agents load private keys into memory and handle authentication on behalf of SSH clients. OpenSSH's ssh-agent is the standard implementation. You run ssh-add to load keys, and from that point forward, any process on your system can use those keys to authenticate. The agent holds unencrypted keys in memory, responding to signature requests from SSH clients.
The 1Password SSH agent follows the same protocol but changes the security model fundamentally. Private keys never leave the encrypted vault. They don't get loaded into agent memory. They don't write to disk outside 1Password's encrypted storage. When an SSH client requests authentication, 1Password prompts for explicit approval—showing which application wants to use which specific key. Only after you approve does 1Password decrypt the key, sign the authentication challenge, and return the signature. The key itself never leaves the vault.
This consent-based model means every authentication requires your explicit approval until 1Password locks. You can authorize per application, per application per terminal session, or require approval for every single SSH operation if you want that level of control. The standard ssh-agent offers none of this—once keys are loaded, any process can use them without additional authorization.
Setting up the SSH agent
The setup process requires enabling the agent in 1Password, generating or importing keys, and configuring your SSH client to use the 1Password agent socket instead of the system default.
Start by opening 1Password and navigating to Settings → Developer. Enable "Use the SSH agent" and choose whether to display SSH key names during authorization prompts. Displaying names makes it obvious which key is being requested; hiding them shows only fingerprints, which matters if you're working in environments where shoulder-surfing is a concern.
For 1Password to stay accessible, enable "Keep 1Password in the menu bar" and "Start at login." Without these, the SSH agent won't be available until you manually launch 1Password.
On Windows, there's one additional step—disable the OpenSSH Authentication Agent service to prevent conflicts. Open Services (via services.msc), find "OpenSSH Authentication Agent", stop it, and set startup type to Disabled. Both agents attempt to use the same socket, and conflicts result in authentication failures that are annoying to debug.
Generate an SSH key directly in 1Password by creating a new item, selecting SSH Key, then choosing "Generate New Key." You'll select between Ed25519 and RSA. Ed25519 is the modern choice—smaller keys, better performance, stronger security guarantees. RSA works if you're dealing with legacy systems that don't support Ed25519.
The key generates inside the vault. 1Password creates both the private and public components, encrypts the private key, and makes the public key available for copying. You'll need that public key to add to GitHub, GitLab, servers, or wherever you're authenticating.
Configure your SSH client to use the 1Password agent by editing ~/.ssh/config:
Host *
IdentityAgent ~/.1password/agent.sock
This tells SSH to use 1Password's agent socket for all hosts. The socket path is consistent—~/.1password/agent.sock on Unix-like systems. On Windows, the path differs but follows the same principle.
Alternatively, set the SSH_AUTH_SOCK environment variable to point to the socket. This works but requires setting it in every shell session, making the config file approach cleaner.
Test the setup by running an SSH command—perhaps ssh -T git@github.com to test GitHub authentication. 1Password prompts for approval, showing the application (your terminal), the key being requested, and what's being signed. Approve using Touch ID, Windows Hello, or your account password. Authentication succeeds, and subsequent requests from the same application proceed without additional prompts until 1Password locks.
Managing multiple keys
By default, the SSH agent makes keys from your Personal, Private, and Employee vaults available for authentication. Keys in shared vaults or custom vaults require explicit configuration through an agent config file.
Create ~/.config/1Password/ssh/agent.toml and specify which vaults to include:
[[ssh-keys]]
vault = "Development"
[[ssh-keys]]
vault = "Client Projects"
This extends the agent's scope beyond default vaults, making keys in those vaults available for authentication.
The bigger challenge comes from OpenSSH's MaxAuthTries setting, which defaults to six. If you have more than six keys available to the agent, and SSH tries them sequentially, you'll hit the attempt limit before finding the right key. The server refuses the connection, and you're stuck.
The solution involves mapping specific keys to specific hosts in your SSH config. Instead of letting SSH try every available key, you tell it which key to use for which destination:
Host github.com
IdentityAgent ~/.1password/agent.sock
IdentityFile ~/.ssh/github_key.pub
Host work-server
HostName work.mycompany.com
IdentityAgent ~/.1password/agent.sock
IdentityFile ~/.ssh/work_key.pub
The IdentityFile directive references the public key. 1Password matches the public key to the corresponding private key in your vault and uses that specific key for authentication. SSH no longer tries every available key—just the one you specified.
Security advantages over traditional agents
The traditional SSH workflow stores private keys unencrypted on disk. Filesystem permissions restrict access to your user account, but anything running as your user can read them. Malware, compromised applications, or an attacker with filesystem access gains immediate access to your private keys. Once they have the keys, they have permanent access to any system those keys authenticate to—until you rotate them, which requires touching every machine where those keys exist.
The standard ssh-agent improves this slightly by keeping keys in memory rather than reading them from disk repeatedly. But it introduces a new problem: once keys are loaded, any process can request signatures without additional authorization. Your web browser, your text editor, that sketchy script you downloaded and ran—they can all use loaded keys transparently. The agent provides no granular access control.
1Password's agent eliminates both problems. Private keys never touch disk outside the encrypted vault. They don't exist in memory except during the brief moment needed to sign an authentication challenge. Every access requires explicit approval with context—1Password shows which application wants which key, allowing informed decisions about each request. Malicious processes can't silently use your keys. Compromised applications can't extract keys from memory. The keys remain protected by 1Password's encryption, synchronized across devices, and backed up automatically.
If your laptop gets stolen or compromised, your SSH keys remain safe inside the encrypted vault. Without your 1Password credentials and second factor, the keys are inaccessible. Compare that to traditional keys on disk—if the laptop is compromised, you must assume all keys on that machine are compromised and rotate them immediately across every system.
The biometric authentication aspect matters too. Touch ID or Windows Hello provides quick approval without typing passwords repeatedly. This reduces friction enough that the additional security doesn't feel like overhead—it feels like the system just working. The old model required either storing keys unencrypted (insecure) or using passphrase-protected keys and typing the passphrase frequently (high friction). The 1Password approach provides better security with less friction.
The synchronization advantage
Generate a key once. It's available everywhere 1Password is installed. Add the public key to a server once. Every machine authenticates using the vault's private key. Get a new machine, install 1Password, and all SSH keys are immediately available—no copying directories, no file transfers, no hunting for backup keys stored somewhere safe that you can't quite remember where.
This extends to team scenarios. Keys stored in shared vaults become available to team members. When someone leaves, remove their vault access, and they lose access to those keys. When someone joins, grant vault access, and they gain access. Key rotation happens once in the vault, and everyone picks up the new key automatically. The old approach required distributing new keys to every team member and ensuring they updated their systems—a coordination nightmare that inevitably resulted in someone still using old keys weeks later.
The synchronization happens automatically through 1Password's normal vault sync. You don't manage it separately from your other 1Password data. The keys receive the same encryption, the same backup, the same recovery options as everything else in your vault.
Advanced configurations
The agent config file (~/.config/1Password/ssh/agent.toml) provides additional control beyond basic vault selection. You can specify which keys the agent offers to servers and in what order:
[[ssh-keys]]
vault = "Personal"
[[ssh-keys]]
item = "GitHub Deploy Key"
vault = "Work"
This prioritizes the GitHub Deploy Key from your Work vault, offering it before other keys. Order matters when servers limit authentication attempts.
You can also configure the agent to require approval for every operation rather than maintaining session-based authorization:
[agent]
# Require approval for every SSH operation
session = "require"
This maximizes security at the cost of convenience—you'll approve every SSH connection, every Git push, every authentication. For most users, the default session-based authorization provides sufficient security without becoming tedious.
Git signing integration works similarly to SSH authentication. Configure Git to sign commits using keys from 1Password:
git config --global gpg.format ssh
git config --global user.signingKey "key::YOUR_KEY_FINGERPRINT"
Now every commit prompts for 1Password authorization, and the commit gets signed using your SSH key. This provides verification that commits actually came from you rather than someone who compromised your Git credentials.
The transition from traditional key management to vault-based keys took perhaps twenty minutes—enabling the agent, moving my existing keys into 1Password, updating my SSH config. The workflow improvements appeared immediately. New machines take minutes to configure for SSH access instead of the hour-long key hunting ritual. Key rotation happens in one place instead of across multiple systems. The security model finally matches what SSH authentication should have been from the beginning—keys that never leave encrypted storage, explicit authorization for every application, biometric approval instead of password tedium.
The old approach—unencrypted keys scattered across machines—works until it doesn't. Until you lose a laptop. Until you need to revoke access and can't remember which machines have which keys. Until malware exfiltrates your ~/.ssh directory. The 1Password approach eliminates these failure modes by centralizing keys in encrypted vaults whilst maintaining the transparency that makes SSH agent functionality useful.
If you're already using 1Password for passwords and sensitive data, adding SSH keys is the logical next step. If you're not using a password manager with SSH agent functionality, the manual key management you're doing is the problem that vault-based solutions solve. Either way, the file juggling ritual isn't a workflow worth preserving.
Published on:
Updated on:
Reading time:
10 min read
Article counts:
50 paragraphs, 1,972 words
Topics
TL;DR
The traditional SSH workflow stores unencrypted private keys on disk, accessible to any compromised process running as your user. 1Password eliminates this by keeping keys encrypted in vaults and requiring explicit approval for every authentication request—showing which application wants which key. This consent-based model prevents silent key exfiltration whilst providing biometric approval for immediate access. Keys synchronise automatically across all devices, transforming what was once an hour-long key hunting ritual into minutes of setup. The security improvement isn't theoretical: stolen laptops no longer mean immediate key rotation across every server, and malware can't silently authenticate using your credentials.