ssh-add and the macOS Keychain: getting the passphrase prompt to actually go away across reboots

You set up an ed25519 SSH key with a strong passphrase, like the security guides told you to. Every time you boot your Mac and connect to a server, you type the passphrase. Every time you open a new terminal tab, sometimes you type it again. After a week, the passphrase has been typed enough times that you start considering whether to remove it altogether — which is exactly the wrong move.

The fix isn’t a weaker key. The fix is to teach ssh-agent + the macOS Keychain to remember the passphrase across reboots and shells, so you type it once per device lifetime and never again. The problem is that the right config has changed twice in recent macOS versions and most search results still tell you to do something that hasn’t worked since Big Sur.

The right ~/.ssh/config (macOS 13+, working in 2026)

# ~/.ssh/config — at the top, before any Host blocks

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519
  • UseKeychain yes — when ssh asks you for the passphrase the first time, store it in the macOS Keychain. Next time you SSH (even after a reboot), ssh-agent reads the passphrase out of Keychain silently. This is the magic line.
  • AddKeysToAgent yes — auto-add the key to ssh-agent on first use. Without this, every new shell starts with an empty agent and re-prompts.
  • IdentitiesOnly yes — only offer the key listed here, not every key in ~/.ssh. Without this, you’ll exhaust the server’s MaxAuthTries on hosts that have multiple keys.
  • IdentityFile — explicit so OpenSSH doesn’t try other defaults.

The one-time setup

# Add the key to the agent AND save its passphrase to Keychain.
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# Verify the key is in the agent
ssh-add -l
# Expected output: 256 SHA256:... id_ed25519 (ED25519)

After this once, your Keychain has the passphrase. Reboot, open Terminal, run ssh-add -l — the key is still there, no prompt.

Why the older guides don’t work in 2026

  • ssh-add -K was deprecated. The flag was renamed to --apple-use-keychain in macOS 12. Old -K still works on most installs but throws a deprecation warning, and it’s removed in some recent point releases.
  • UseKeychain in ~/.ssh/config is no longer a default. Apple removed it from the default config in macOS Monterey. You have to add it yourself.
  • Homebrew’s openssh is a separate path. If you ran brew install openssh, you have /opt/homebrew/bin/ssh alongside /usr/bin/ssh — and Homebrew’s openssh does not have UseKeychain support, because Apple’s Keychain bindings are in Apple’s fork. Make sure your $PATH finds Apple’s /usr/bin/ssh first, OR delete the Homebrew one if you don’t need it.

How to know which ssh you’re actually running

which ssh
ssh -V
# OpenSSH_9.x.x — Apple variant has a build like "OpenSSH_9.0.0p1, LibreSSL 3.x"
# Homebrew's looks like "OpenSSH_9.5p1, OpenSSL 3.x"

# If which ssh returns /opt/homebrew/bin/ssh and you want to use Apple's:
echo 'export PATH="/usr/bin:$PATH"' >> ~/.zshrc
# (or remove the brew one: brew uninstall openssh)

YubiKey FIDO2 keys: a special case

If your key is a hardware-resident ed25519-sk on a YubiKey, the Keychain story doesn’t apply — the private key is on the YubiKey, the local file is just a “key handle.” You’ll still get a touch prompt on every SSH connection (that’s the point of FIDO2). What you DO want is the libfido2 PIN cached, which is a slightly different config:

# ~/.ssh/config for a FIDO2 key alongside a regular ed25519
Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519
    IdentityFile ~/.ssh/id_ed25519_sk    # YubiKey key handle

SSH will try the regular key first (silent), then the FIDO2 key (touch). Don’t reverse the order — if the FIDO2 entry is first, every connection will prompt for a touch even when the regular key would have worked.

What to do if it still prompts

  1. Check that UseKeychain is in a Host * block at the TOP of ~/.ssh/config, not under a specific Host. ssh-config matching is first-match-wins; if a more specific block lacks UseKeychain, that wins.
  2. ssh -v <host> — verbose mode. Look for the line debug1: Keychain has key. If you see debug1: Keychain unavailable, you’re running Homebrew’s ssh.
  3. Check the Keychain entry exists: Open Keychain Access → search for ssh. You should see a “SSH: ~/.ssh/id_ed25519” item. If not, run ssh-add --apple-use-keychain ~/.ssh/id_ed25519 again.
  4. Make sure Login Keychain is unlocked. If you set a separate password for the Login Keychain, you need to unlock it on every reboot. The fix is to make the Login Keychain password match your user account password — System Settings → Users & Groups → Change Password (sets both at once).

One last gotcha: launchd-started ssh-agent

macOS’s ssh-agent is launched per-user by launchd, not by your shell. Sometimes after an upgrade the agent gets confused — ssh-add -l says “Could not open a connection to your authentication agent” even though SSH otherwise works. The reset:

launchctl bootout gui/$(id -u) /System/Library/LaunchAgents/com.openssh.ssh-agent.plist
launchctl bootstrap gui/$(id -u) /System/Library/LaunchAgents/com.openssh.ssh-agent.plist

# then re-add the key
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Half the “ssh-add not working” issues you’ll find on Stack Overflow are this exact stuck-agent problem, masquerading as ten different symptoms. Bouncing the agent fixes it almost every time.

Photo: Scattered keys with labeled keychains on a wooden surface by Marcin Szmigiel on Pexels.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.