Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: August 31, 2025
The ssh-agent is part of the OpenSSH package.
In this tutorial, we’ll understand how ssh-agent works and how to use it. We’ll also learn some best practices. Further, we’ll discuss how the SSH and ssh-agent work together to create a seamless experience for the user.
To make things clearer, let’s walk through a quick summary of the steps taken to establish an SSH connection:
By following these steps, a secure encrypted tunnel is created, and the client can now send commands, transfer files, or use port forwarding over the new tunnel. Notably, this procedure relies on the client having a trusted copy of the server’s public key, typically stored in the ~/.ssh/known_hosts file.
Now that we understand what SSH is and the typical session preparation and creation process, let’s see how ssh-agent fits into that.
ssh-agent is a key manager that holds the private keys used for public-key authentication (SSH-2 RSA, DSA, ECDSA, and Ed25519 keys). It enables us to initiate SSH connections, execute commands on remote servers, and perform secure file transfers without constantly re-entering a passphrase or pointing to a specific key. This improves both convenience and security.
There are three main features of ssh-agent. Let’s discuss each one.
The first feature of ssh-agent is key management. In particular, the agent stores the private keys in memory so that it can use them for authentication later. The agent stores the private keys in memory and not in the secondary storage to provide better security.
When trying to establish an SSH connection to a server, ssh-agent automatically handles the authentication using the SSH private keys already stored on the system. In particular, it picks the correct keys based on the parameters of the session. This way, the SSH experience is smoother and more user-friendly.
Finally, the third feature is session handling, which refers to how the ssh-agent manages the lifecycle and accessibility of SSH keys across different user sessions. This ensures that once the agent is started and keys are added, they can be used for authentication throughout the user’s session without needing to re-enter passphrases.
In this section, we walk through a typical ssh-agent workflow. Then, we understand some of the available options that ssh-agent offers.
Now, let’s walk through a typical ssh-agent workflow.
To start the agent, we use the eval command:
$ eval "$(ssh-agent -s)"
Thus, we start the agent and set up some environmental variables used by the agent.
After that, we add an SSH key:
$ ssh-add ~/.ssh/id_rsa
Notably, we can add, delete, or manage keys for the agent using the ssh-add command.
Furthermore, to list the keys available in the agent, we use the -l flag:
$ ssh-add -l
The -d switch removes a specific key:
$ ssh-add -d ~/.ssh/id_rsa
After configuring the required keys, we can establish a session.
Next, we connect to a remote server using SSH:
$ ssh [email protected]
When we run this command, the agent automatically authenticates the session behind the scenes with the respective key.
Finally, when done we can use a simple command to kill the agent:
$ eval "$(ssh-agent -k)"
This is a basic example of a workflow of the ssh-agent in action.
Now that we have seen a typical workflow, let’s discuss agent forwarding which is a useful feature of the ssh-agent.
So, let’s start exploring the options available when using ssh-agent.
To begin with, let’s explore some of the commonly used options:
| Option | Command | Description |
|---|---|---|
| -k | ssh-agent -k | Kill the active agent. |
| -t | ssh-agent -t 1h | Set the maximum lifetime for keys added to the agent. After that time passes, they expire. The lifetime may be specified in seconds or the format described in the sshd configuration documentation. |
| -s | ssh-agent -s | Output the Bourne-style shell setup commands to stdout. This is the default if the shell appears to not be a C shell. Typically, this is combined with eval to start the agent. |
| -c | ssh-agent -c | Output the C shell commands on stdout. This is the default if the shell appears to be a C shell. Typically, this is combined with eval to start the agent in a C shell environment. |
| -E | ssh-agent -E <fingerprint_hash> | Specify the hashing algorithm to use to display key fingerprints. Allowed options are “md5” and “sha256” (default). |
These commands are typical when using ssh-agent.
Now, let’s explore some more advanced options:
| Option | Command | Description |
|---|---|---|
| -a | ssh-agent -a /path/to/socket | Specify a UNIX-domain socket that we want the agent to use. By default, it uses a temporary socket. |
| -D | ssh-agent -D | Run the ssh-agent in the foreground, e.g., for debugging. |
| -d | ssh-agent -d | Run the agent in debug mode so that it outputs more information about what’s actually happening. |
| -O | ssh-agent -O “allow-remote-pkcs11” | Turn off two security features. This can lead to security risks and isn’t recommended. The two allowed options are “allow-remote-pkcs11” and “no-restrict-websafe“. |
| -P | ssh-agent -P “usr/lib*/*,/usr/local/lib*/*” | Define the paths including the shared libraries that can be used with the -s option for ssh-add. |
At this point, we’ve seen a typical workflow of ssh-agent and explored most of the options available with the command. Next, let’s discuss agent forwarding which is a useful feature of the ssh-agent.
In brief, agent forwarding is a feature that enables the agent to act on a server we’re already connected to using SSH and automatically authenticate connections that we’re trying to establish from this server. This clever feature lets us leverage the local SSH keys on remote servers, even when we’re connecting through a chain of such connections.
In other words, the ssh-agent creates a secure tunnel to safely transmit the key information from the local machine, eliminating the need to enter the passphrase repeatedly:
Let’s see an example to make things clearer. For instance, if we want to access a private GitHub repository from an EC2 instance, normally, we’d have to store the GitHub private key on the EC2 instance, which isn’t ideal. However, with agent forwarding, the EC2 instance can securely use the local key on the current machine to authenticate with GitHub, keeping the key safe and centralized.
Yet, this feature can also be risky. This is because when we use agent forwarding the servers that transmit the data all get access to all the stored keys in the agent. So, malicious actors can use this to access resources they normally don’t have access to.
Thus, to avoid this, we should follow a few best practices:
This way, we need to enter a password each time the agent authenticates a server. We can set up a password using the ssh-add -x command and remove the password we via ssh-add -X.
In this article. we learned about SSH and ssh-agent. We learned how to use it and the different available options during a regular workflow and advanced setups. Also, we saw why it’s important to be careful when using agent forwarding and what we can do to preserve a secure environment.