GPG Key with SSH Support
A single GPG primary key can certify three separate subkeys for signing, encryption, and authentication. Using an authentication subkey with SSH eliminates the need for a separate SSH keypair — the same OpenPGP key that signs Git commits and encrypts email also logs you into servers.
The workflow below creates a locked-down, single-purpose key hierarchy: an offline primary certification key and three rotated subkeys (sign, encrypt, authenticate). The 13-month expiration provides a one-month renewal window.
Create the primary key
gpg --expert --full-generate-keyInteractive choices:
- Key type:
ECC (set your own capabilities) - Capabilities: Toggle Sign off (
S), then finish (Q)- The primary key should only certify; signing is delegated to a subkey.
- Curve:
Curve 25519 - Expiration:
13m(13 months) - Name: Your real name
- Email: Primary email address
- Comment: Leave empty — comments leak metadata and are unnecessary.
Edit the key and add subkeys
gpg --expert --edit-key $KEYIDAdd UIDs
adduid
Enter name and email; leave comment empty. Repeat for each identity you want certified.
Add a signing subkey
addkey
- Type:
ECC (sign only) - Curve:
Curve 25519 - Expire:
13m
Add an authentication subkey
addkey
- Type:
ECC (set your own capabilities) - Toggle Sign off (
S) - Toggle Authenticate on (
A) - Finish (
Q) - Curve:
Curve 25519 - Expire:
13m
Add an encryption subkey
addkey
- Type:
ECC (encrypt only) - Curve:
Curve 25519 - Expire:
13m
Save
save
Remove the primary key for offline storage
The primary key is only needed to certify new subkeys, add UIDs, or extend expirations. Keep it offline; the subkeys handle day-to-day operations.
# Export everything
gpg --armor --export-secret-key $KEYID > $KEYID.asc
gpg --export-secret-subkeys $KEYID > subkeys.gpg
# Delete all secret keys from the local keyring
gpg --delete-secret-keys $KEYID
# Re-import only the subkeys
gpg --import subkeys.gpg
# Verify
gpg --list-keys
gpg --list-secret-keys
# Cleanup
rm subkeys.gpgStore $KEYID.asc on an encrypted, offline drive. You will need it to rotate subkeys next year.
Export the authentication subkey to SSH
-
Find the authentication subkey’s keygrip:
gpg --list-secret-keys --with-keygripLook for the subkey marked
[A]. -
Add the keygrip to
~/.gnupg/sshcontrol(one per line):# ~/.gnupg/sshcontrol 0123456789ABCDEF0123456789ABCDEF01234567 -
Ensure
gpg-agentis configured to emulatessh-agent:# ~/.gnupg/gpg-agent.conf enable-ssh-supportThen restart the agent:
gpgconf --kill gpg-agent -
Export the SSH public key:
gpg --export-ssh-key $KEYID > ~/.ssh/id_${KEYID}.pub -
Use it:
- Reference with
IdentityFile ~/.ssh/id_${KEYID}.pubin~/.ssh/config - Or append the contents to a host’s
~/.ssh/authorized_keys
- Reference with
Note: The
IdentityFilepoints to the public key file when using gpg-agent; the private key material stays in GPG’s keyring.
Operational notes
- Rotation: Subkeys expire in 13 months. Before expiry, import the offline primary, extend subkey expirations (
gpg --expert --edit-key $KEYID, thenexpirefor each subkey), re-export subkeys, delete local secrets, and re-import. - Revocation: Generate a revocation certificate when the primary is created and store it offline with the primary key.
- Backup:
$KEYID.ascis a full backup of all secret keys. Guard it accordingly. - Git: Git can use the GPG authentication subkey for SSH transport and the signing subkey for commit signing — see git-on-windows-sshcommand for Windows-specific quoting issues.
See also
- python — scripting language often used with GPG for automation
- shell-stabilization — SSH connections often need stabilization too