keychain - Man Page

Manager for ssh-agent, gpg-agent and private keys. Compatible with POSIX systems.

Examples (TL;DR)

Synopsis

keychain [ -hklQqV ] [ --clear --confhost --confallhosts --debug --extended --gpg2 --help --ignore-missing --list --noask --nocolor --nogui --noinherit --nolock --quick --quiet --ssh-allow-forwarded --ssh-rm --ssh-spawn-gpg --systemd --version ] [ --ssh-agent-socket path ] [ --dir dirname ] [ --host name ] [ --lockwait seconds ] [ --stop which ] [ --timeout minutes ] [ --wipe which ] [ keys... ]

Introduction

Keychain helps you to manage SSH and GPG keys in a convenient and secure manner. It acts as a frontend to ssh-agent and ssh-add, but allows you to easily have one long running ssh-agent process per system, rather than the norm of one ssh-agent per login session.

This dramatically reduces the number of times you need to enter your passphrase. With keychain, you only need to enter a passphrase once every time your local machine is rebooted. Keychain also makes it easy for remote cron jobs to securely "hook in" to a long running ssh-agent process, allowing your scripts to take advantage of key-based logins.

Keychain also supports GnuPG 2.1 and later, and will automatically start gpg-agent if any GPG keys are referenced on the command-line, and will ensure these credentials are cached in memory and available for use.

Keychain supports most UNIX-like operating systems. It supports integration with Bourne-compatible, csh-compatible and fish shells.

Additional documentation for Keychain can be found on  "https://www.funtoo.org/Funtoo:Keychain" in the Keychain wiki page.

Lifecycle

Typically, you configure keychain to run when you first log in to a system. If you are using Bourne shell or bash, you will create a ~/.profile or  ~/.bash_profile file and include the following line in it:

    eval "$(keychain --eval id_rsa)"

Keychain will start ssh-agent if one isn't already running. Keychain then checks to make sure your private keys (in this example, "id_rsa") are loaded into the agent. If they are not, you are prompted for any passphrase necessary to decrypt them, so that they are cached in memory and available for use.

In addition to printing some user-friendly output to your terminal, keychain will also output important ssh-agent environment variables, which the "$( )" (you can also use "` `") captures, and the "eval" evaluates, setting these variables in your current shell.

These ssh-agent environment variables are also written to ~/.keychain/${HOSTNAME}-sh, so that subsequent logins and non-interactive shells such as cron jobs can source the file to access the running ssh-agent and make passwordless ssh connections using the cached private keys -- even when you are logged out. These files are collectively called pidfiles.

The key files specified on the command-line will be searched for in the ~/.ssh/ directory, and keychain will expect to find the private key file with the same name, as well as a .pub public key. Keychain will also  see if any GPG keys are specified, and if so, prompt for any passphrases to cache these keys into gpg-agent.

Typically, private SSH key files are specified by filename only, without path,  although it is possible to specify an absolute or relative path to the private key file as well. Private key files can be symlinks to the actual key as long as your system has the readlink command available. More advanced features are available for specifying keys as well -- see the
--extended and --confallhosts options for more information.

In addition, for GPG keys specified, similar steps will be taken to ensure  that gpg-agent has the GPG key cached in memory and ready for use.

Streamlining and Simplification

Keychain 2.9.0 has been streamlined, and with this maintenance several command-line options have been retired as they are not completely necessary. This simplifies the use of the tool by making it more intuitive to use. The files created in ~/.keychain have also been cleaned up. This section details all the important changes.

Pidfile Changes

"Pidfile" is the nickname for files created in ~/.keychain which can then be sourced by your scripts to access a running agent.

When using gpg-agent for GPG keys, keychain will no longer create a ~/.keychain/${HOSTNAME}-sh-gpg pidfile. This file is no longer needed as the canonical GPG socket inside ~/.gnupg/ will be used to detect the running gpg-agent, which is the modern convention. GnuPG 2.1 and later  have stopped using environment variables to find the agent, so we follow this upstream change.

