This documents the full workflow for setting up SSH authentication with a YubiKey FIDO2 resident key. This is optional: it only applies if you use a YubiKey for SSH.
- YubiKey 5 series or later (must support FIDO2 resident keys)
- OpenSSH 8.2+ (for
ed25519-skkey type) ykman(YubiKey Manager CLI), installed via Homebrew:brew install ykman
The OTP slot on YubiKeys triggers when you accidentally touch the key, pasting a one-time password into whatever has focus. Disable it if you do not use OTP:
ykman config usb -d OTPA FIDO2 PIN is required before you can create resident keys. If you have not set one yet:
ykman fido access change-pinYou will be prompted to enter and confirm a new PIN. This PIN is used for verify-required operations (see below).
ssh-keygen -t ed25519-sk -C "user@domain.tld" -O resident -O verify-requiredWhat the flags do:
| Flag | Purpose |
|---|---|
-t ed25519-sk |
Use the Ed25519 algorithm with a FIDO2 security key |
-C "user@domain.tld" |
Comment to identify the key (use your email) |
-O resident |
Store the key handle on the YubiKey itself, making it portable between machines |
-O verify-required |
Require PIN entry on each use, not just a physical touch |
This creates two files:
~/.ssh/id_ed25519_sk: the private key stub (a reference to the key on the YubiKey, not the actual private key)~/.ssh/id_ed25519_sk.pub: the public key (add this to GitHub, servers, etc.)
Because the key is resident (stored on the YubiKey), you can regenerate the key stub on any machine:
ssh-keygen -KThis downloads all resident credentials from the YubiKey into the current directory as id_ed25519_sk_rk* files. Move them to ~/.ssh/ and set permissions:
mv id_ed25519_sk_rk* ~/.ssh/
chmod 600 ~/.ssh/id_ed25519_sk_rk
chmod 644 ~/.ssh/id_ed25519_sk_rk.pubA single YubiKey is a single point of failure. If you lose it, you lose SSH access to every service that only has that key registered.
Options:
- Two YubiKeys: generate a resident key on each, register both public keys everywhere. Keep the backup in a safe location.
- Fallback key type: keep a traditional
ed25519key (encrypted, stored securely) as a break-glass credential registered on critical services. - GitHub recovery codes: always save your GitHub account recovery codes separately from your YubiKey.
- Rotate your FIDO2 PIN periodically. Use
ykman fido access change-pinto change it. - List registered credentials with
ykman fido credentials listto audit what is stored on the key. - Delete credentials you no longer use:
ykman fido credentials delete <credential>. - If a YubiKey is lost or compromised, remove its public key from all services and revoke it from your GitHub account immediately.
| Mode | What happens on use |
|---|---|
| Touch-only (default) | YubiKey blinks, you touch it, authentication proceeds |
verify-required |
YubiKey blinks, you enter your FIDO2 PIN, authentication proceeds |
verify-required is stronger: a stolen YubiKey cannot be used without the PIN. The tradeoff is that you type the PIN on every SSH operation (git push, scp, ssh, etc.).