SSH agent forwarding is a technique you can use to make deploying to a remote server simpler for you and your developers. It allows you to use you local SSH keys instead of leaving passphrase-less keys sitting on your server.

What is this fancy thing?

If you've already set up an SSH key, you're probably familiar with ssh-agent. This is an app that runs in the background and keeps your key loaded into memory so you do not have to enter your passphrase every time you need to use the key. The nifty thing is, you can selectively let remote servers access your local ssh-agent as if it was running on the server. This is sort of like asking a friend to enter their password so you can use their computer.

Check out Steve Friedl's Tech Tips guide for a detailed explanation of SSH agent forwarding.

Getting things working

First and foremost, ensure you have your local SSH key set up and working. You can use this guide if you've not done this yet. You can test that your local key works by running ssh -T git@github.com.

ssh -T git@github.com
# Attempt to SSH in to github
# Hi username! You've successfully authenticated, but GitHub does not provide
# shell access.

We're off to a great start. Let's set up SSH to allow agent forwarding to your remote server. Open up the file at ~/.ssh/config in your text editor. If it doesn't exist, create it by running touch ~/.ssh/config. Add the following section, replacing example.com with your server's domain name or IP.

Host example.com
  ForwardAgent yes

Warning: You may be tempted to use a wildcard like Host * to just apply this setting to all SSH connections. That's not really a good idea, as you'd be sharing access to your local SSH keys with every server you SSH to. They won't have direct access to the keys, but they will be able to use them while the connection is established. You should only add servers you intend to use agent forwarding with.

Test it out

To test that agent forwarding is working with your server, you need to SSH in and run the ssh -T git@github.com command on the server. If all is well, you'll get back the same prompt as you do locally. If you are unsure if your local key is being used, you can inspect the SSH_AUTH_SOCK variable:

echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
# /tmp/ssh-4hNGMk8AZX/agent.79453

If the variable is not set, agent forwarding is not working:

echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
# [No output]
ssh -T git@github.com
# Try to SSH to github
# Permission denied (publickey).

Troubleshooting

SSH keys must work locally

Before you can make your keys work through agent forwarding, they must work locally first. Check out this guide for help setting up your local SSH keys

Local SSH must allow forwarding

Not only do you need to enable agent forwarding in your user's SSH config (see above), but you may need to set it in your system's SSH settings as well. You can check if a system config file is being used by running ssh -v example.com and checking the first few lines of the output. Make sure you use your server's domain name or IP, of course.

ssh -v example.com
# Connect to example.com with verbose debug output
# OpenSSH_5.6p1, OpenSSL 0.9.8r 8 Feb 2011
# debug1: Reading configuration data /Users/you/.ssh/config
# debug1: Applying options for example.com
# debug1: Reading configuration data /etc/ssh_config
# debug1: Applying options for *

Don't forget to exit to return to your local system!

In the example above, the file ~/.ssh/config is loaded first, then /etc/ssh_config. We can inspect that file to see if it's overriding our options.

cat /etc/ssh_config
# Print out the /etc/ssh_config file
Host *
  SendEnv LANG LC_*
  ForwardAgent no

What do we have here? Our system settings file is overriding the ForwardAgent setting. We can edit this file and remove that line.

Server must allow forwarding on inbound connections

Agent forwarding may be blocked on the server's side. Make sure AllowAgentForwarding is set in sshd_config

Your local ssh-agent must be running

On most systems the OS will automatically launch ssh-agent for you. On windows, however, you need to do this manually. Check out this guide for details on how to run ssh-agent automatically when you open Git Bash.

To check to see if ssh-agent is running, inspect the SSH_AUTH_SOCK variable:

echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
# /tmp/launch-kNSlgU/Listeners

Your key must be available to ssh-agent

You can check with:

ssh-add -L

And if no identity is available:

ssh-add yourkey

Related documentation