This project is a collection of scripts that help set up a YubiKey to be used for SSH and GPG signing including the signing of git commits. These scripts are for my personal use, but you may find them helpful as well.
  • Batchfile 100%
Find a file
2026-05-08 18:44:52 -07:00
Docs The anti-fascist badge I made is rendering weird on mobile (probably the dropshadow on the text being a pixel value). For now I'm just replacing it with one from https://pride-badges.pony.workers.dev/static/v1?label=anti-fascist&stripeWidth=6&stripeColors=5BCEFA,F5A9B8,FFFFFF,F5A9B8,5BCEFA 2026-05-08 15:33:13 -07:00
Scripts/Windows Initial commit: first pass on YubiKey config scripts to improve the workflow of provisioning multiple YubiKeys for SSH and signing. 2026-05-08 13:28:12 -07:00
LICENSE.md Initial commit: first pass on YubiKey config scripts to improve the workflow of provisioning multiple YubiKeys for SSH and signing. 2026-05-08 13:28:12 -07:00
README.md Adding more troubleshooting steps for being unable to sign commits with git 2026-05-08 18:44:52 -07:00

xo's YubiKey Config

License: CC BY-NC-SA 4.0 Anti-Fascist

This project is a collection of scripts that help set up a YubiKey to be used for SSH and GPG signing including the signing of git commits.

These scripts are for my personal use, but you may find them helpful as well.

Prerequisites

Note: Versions above use the standard Maven version range syntax.

Usage

Must be run as Administrator (required for setting the FIDO2 PIN).

Begin an interactive process of setting up one or more YubiKeys:

.\Scripts\Windows\00-provision-keys.bat

Same as above with colorized output:

.\Scripts\Windows\00-provision-keys-colors.bat

Note: 00-provision-keys-colors will not use colors if a NO_COLOR variable is set.

Using Your Keys on a New Device

Firmware 5.2.3+ (ed25519-sk, resident keys): The key material lives on the YubiKey, not on disk. To use on a new machine:

  1. Install OpenSSH
  2. Plug in your YubiKey and run ssh-keygen -K in an administrator command prompt - this pulls the public key and a stub file down from the key into the working directory. Copy that to ~/.ssh or run the command from there.
  3. Done. SSH will use the YubiKey automatically when it's plugged in.

Firmware [5.1, 5.2.3) (ecdsa-sk, non-resident): The private key stub is written to disk during provisioning, so it won't be on a new machine automatically. Copy ~/.ssh/yubikey-<serial> and ~/.ssh/yubikey-<serial>.pub to the new machine manually. The YubiKey still handles the actual cryptography - the stub just tells SSH where to find it.

Tip: If you aren't sure if a resident key is on your Yubikey you can install ykman run ykman fido credentials list to list the resident keys on your YubiKey.

SSH config

Add entries to ~/.ssh/config to tell SSH which keys to use. List one IdentityFile per YubiKey - SSH will try each in order and use whichever matches the key currently plugged in:

Host *
    IdentityFile ~/.ssh/yubikey-11223344
    IdentityFile ~/.ssh/yubikey-55667788
    IdentityFile ~/.ssh/yubikey-99001122
    IdentitiesOnly yes
    AddKeysToAgent no
  • IdentityFile - path to the key stub written by the provisioning script. The filename is yubikey-<serial> where serial matches what ykman info reports for that key.
  • IdentitiesOnly yes - only try the listed keys, nothing else. Prevents SSH from offering unrelated keys and hitting MaxAuthTries limits.
  • AddKeysToAgent no - the private key never leaves the hardware so there is nothing meaningful to add to the agent.

You can scope entries to specific hosts if needed:

Host github.com
    IdentityFile ~/.ssh/yubikey-11223344
    IdentityFile ~/.ssh/yubikey-55667788
    IdentitiesOnly yes
    AddKeysToAgent no

For GPG signing on a new machine:

  1. Import your public key from the backup directory:
    gpg --import gpg-signing-key.asc
    
  2. Plug in the YubiKey and run gpg --card-status - GPG will detect the card and link it to the imported key automatically
  3. Set trust: gpg --edit-key <fingerprint> -> trust -> 5

The backup directory from provisioning is your recovery point if you ever lose all your YubiKeys - that's the only place private key material exists off-hardware.

Troubleshooting

Git signing fails after switching YubiKeys

The issue: GPG records the serial number of the last card used. When you insert a different YubiKey, GPG can't match it to the key stub.

The fix: Run gpg --card-status to re-sync GPG to whichever card is currently inserted, then retry the commit.

gpg failed to sign the data when comitting

The issue: Git and gpg are not hooked up together properly.

First make sure you can sign using your key. If this doesn't work you need to fix that before you can get gpg hooked up to Git properly:

echo "test" | gpg --clear-sign

This command should require you to enter your PIN and touch your Yubikey. If it doesn't you'll need to check if your key was imported properly (gpg --import gpg-signing-key.asc) before you continue.

Next you'll want to configure git. This guide by GitHub is a good reference.

That might be enough to get them hooked up for you, but if you're running into issues still check that git's version of gpg is the one you're using to run gpg commands. Basically you want the top result when running where gpg to match the value of your git config's gpg.program. An example would be something like:

$ where gpg
C:\Program Files\GnuPG\bin\gpg.exe
C:\msys64\usr\bin\gpg.exe

$ git config --global gpg.program "C:\Program Files\GnuPG\bin\gpg.exe"`

Note: $ in the example above annotates a command to be run. Other lines are the output of the command being run.

OpenPGP PIN rejected on a freshly reset key

The issue: The factory defaults are user PIN 123456 and admin PIN 12345678. If the key was partially set up before, those may have changed.

The fix: Use ykman openpgp reset to restore these defaults before running the provisioning scripts.

I can't use these keys to SSH into Windows

The issue: Windows' OpenSSH server has poor support for authentication methods other than password based auth.

The fix: Unknown. I just skip FIDO2 authentication when accessing Windows via SSH. I either remote in or use password-based authentication.

Future Improvements:

These scripts are meeting my needs at the moment, so although improvements are not a priority these ideas would be considered if requested:

  • Support for bash on Unix-based systems.
  • Improved error handling (although there are some already)
  • Improved self-test steps (although there are some already)
  • Offering the user a clean/reliable setup by...
    • Resetting their YubiKey to factory settings.
    • Setting up their .ssh/config file for them.
  • Improving key comments to help the user with debugging.
  • Programmatically write out helper scripts to...
    • Verify SSH credentials for some domain (ie: ssh -T )
    • Sign and verify the signature of an arbitrary set of input bytes or a file.

Unplanned:

The following changes will not be implemented / are not in the spirit of this project:

  • A port to PowerShell, Python, etc...
  • Tight integration with GitHub or other specific Git services.
  • Support for other brands of hardware keys.
  • Providing a license permitting commercial use.
  • Support setting different PINs per-card.
    • You can just re-start the provisioning process to do that if you want.