Improved Debugging

A new --debug option is now available which will print additional information related to keychain's decisions regarding why and how an agent was found -- or not.

New (and Deprecated) Options

This section provides an overview of new and deprecated command-line options. For full details on each option, see the respective option definition under "Options".

Keychain 2.9.2

The --confhost option has been deprecated. Instead of --confhost hostname, use --extended host:hostname. This extended format allows multiple keys of multiple types (SSH, GPG and SSH-from-hostname) to be specified on the  command-line together. This is also fully compatible with --confallhosts, and keychain now de-duplicates the list of keys to be loaded.

Keychain 2.9.1

The short-lived --ssh-wipe and --gpg-wipe options that appeared only in version 2.9.0 were replaced with --wipe which to work similarly to  the --stop option, and allows you to specify "ssh", "gpg" or "all".

Keychain 2.9.0

The --agents option is now deprecated. Keychain will always ensure an ssh-agent or equivalent is running, or if --ssh-spawn-gpg is used,  potentially a gpg-agent for the purpose of storing SSH keys if no running ssh-agent is available. To simply use a gpg-agent if one is already running, falling back to launching ssh-agent if no agent is available, use the --ssh-allow-gpg option.

Specifying a GPG key on the command-line will instruct keychain to  enable gpg-agent functionality automatically. This eliminates an option  that you need to specify (--agents ssh,gpg) when invoking keychain,  and for many will avoid spawning a GPG agent you may not be using.

Specifying the --agents option will now display a warning that it's  deprecated, but keychain will not abort.

The --inherit option, which took one of four arguments, has been  deprecated. Keychain's default behavior remains that of preferring to use an ssh-agent or equivalent referenced by its pidfile, falling back to finding an ssh-agent in its environment. By default, keychain will not use a gpg-agent socket for SSH keys unless at least --ssh-allow-gpg is specified. Similarly, the use of any forwarded SSH agent connection is disabled by default and can be enabled via --ssh-allow-forwarded. Again, see the full documentation for each option in the "Options" section.

You can still influence keychain's behavior via the still-present  --noinherit option which will prevent all detection of existing SSH agents via the environment.

The --clear option is still available, but isn't intended to be a  "standalone" option, meaning that it is used to perform an initial clearing of cached keys before loading any specified keys when Keychain is run. To perform the sole action of wiping all cached keys, use the --wipe action. To remove an individual cached SSH private key or keys, use the --ssh-rm keyfile option.

The --stop option will now only stop any running ssh-agent processes, and still supports three possible options: "mine", "others" and "all". It no longer stops gpg-agent processes, which tend to get auto-respawned by GPG tools, so killing gpg-agent typically doesn't make a lot of sense.

Better Gnupg Integration

Keychain can now use an existing gpg-agent that has been started in your environment to store ssh keys, rather than spawning its own ssh-agent, by using the --ssh-allow-gpg option.

If you would like keychain to spawn gpg-agent instead of ssh-agent, and use it to store SSH keys, specify the "--ssh-spawn-gpg" option.

Without either option, keychain will not use an SSH_AUTH_SOCK that is provided by gpg-agent, and will spawn an official ssh-agent process.

In addition, behind the scenes, keychain now uses the gpg-connect-agent  executable to restart the agent, get official PID and socket information, etc.

Please note that while gpg-agent provides full compatibility with ssh-agent, its password prompt is handled by pinentry and its store may encrypt your in-memory keys. For this reason, consider this new feature experimental, and use GitHub issues to report back any  anomalies or suggested improvements for gpg-agent integration.

Display Changes

When keychain uses gpg-agent for either GnuPG or SSH support, then keychain will display the GnuPG socket file in its output, rather than the PID. Since the socket file has the ~/.gnupg path in it, this communicates to you that gpg-agent, not ssh-agent, is active. If you see an integer PID, this means that ssh-agent is being used. =head2 STREAMLINED STARTUP

