Sixth post in a series where I read through SSH man pages and write about things that catch my eye. Previous posts: ObscureKeystrokeTiming, ChannelTimeout, Match version, Match sessiontype, Escape Sequences. Today lets move to something a little bit different: AddKeysToAgent.

The typical SSH key workflow looks like this: we generate a key with a passphrase, then we either type the passphrase every time we connect, or we run ssh-add once to load the key into our agent so it stays decrypted in memory. Most people do the ssh-add dance at the start of their session and don't think about it again. Some people skip the passphrase entirely because they find the workflow annoying, which is worse.

AddKeysToAgent eliminates the manual step. It's a ssh_config directive that tells the SSH client to automatically add keys to a running agent after successful authentication. You type our passphrase once on first use, and the key gets loaded into the agent. Subsequent connections use the agent and don't prompt.

From the man page:

AddKeysToAgent
    Specifies whether keys should be automatically added to a
    running ssh-agent(1).  If this option is set to yes and a
    key is loaded from a file, the key and its passphrase are
    added to the agent with the default lifetime, as if by
    ssh-add(1).  If this option is set to ask, ssh(1) will
    require confirmation using the SSH_ASKPASS program before
    adding a key (see ssh-add(1) for details).  If this option
    is set to confirm, each use of the key must be confirmed,
    as if the -c option was specified to ssh-add(1).  If this
    option is set to no, no keys are added to the agent.
    Alternately, this option may be specified as a time interval
    [...] to specify the key's lifetime in ssh-agent(1), after
    which it will automatically be removed.  The argument must
    be no (the default), yes, confirm (optionally followed by a
    time interval), ask or a time interval.

The simplest version, we can just add it to our config for all hosts:

Host *
    AddKeysToAgent yes

Now every key we use gets loaded into the agent on first use. No more ssh-add at login. But yes keeps the key in the agent forever (until the agent dies, or you manually remove it). That's fine on a personal laptop, but on shared machines or if we're forwarding our agent, we probably want more control.

The time-limited variant is where it gets interesting, if we set it to a duration instead of yes:

Host *
    AddKeysToAgent 1h

The key gets added to the agent with a 1-hour lifetime. After that, it's automatically removed, and the next connection will prompt for the passphrase again. This is a good balance between convenience and security, our key isn't sitting decrypted in memory indefinitely. The time format supports s (seconds), m (minutes), h (hours), d (days), w (weeks), and combinations like 1h30m.

Then there's confirm:

Host *
    AddKeysToAgent confirm

This adds the key to the agent, but every time the key is used for authentication, the agent will pop up a confirmation dialog via ssh-askpass before signing. We get a visual prompt each time something tries to use our key. This is particularly valuable if we forward our agent to remote hosts, it means a compromised remote machine can't silently use our key to hop further without you seeing the confirmation. We can combine confirm with a time limit for even more control:

Host *
    AddKeysToAgent confirm 4h

Here the key is loaded with both a confirmation requirement and a 4-hour expiry.

The ask option is different from confirm. With ask, we get prompted before the key is added to the agent, it's a one-time gate on whether the key should be loaded at all. With confirm, the key is loaded immediately, but we're prompted on every subsequent use. These serve different purposes: ask protects against accidentally loading a key, confirm protects against unauthorized use of an already-loaded key.

There are few practical notes. AddKeysToAgent requires a running ssh-agent with SSH_AUTH_SOCK set in our environment. If no agent is available, the option is silently ignored, and we just get the normal passphrase prompt each time. On macOS, the system agent is usually running already. On Linux, it depends on our desktop environment or how we start our session — most modern setups (systemd user sessions, GNOME, etc.) launch an agent automatically.

For the confirm option to work, we need a ssh-askpass program installed. On macOS, ssh-askpass isn't included by default, but there are several available (like ssh-askpass-mac from Homebrew). On Linux with a desktop environment, it's usually available through the system package manager.

The combination I've settled on for my own config is confirm 8h on machines where I forward my agent, and a plain 4h everywhere else. The timeout means I re-authenticate at least once a workday, and the confirmation on forwarded sessions means nothing uses my key without me seeing it.