HowTo :: SSH access using a GPG key for authentication

Introduction

Replace traditional SSH keys with GPG authentication subkeys, reducing the number of keys to manage while enabling GPG web of trust for SSH access distribution.

What is This About?

Many of us are familiar with Secure Shell (SSH), which allows us to connect to other systems using a key instead of a password. This guide will explain how to eliminate SSH keys and use a GNU Privacy Guard (GPG) subkey instead.

Important clarification: Using GPG does not make your SSH connections more secure. SSH is already a secure protocol, and SSH keys are secure. Instead, this approach provides:

Your SSH workflow remains unchanged - all commands work as expected, except you’ll unlock your GPG key instead of managing separate SSH private keys.

What You’ll Need

Understanding GPG Subkeys

A GPG key is actually a collection of keys, not just one:

Subkeys are separate keys signed by your primary key and transmitted together. This architecture allows you to revoke individual subkeys (e.g., if compromised) while keeping your primary key valid.

For SSH, we’ll create an authentication subkey that completely replaces traditional SSH keypairs generated with ssh-keygen. You can create multiple authentication subkeys if you need different SSH keys for different purposes.

Step-by-Step Guide

Step 1: Create an Authentication Subkey

You’ll create the subkey by editing your existing GPG key in expert mode to access authentication options.

Start the key editing process:

1
gpg2 --expert --edit-key <KEY_ID>

In the GPG prompt, add a new key:

1
gpg> addkey

Select key type 8 (RSA with custom capabilities):

Your selection? 8

Toggle capabilities to enable only Authentication:

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

Your selection? s
Your selection? e
Your selection? a

Current allowed actions: Authenticate

Your selection? q

Choose key size. SSH typically uses 2048-bit, but 4096-bit provides additional security:

What keysize do you want? (2048) 4096

Set expiration. Consider setting an expiration date (e.g., 2 years) as a security best practice:

Key is valid for? (0) 2y

Or choose no expiration if you prefer:

Key is valid for? (0) 0

Confirm your choices and enter your passphrase when prompted. You should see output showing your new authentication subkey (marked with usage: A):

ssb rsa4096/136F0B4E3D42CF31
    created: 2019-03-21  expires: never     usage: A

Save and exit:

gpg> quit
Save changes? (y/N) y

Step 2: Configure gpg-agent for SSH

The gpg-agent program will handle SSH authentication requests instead of ssh-agent.

Enable SSH support in gpg-agent by adding this line to ~/.gnupg/gpg-agent.conf:

1
echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

Verify the configuration:

1
cat ~/.gnupg/gpg-agent.conf

You should see:

enable-ssh-support

Step 3: Pre-configure SSH Keys (Optional)

You can pre-specify which keys to use for SSH to avoid running ssh-add each time.

Find your authentication subkey’s keygrip:

1
gpg2 -K --with-keygrip

Look for the subkey with [A] (authentication) capability:

ssb   rsa2048 2019-03-21 [A]
      Keygrip = 2BE91C3C443AA29C3703D004587AD6DA9D7E40FC

Add the keygrip to sshcontrol:

1
echo "2BE91C3C443AA29C3703D004587AD6DA9D7E40FC" >> ~/.gnupg/sshcontrol

Replace the keygrip above with your actual keygrip value.

Step 4: Configure Shell Environment

Tell SSH how to access gpg-agent by setting the SSH_AUTH_SOCK environment variable.

Add these lines to ~/.bashrc (or ~/.zshrc if using zsh):

1
2
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent

Apply the configuration to your current session:

1
source ~/.bashrc

Or start a new terminal session.

Step 5: Verify the Setup

Check that gpg-agent is providing your SSH key:

1
ssh-add -L

You should see your GPG-based SSH public key printed. The key will have a comment indicating it’s from GPG.

If you see “The agent has no identities,” restart gpg-agent:

1
2
3
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
ssh-add -L

Step 6: Share Your Public Key

Distribute your public key to remote systems just like traditional SSH keys.

Option 1: Manual copy

1
ssh-add -L

Copy the output and manually add it to ~/.ssh/authorized_keys on the remote system.

Option 2: Use ssh-copy-id (recommended)

1
ssh-copy-id user@remote-host

This automatically copies your public key to the remote system.

Step 7: Test SSH Connection

Connect to a remote system as usual:

1
ssh user@remote-host

You should be prompted for your GPG passphrase instead of an SSH key passphrase. After successful authentication, your passphrase will be cached according to your gpg-agent configuration.

Troubleshooting

Key Management Best Practices

Next Steps

Now that you have GPG-based SSH authentication:

  1. Distribute via keyserver - Upload your GPG key to public keyservers so others can fetch your SSH key
  2. Explore Monkeysphere - Visit The Monkeysphere Project to learn about GPG web of trust for SSH
  3. Hardware tokens - Consider using a YubiKey or other hardware token to store your GPG key
  4. Multiple authentication subkeys - Create different subkeys for different systems or purposes
  5. Remove old SSH keys - Once confident in your GPG setup, remove traditional SSH keys: rm ~/.ssh/id_rsa*

Congratulations!

You’ve successfully enabled SSH access using GPG authentication! Your SSH workflow remains identical from a user perspective, but you’ve gained:

Stay safe and practice good key hygiene!

See Also