By default, keychain will always ensure that an ssh-agent should be started. It will only start a gpg-agent if a GPG key is referenced on the command-line.

Modern versions of gpg-agent also support the caching of SSH keys, allowing it to be a drop-in replacement for ssh-agent. With keychain 2.9.0, a new  "--ssh-spawn-gpg" option has been added, which when specified will give  keychain permission to spawn a gpg-agent in place of ssh-agent.

Code Optimization

With keychain 2.9.0, there has been significant code cleanup, reducing the size of the script from 1500 lines to about 1100 lines. In addition, the script is now fully compliant with ShellCheck <https://shellcheck.net>, which will be hugely helpful to ensure continued POSIX shell compatibility moving forward.

Agent Detection and Startup Algorithm

This section documents the official algorithm used for detecting and if necessary starting ssh-agent, to facilitate understanding as well as developer maintenance of the codebase.

Definitions

There are several important definition related to the algorithm:

1. The agent, "ssh-agent", which is a long-running daemon. This can also in some cases be "gpg-agent", depending on command-line options.

2. The inherited agent, which is the agent or forwarded agent that was not started by keychain, but is detected in the environment or by other means.

3. The adopted agent, which is an inherited agent whose information has been persisted by being written to the pidfiles (see below).

4. The environment variables SSH_AUTH_SOCK, which points to the socket file used to communicate with ssh-agent, and optionally SSH_AGENT_PID, which indicates its process ID if running locally (although gpg-agent does not define SSH_AGENT_PID, even if running locally.)

5. The file ~/.keychain/${HOSTNAME}-sh and related files, which are collectively referred to as "pidfiles". Pidfiles are used to persistently store SSH_AUTH_SOCK and SSH_AGENT_PID environment variables for use by other scripts, as well as by keychain itself, formatted so that they can be "sourced" by shells of various types.

6. Relevant command-line options affecting behavior, which include --noinherit, --ssh-allow-gpg, --ssh-spawn-gpg, and --ssh-allow-forwarded.

Algorithm Overview

When the keychain script is run, it will first attempt to find a running ssh-agent.

Phase 1: pidfile: To do this, it will first look for an existing pidfile. If one exists, it will be inspected and used to find a running agent, in alignment with specified command-line options. If this process is successful, a "keychain-spawned" agent is found and this process is complete. Otherwise, we continue to the next step.

Phase 2: environment: If keychain's pidfile did not yield a running agent, keychain looks at environment variables defined in the current environment. This step will be skipped if the --noinherit option is specified. If an agent is found that is in alignment with specified command-line options, it is considered "inherited" by keychain, and the process is complete. Otherwise, we continue to the next step.

Phase 3: spawn agent: In the absence of finding a keychain-spawned or existing agent that can be adopted, keychain will spawn a new ssh-agent, or a new gpg-agent if --ssh-spawn-gpg is specified and gpg-agent is available.

Final Phase: update pidfile: In addition, the pidfiles will be updated to reflect the keychain-spawned or "inherited" agent. An "inherited" agent, once written to the pidfile, is now considered to be "adopted".

Pidfile update exception: If the --ssh-allow-forwarded option was specified, and a forwarded SSH socket was found -- which is identified as a valid SSH socket defined in a SSH_AUTH_SOCK variable, which has no associated or valid SSH_AGENT_PID also defined in the environment and is also determined to not be the socket of any running gpg-agent -- then this agent will simply be used, but not persisted in any pidfile. This is because this SSH-supplied socket will disappear when the underlying SSH connection terminates, and thus it cannot be relied on to be available persistently.

The Quick Short-Circuit

