Skip to content

Instantly share code, notes, and snippets.

@gabriel-lopez
Created March 15, 2026 09:15
Show Gist options
  • Select an option

  • Save gabriel-lopez/f7195c872ddd519e9a74da357a8514f0 to your computer and use it in GitHub Desktop.

Select an option

Save gabriel-lopez/f7195c872ddd519e9a74da357a8514f0 to your computer and use it in GitHub Desktop.

YubiKey SSH Signing Key Setup

1. Generate the FIDO2 resident key on the YubiKey

ssh-keygen -t ed25519-sk -O resident -O application=ssh:<your-username>-signing -O user=<your-username> -C "<your-email>" -f "$env:USERPROFILE\.ssh\id_ed25519_sk_<your-username>-signing"

Key flags:

  • -t ed25519-sk — hardware-backed FIDO2 key
  • -O resident — key material stored on the YubiKey (survives machine wipes)
  • -O application=ssh:<your-username>-signing — labels the credential slot on the key
  • -O user=<your-username> — sets a non-null user handle (required to avoid "user id null" error)
  • -O verify-required — optionally add this if you want PIN required on use

2. Verify the key was created

Get-Content "$env:USERPROFILE\.ssh\id_ed25519_sk_<your-username>-signing.pub"

3. Configure Git to use SSH signing (this repo)

git config gpg.format ssh
git config user.signingkey "$env:USERPROFILE\.ssh\id_ed25519_sk_<your-username>-signing.pub"
git config commit.gpgsign true
git config tag.gpgsign true

Use --global to apply to all repos instead.

4. Set up allowed_signers for verification

New-Item -Force "$env:USERPROFILE\.ssh\allowed_signers" | Out-Null
$pubkey = Get-Content "$env:USERPROFILE\.ssh\id_ed25519_sk_<your-username>-signing.pub"
Add-Content "$env:USERPROFILE\.ssh\allowed_signers" "<your-email> $pubkey"
git config gpg.ssh.allowedSignersFile "$env:USERPROFILE\.ssh\allowed_signers"

5. Add the public key to GitHub

Go to GitHub → Settings → SSH and GPG keys → New SSH key, set type to Signing Key, and paste the contents of id_ed25519_sk_<your-username>-signing.pub.

6. Test it

git commit --allow-empty -m "test signing"
git log --show-signature -1

Troubleshooting

"A resident key scoped to '...' with user id 'null' already exists"

The YubiKey has a leftover credential with a null user handle. Fix with either:

Force overwrite (add -O overwrite-resident and -O user=<name> as shown in step 1).

List credentials:

ykman fido credentials list

Delete a specific credential by ID:

ykman fido credentials delete <credential-id>

Full FIDO2 reset (destructive — deletes ALL FIDO2/WebAuthn credentials):

ykman fido reset

Install ykman if needed:

winget install Yubico.YubiKeyManager
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment