ssh-agent and the macOS Keychain
Your Mac asks for the same SSH key passphrase every time, and every guide tells you to run ssh-add -K forever. Here is the setting that actually causes it, quoted from the manual page Apple ships.
The short version. macOS does not forget your passphrase.
It was never told to remember it. Two options in ~/.ssh/config
control this, UseKeychain and AddKeysToAgent, and the
manual page Apple ships states that both default to no. Setting
them is a one-time fix. The advice you will find on most pages about this —
run ssh-add -K at every login — treats the symptom forever
instead.
Why does my Mac ask for the SSH key passphrase every single time?
Because on a default macOS installation nothing is storing it. When you run
ssh and your private key is protected by a passphrase, OpenSSH
needs that passphrase to decrypt the key in memory before it can sign the
authentication challenge. It asks you, uses the result, and then the process
exits and the decrypted key goes with it. The next connection starts from
nothing. The component that is supposed to hold the decrypted key between
connections is ssh-agent, and the component that is supposed to
hold the passphrase across reboots is the login Keychain. Neither of them is
wired up automatically. macOS runs an agent for you, but it starts empty, and
it stays empty until something adds a key to it. That "something" is what most
people end up doing by hand, over and over, without realising there is a
setting for it.
Which two settings actually control this?
Apple ships a patched OpenSSH whose ssh_config(5) manual page
documents a macOS-only option. Its own words: "On macOS, specifies whether
the system should search for passphrases in the user's keychain when attempting
to use a particular key. When the passphrase is provided by the user, this
option also specifies whether the passphrase should be stored into the keychain
once it has been verified to be correct. The argument must be 'yes' or 'no'.
The default is 'no'." That option is UseKeychain. The second
is AddKeysToAgent, which is standard OpenSSH rather than an Apple
addition, and whose documented default is likewise no. Read
together, the two defaults explain the entire complaint: macOS will not look in
the Keychain for your passphrase, and it will not keep the key in the agent
after using it. Both behaviours are opt-in, and almost nobody is told to opt
in.
The configuration that fixes it
Put this in ~/.ssh/config. Create the file if it does not
exist, and make sure it is not world-readable.
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
chmod 600 ~/.ssh/config
The first time you connect after this change, macOS prompts for the
passphrase once more. That prompt is the one that matters: entering it stores
the passphrase in your login Keychain and loads the key into the agent. From
then on the agent answers on your behalf, and after a reboot the Keychain
supplies the passphrase without asking. There is nothing to add to
.zshrc, nothing to run at login, and no background script to
maintain.
One documented incompatibility. The same manual page states
that UseKeychain is "Incompatible with
PKCS11Provider". If you authenticate with a smart card, a
YubiKey in PIV mode, or anything else driven through a PKCS#11 library, this
option is not the mechanism for you and setting it will not help.
Why is most of the advice about this wrong?
Search for this problem and the results are dominated by pages written
between 2016 and 2017, when macOS Sierra changed the agent's behaviour and
broke a workflow people had relied on for years. Those pages were accurate
then. They are not accurate now, and they share a common shape: they tell you
to run ssh-add -K, often from a shell startup file so it runs at
every login. That instruction has two problems in 2026. The flag was renamed,
so on a current macOS the short form is deprecated in favour of a long one.
More importantly, running ssh-add at every login is a workaround
for not having set UseKeychain and AddKeysToAgent.
It papers over the default rather than changing it, which is why the problem
comes back on every new machine you set up.
What replaced ssh-add -K?
Apple renamed the two Keychain-related flags to self-describing long forms.
The manual page for ssh-add(1) that ships with macOS gives the
mapping precisely, and it is worth stating carefully because the two are
frequently reported the wrong way round:
| Current flag | Legacy flag | What the manual page says it does |
|---|---|---|
--apple-use-keychain |
-K |
"When adding identities, each passphrase will also be stored in the user's keychain. When removing identities with -d, each passphrase will be removed from it." |
--apple-load-keychain |
-A |
"Add identities to the agent using any passphrase stored in the user's keychain." |
So --apple-use-keychain is the one that writes a
passphrase into the Keychain while adding a key, and
--apple-load-keychain is the one that reads passphrases
back out to populate the agent. If you set UseKeychain yes in your
config you will rarely need either of them directly, because the config option
covers both directions for keys used through ssh.
How do I check whether it actually worked?
Ask the agent what it is holding. ssh-add -l lists the
fingerprints of every key currently loaded, one line each, and prints "The
agent has no identities" when it is empty. Run it immediately after a reboot,
before connecting to anything. If your key is listed at that point, the
Keychain is supplying the passphrase and the setup is working. If the agent is
empty after a reboot but fills up the moment you connect, that is
AddKeysToAgent doing its job while UseKeychain is not
set, and you will be prompted again after the next restart. If it is empty and
stays empty, neither option took effect — check that the file is really at
~/.ssh/config and that your Host pattern actually
matches the host you are connecting to.
ssh-add -l
ssh -v git@example.com 2>&1 | grep -i 'offering\|agent'
The verbose flag is the honest answer to "which key is it even trying?". OpenSSH prints a line for each identity it offers and names the source, so you can see whether the key came from the agent or was read from disk. That distinction is exactly what you are trying to establish here, and it takes one command rather than guesswork.
How do I remove a passphrase from the Keychain again?
Deleting a key from the agent and deleting its passphrase from the Keychain
are two separate actions, and doing only the first is a common mistake. The
manual page is explicit that --apple-use-keychain combined with
the delete flag is what removes the stored passphrase, so the complete removal
for a single key is ssh-add -d ~/.ssh/id_ed25519 together with
--apple-use-keychain. To confirm, open Keychain Access, select the
login keychain, and search for the key's filename; macOS stores these as
application password items named after the key. If an item is still there after
you thought you had removed it, the agent was cleared but the Keychain was
not.
ssh-add --apple-use-keychain -d ~/.ssh/id_ed25519
ssh-add -D # clears every identity from the running agent
Does any of this change when the server is mounted as a volume?
Mounted volumes do behave differently, and this is the part that catches
people out. Everything above
describes keys used by the ssh command in a terminal, where a
prompt can appear in front of you and you can type into it. An application that
mounts a remote server as a volume in the Finder is not running in your
terminal session, and depending on how it is built it may not share your
agent's socket at all. If a mount fails to authenticate with a key that works
perfectly from the command line, the agent is usually the reason: the app
cannot reach it, or is not looking. That is worth checking before you conclude
the key or the server is at fault. The related symptom at the command line has
its own page here, Permission
denied (publickey) on macOS, which starts from the same agent
question.
Disclosure. This site is published by OnePasswordManager Ltd, who also make SSHMount, a paid macOS app that mounts SSH and SFTP servers as Finder volumes. The behaviour described above is OpenSSH and macOS behaviour, not our product's, and everything on this page works with no third-party software installed. Product details are on sshmount.it, deliberately not here.
Where to go next
-
SSH keys on macOS: the whole picture
Where keys live, what reads them, and which parts of the chain are Apple's rather than OpenSSH's.
-
Ed25519 or RSA in 2026?
What OpenSSH 8.8 disabled by default, why an old RSA key can suddenly stop working, and what to generate instead.
Sources
Every technical claim above is checked against one of these. Where a manual page is quoted, it is the copy shipped by the vendor named, not a third-party summary of it.
- ssh_config(5), the manual page shipped with macOS — UseKeychain, AddKeysToAgent, IdentityAgent — https://keith.github.io/xcode-man-pages/ssh_config.5.html
- ssh-add(1), the manual page shipped with macOS — --apple-use-keychain and --apple-load-keychain — https://keith.github.io/xcode-man-pages/ssh-add.1.html
- OpenSSH release notes, upstream project — https://www.openssh.com/releasenotes.html