When the --quick option is specified, a special algorithm will run prior to the main agent-detection algorithm listed above. A pidfile, if it exists, will be evaluated as per Phase 1 of the main algorithm. If a valid running agent is found, it will be queried for valid keys. If at least one valid key is loaded into the agent, the quick start is considered successful, and keychain will skip the regular agent startup algorithm, and will use this found agent.

Summary and Rationale

The keychain ssh-agent detection and startup algorithm is somewhat sophisticated for a reason. There is an intention behind its behavior.

The algorithm has been specifically designed to prefer an agent spawned by keychain, or previously adopted, if that agent is currently available. This is by design, because other system software could spawn ssh-agent and/or gpg-agent processes, and we want keychain to  not coerced into using these new agents which may suddenly appear in the environment unexpectedly when new desktop sessions start and in other circumstances.  If keychain is too "suggestible", it will lose track of the agent which currently holds valid keys, which can result in unncessary prompting for passphrases, and general confusion.

Options

--absolute

Any arguments to "--dir" are interpreted to be absolute. The default behavior is to append "/.keychain" to the argument for backwards compatibility.

--clear

When specified, this option adds an initial step prior to adding any keys to the agents of wiping all existing cached keys/passphrases. This is intended to be used alongside keychain --eval to ensure that only the specified keys are loaded, and that keychain should assume that you are an intruder until proven otherwise and force all interactive logins to specify valid passphrases.  This option increases security and  still allows your  cron jobs to use your ssh keys when you're logged out.

--confallhosts

In addition to any keys specified on the command-line, this option will tell keychain to scour ~/.ssh/config for all private keys referenced in all IdentityFile lines, and load all keys for all hosts.

--confirm

Keys are subject to interactive confirmation by the SSH_ASKPASS program before being used for authentication.  See the -c option for ssh-add(1).

--debug

Keychain 2.9.0 introduces the --debug option, which will output  additional information related to how Keychain makes its agent-selection process. Specifically, it will output when an SSH_AUTH_SOCK is rejected because it is being supplied by gpg-agent -- and this is not allowed due to no --ssh-allow-gpg option, or when it is rejected because it appears to be from a forwarded SSH connection, and --ssh-allow-forwarded was not supplied.

--dir dirname

Keychain will use dirname rather than $HOME/.keychain

--env filename

After parsing options, keychain will load additional environment settings from "filename".  By default, if "--env" is not given, then keychain will attempt to load from ~/.keychain/[hostname]-env or alternatively ~/.keychain/env.  The purpose of this file is to override settings such as PATH, in case ssh is stored in a non-standard place.

--eval

Keychain will print lines to be evaluated in the shell on stdout.  It respects the SHELL environment variable to determine if Bourne shell or C shell output is expected.

--extended

This enables extended command-line key processing with more features, and is a replacement for the old --confhost option. When specified, each key specified on the command-line must have a prefix to explictly. categorize it. SSH keys must have a prefix of "sshk:" immediately  followed by the path or key name (the part after the "sshk:" is processed just like a SSH key is without the --extended option). GPG keys must be in the format "gpgk:" immediately followed by the 8 or 16-character fingerprint. If "host:<hostname>" is specified, then Keychain will  extract the SSH configuration for the specified hostname, grab all  identityfile options (private keys) specified, and these keys will be included in the set of keys to be loaded by keychain. This allows multiple keys of multiple types, including SSH-keys-by-host, to be specified together, which wasn't possible with --confhost.

--gpg2

This option changes the default gpg calls to use gpg2 instead to support distributions such as Ubuntu which has both gpg and gpg2

--help -h

Show help that looks remarkably like this man-page. As of 2.6.10, help is sent to stdout so it can be easily piped to a pager.

--host name

Set alternate hostname for creation of pidfiles

--ignore-missing

Don't warn if some keys on the command-line can't be found.  This is useful for situations where you have a shared .bash_profile, but your keys might not be available on every machine where keychain is run.

-l --list

List signatures of all active SSH keys, and exit, similar to "ssh-add -l".

