March 17th, 2026
Use of SSH keys is ubiquitous, and while I like SSH certificates even better, SSH keys are still great. But you do have to keep the private key, well, private. We normally do that by encrypting the private key with a passphrase, but of course that incurs all the usual issues inherent in passphrase management: picking a strong passphrase, having to remember or store that passphrase, having to enter the passphrase, and so on.
To avoid having to enter a lengthy passphrase every time we use the private key, we can make use of an SSH agent, meaning we have to provide the passphrase only once. But we're lazy and really would prefer the number of times we enter the passphrase to be zero, since otherwise we'll inevitably set it to be "password123".
So here are two convenient ways to never (or only exactly once) have to enter your SSH key's passphrase by example of macOS:
1. Store the passphrase in the macOS keychain
macOS provides a custom ssh_config option to automatically
use the keychain
for SSH. This is a seamless integration and allows
you to use SSH completely without any agents and still
not have to manually type your passphrase.
In order to take advantage of this, just add the UseKeychain yes option to your
~/.ssh/config. After that,
the first time you use a key, you will be prompted for
the passphrase and the system will then store it in
the keychain and supply it in the future
non-interactively:
$ grep UseKeychain ~/.ssh/config
UseKeychain yes
$ ssh -i ~/.ssh/mykey some-host hostname
Enter passphrase for key '/Users/jschauma/.ssh/mykey':
hostname.example.com
$ ssh-add -l
The agent has no identities.
$ ssh -i ~/.ssh/mykey -v -v some-host true 2>&1 | grep keychain
debug2: using passphrase from keychain
$
Note that even though we are not using an
agent, we are not prompted for a passphrase the second
time around, but ssh(1)
fetched it from the keychain automatically as shown in
the debug
output.
Now I'd have liked to show you the item in the keychain using the
security(1) command, but the
passphrase is placed in the "Local Items" keychain,
which appears to be inaccessible
to the security(1) tool.
Direct sqlite3 access to
~/Library/Keychains/*/keychain-2.db
doesn't help, either, since everything's encrypted, of
course. In addition, the item was added using an Key
Chain Access Group Entitlement of com.apple.ssh.passphrases; /usr/bin/ssh can access it because
it has that entitlement. I'll illustrate these
properties below:
$ security find-generic-password -s "SSH: /Users/jschauma/.ssh/mykey"
security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
$ echo "SELECT rowid,acct,agrp,data,
datetime(mdat + 978307200, 'unixepoch', 'localtime') AS last_modified
FROM genp
WHERE agrp = 'com.apple.ssh.passphrases'
ORDER BY mdat DESC
LIMIT 1;" | sqlite3 ~/Library/Keychains/*/keychain-2.db
31926|luINe褞V-?&?:?:?^]$?|com.apple.ssh.passphrases|^H|2026-03-17 11:39:18
$ codesign -d --entitlements - /usr/bin/ssh
Executable=/usr/bin/ssh
[Dict]
[...]
[Key] keychain-access-groups
[Value]
[Array]
[String] com.apple.ssh.passphrases
$ Just sharing these commands above because it took me a while to find them as I was looking for ways to get the key from the command-line and understand the different restrictions. (Arguing with AI about the many different ways it hallucinated for how to retrieve the key using the command-line was a big waste of time, of course.) Anyway, where were we?
...but still use an agent
Of course not having added this key
to your agent means that you can't forward it to
another system. If you do need that, then add AddKeysToAgent yes to your ~/.ssh/config. This option works
just fine in combination with UseKeychain, but comes with the
caveat that many SSH servers have a default of how
many authentication attempts they permit: OpenSSH, for
example, defaults to MaxAuthTries
6. That is, if you have more than six keys in
your agent, you might be unable to log in because the
server closes the connection before your agent can
even offer the right key.
The workaround for that is to specify an explicit
IdentityFile and enable
IdentitiesOnly in your
config file for the given host. For example:
$ cat ~/.ssh/config
UseKeychain yes
AddKeysToAgent yes
Host *ip.linodeusercontent.com
IdentityFile ~/.ssh/linode
IdentitiesOnly yes
Host *amazonaws.com *.ip.aws
IdentityFile ~/.ssh/aws
IdentitiesOnly yes
$ ssh 50-116-63-125.ip.linodeusercontent.com true
Enter passphrase for key '/Users/jschauma/.ssh/linode':
$ ssh-add -l
256 SHA256:tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0 (ED25519)
$ ssh -v 50-116-63-125.ip.linodeusercontent.com true 2>&1 | grep agent
debug1: get_agent_identities: bound agent to hostkey
debug1: get_agent_identities: agent returned 1 keys
debug1: Will attempt key: /Users/jschauma/.ssh/linode ED25519 SHA256:tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0 explicit agent
debug1: Offering public key: /Users/jschauma/.ssh/linode ED25519 SHA256:tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0 explicit agent
debug1: Server accepts key: /Users/jschauma/.ssh/linode ED25519 SHA256:tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0 explicit agent
$ Cool! We can use our agent, but don't have to type our passphrase even after a reboot, because the keychain will supply it. Pretty cool. But there's another way to do this:
2. Use 1Password
If you use 1password, you can also store your SSH keys directly in your password manager. This is particularly neat, because it now allows you to use biometric authentication to unlock the key, and thus doesn't involve a passphrase at all. The secret key remains in the 1Password vault.
The documentation
provided by 1Password is excellent, so you can just follow
it. The one thing to pay attention to is the above
mentioned limitation on the number of keys in your
agent. When using 1Password for your keys, your
private SSH key doesn't live in your ~/.ssh/ directory, so in order to
use the IdentityFile
directive, you need to use the "SSH
Bookmarks" feature in 1Password. That creates a
separate ~/.ssh/1Password/config file,
which you can include from your normal configuration
file.
Alternatively, you can of course also just populate
your normal config file with the pathnames for the
public keys found in the ~/.ssh/1Password/ directory. The
file names are based on the public key fingerprint, so
maybe creating memorable symlinks might be useful:
$ ls ~/.ssh/1Password config SHA256_2LPQtjSsvmKvMRTZovolV95osJ6gV9KN9aoRrRKaDtw.pub SHA256_fB9lcd3sLYCBdupp+spKBHqlcAvKvxyHzt3MLf+rrl8.pub SHA256_NUI+Qd8mJ8HsZrIiGChLaEf0b8Ge6JyLDw0NvAZgt_I.pub SHA256_tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0.pub $ file -h ~/.ssh/agent.sock /Users/jschauma/.ssh/agent.sock: symbolic link to /Users/jschauma/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock $ ssh-add -l The agent has no identities. $ SSH_AUTH_SOCK=~/.ssh/agent.sock ssh-add -l 256 SHA256:tSQphFDPCfX58d9LvdxErSv6CBf2B8fFYTB+d2AqmA0 Linode SSH Key (ED25519) 256 SHA256:NUI+Qd8mJ8HsZrIiGChLaEf0b8Ge6JyLDw0NvAZgt/I Some SSH Key (ED25519) 256 SHA256:2LPQtjSsvmKvMRTZovolV95osJ6gV9KN9aoRrRKaDtw Another SSH Key (ED25519) 256 SHA256:fB9lcd3sLYCBdupp+spKBHqlcAvKvxyHzt3MLf+rrl8 EC2 SSH Key (ED25519) $ ln -s ~/.ssh/1Password/SHA256_tSQp* ~/.ssh/1Password/linode.pub $ ln -s ~/.ssh/1Password/SHA256_fb9* ~/.ssh/1Password/aws.pub $ cat ~/.ssh/config Host *ip.linodeusercontent.com IdentityAgent "~/.ssh/agent.sock" IdentityFile ~/.ssh/linode.pub IdentitiesOnly yes Host *amazonaws.com *.ip.aws IdentityAgent "~/.ssh/agent.sock" IdentityFile ~/.ssh/aws.pub IdentitiesOnly yes $
Our default SSH agent does not have any keys, but the 1Password ٰSSH agent does. With that in place, you should now be able to see a prompt for authentication using 1Password requesting to use the SSH private key stored in your vault:
Note that it says that there are 4 keys in the agent,
but due to the IdentityFile
directive, it will use that key explicitly, as
intended instead of iterating over all keys.
The SSH keys you store in 1Password will of course be available on all systems where you have access to 1Password. This is both useful (for obvious reasons) and possibly risky: you may in fact want to have different SSH keys for access to a server from different devices, and if you have access to multiple vaults (e.g., a work environment vault as well as a personal vault), you absolutely need to make sure you are placing the right keys into the right vault.
Now there are of course many other ways to handle your SSH keys, and other password managers may also offer SSH agent support. The solutions I wrote down here just worked for me, and hopefully are useful to somebody else out there. ✌
March 17th, 2026
Links:

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.