-L --list-fp

List fingerprints of all active SSH keys, and exit, similar to "ssh-add -L".

--lockwait seconds

How long to wait for the lock to become available.  Defaults to 5 seconds. Specify a value of zero or more. If the lock cannot be  acquired within the specified number of seconds, then this keychain process will forcefully acquire the lock.

--noask

This option tells keychain do everything it normally does (ensure ssh-agent is running, set up the ~/.keychain/[hostname]-{c}sh files) except that it will not prompt you to add any of the keys you specified if they haven't yet been added to ssh-agent.

--nocolor

Disable color highlighting for non ANSI-compatible terms.

--nogui

Don't honor SSH_ASKPASS, if it is set.  This will cause ssh-add to prompt on the terminal instead of using a graphical program.

--noinherit

Don't inherit any agent processes, overriding the default behavior of inheriting all non-forwarded ssh-agent and any existing gpg-agent processes. Also see "Agent Detection and Startup Algorithm".

--nolock

Don't attempt to use a lockfile while manipulating files, pids and keys.

--query

Keychain will print lines in KEY=value format representing the values which are set by the agents.

--quick -Q

If an ssh-agent process is running then use it.  Don't verify the list of keys, other than making sure it's non-empty.  This option avoids locking when possible so that multiple terminals can be opened simultaneously without waiting on each other. See the  "The Quick Short-Circuit" section for more information regarding how this fits into the overall startup algorithm.

--quiet -q

Only print messages in case of warning, error or required interactivity. As of version 2.6.10, this also suppresses "Identities added" messages for ssh-agent.

--stop -k which

Kill currently running ssh-agent processes and exit.

Note that previous versions of keychain (2.8.5 and earlier) allowed killing of gpg-agent as well. This functionality was removed as ssh-agent and gpg-agent have a bit different design philosophies and you almost always only have at most one gpg-agent running at a time. Use "killall gpg-agent" if you really want to kill gpg-agent. However, since this option also removes pidfiles, it will remove any gpg-agent processes adopted by keychain that were being used to store ssh keys.

The following values are valid for "which" which controls which ssh-agents to target:

all

Kill all ssh-agent processes and quit keychain immediately.  Prior to keychain-2.5.0, this was the behavior of the bare "--stop" option.

others

Kill agent processes other than the ones keychain is providing.  Prior to keychain-2.5.0, keychain would do this automatically.  The new behavior requires that you specify it explicitly if you want it.

mine

Kill keychain's agent processes, leaving other agents alone.

--ssh-agent-socket path

Use this option to specify the path to the socket file that you would like ssh-agent to create and use as its official socket. By default, ssh-agent will create its own socket file, typically in /tmp.

--ssh-allow-forwarded

By default, keychain will not use a forwarded ssh-agent connection, which is a ssh-agent socket created by SSH that has no associated local process. To permit keychain to use a forwarded ssh-agent connection, specify this option. If a SSH-forwarded socket is used, it will not be persisted in the pidfiles, as it is not likely to be available outside of the currently-active SSH session.

--ssh-allow-gpg

Would you like to have keychain use an already-running gpg-agent to store your SSH keys, rather than spawning a new ssh-agent? This option does just that. When this option is specified, keychain will accept an SSH_AUTH_SOCK environment variable in its environment, even if it was created by gpg-agent. Modern versions of gpg-agent are also able to store SSH keys. By default, keychain has a special check to avoid using a gpg-agent that has set the SSH_AUTH_SOCK environment variable, and will instead spawn its own ssh-agent. With this option enabled, this restriction is turned off.  Please note that this option does not actually instruct keychain to spawn a  gpg-agent for storing SSH keys if no agent is available -- if you want that,  see the --ssh-spawn-gpg option, below.

ALSO NOTE: When a gpg-agent is adopted for ssh-agent duties in this way, the  ~/.keychain/${HOSTNAME}-sh pidfile will be updated to reference the  gpg-agent socket, so it will be seamlessly used by future cron jobs needing an ssh-agent, as well as by future invocations of keychain, as long as the --ssh-allow-gpg or --ssh-spawn-gpg (which implies --ssh-allow-gpg) are specified.

--ssh-spawn-gpg

This is the option to use if you're really on-board with using gpg-agent as a replacement for ssh-agent. Not only will keychain use a running gpg-agent if found as per the --ssh-allow-gpg, but if it needs to spawn a new ssh-agent, it will go ahead and spawn a gpg-agent in its place,  and use it instead. Also see notes for the --ssh-allow-gpg option, as this option also implies --ssh-allow-gpg.

--ssh-rm -r keys

Only perform the single action of removing the specified cached keys from the running ssh-agent, and then exit.

--systemd

Inject environment variables into the systemd --user session.

--timeout minutes

Allows a timeout to be set for identities added to ssh-agent. When this option is used with a keychain invocation that starts ssh-agent itself, then keychain uses the appropriate ssh-agent option to set the default timeout for ssh-agent. The --timeout option also gets passed to ssh-add invocations, so any keys added to a running ssh-agent will be individually configured to have the timeout specified, overriding any ssh-agent default.

Most users can simply use the timeout setting they desire and get the result they want -- with all identities having the specified timeout, whether added by keychain or not. More advanced users can use one invocation of keychain to set the default timeout, and optionally set different timeouts for keys added by using a subsequent invocation of keychain.

--version -V

Show version information.

--wipe which

Only perform the single action of wiping all agent's cached keys. Specify 'ssh', 'gpg' or 'all' for SSH keys, GPG keys and all agents respectively. Also see the --ssh-rm action and the --clear option.

Examples

This snippet should work in most shells to load two ssh keys and one gpg key:

    eval `keychain --eval id_rsa id_dsa 0123ABCD`

For the fish shell, use the following format:

    if status --is-interactive
        keychain --eval --quiet -Q id_rsa | source
    end

If you have trouble with that in csh:

    setenv SHELL /bin/csh
    eval `keychain --eval id_rsa id_dsa 0123ABCD`

This is equivalent for Bourne shells (including bash and zsh) but doesn't use keychain's --eval feature:

    keychain id_rsa id_dsa 0123ABCD
    [ -z "$HOSTNAME" ] && HOSTNAME=`uname -n`
    [ -f $HOME/.keychain/$HOSTNAME-sh ] && \
            . $HOME/.keychain/$HOSTNAME-sh

This is equivalent for C shell (including tcsh):

    keychain id_rsa id_dsa 0123ABCD
    host=`uname -n`
    if (-f $HOME/.keychain/$host-csh) then
            source $HOME/.keychain/$host-csh
    endif

Likewise, the following commands can be used in fish:

    keychain id_rsa id_dsa 0123ABCD
    test -z "$hostname"; and set hostname (uname -n)
    if test -f "$HOME/.keychain/$hostname-fish"
        source $HOME/.keychain/$hostname-fish
    end

To load keychain variables from a script (for example from cron) and abort unless id_dsa is available:

    # Load keychain variables and check for id_dsa
    [ -z "$HOSTNAME" ] && HOSTNAME=`uname -n`
    . $HOME/.keychain/$HOSTNAME-sh 2>/dev/null
    ssh-add -l 2>/dev/null | grep -q id_dsa || exit 1

See Also

ssh-agent(1), gpg-agent(1), ssh-add(1), ssh(1)

Notes

Keychain was created and is currently maintained by Daniel Robbins. If you need to report a bug or request an enhancement, please report it to the GitHub project page at <https://github.com/funtoo/keychain>.  For more information about keychain, please visit <http://www.funtoo.org/FuntoO:Keychain>.

Info

2025-06-18 2.9.2 http://www.funtoo.org