Synopsis #
ssh-keygen(1)
can create FIDO authenticator-backed SSH keys. The authenticator retains private key material and normally requires a physical touch for each signature. OpenSSH supports ecdsa-sk and ed25519-sk key types.
A non-resident credential stores a key handle in the local private-key file. Both that file and the authenticator are required. A resident credential stores the key handle on a FIDO2 authenticator and can be recovered to another client, but a stolen authenticator may expose more usable credential material.
Maintain a separate tested recovery credential. A hardware token can be lost, damaged, reset, or unavailable.
Check the Authenticator #
Attach one authenticator to the OpenBSD client. OpenSSH uses internal USB HID support by default and can select a fido(4) device without an external provider.
Confirm that the kernel attached the device:
$ dmesg | grep '^fido'
Device support and token capabilities vary. If ed25519-sk enrollment is rejected, try ecdsa-sk, which is supported by a wider range of authenticators.
Create a Non-Resident Credential #
Generate a credential on the client:
$ ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk
Touch the authenticator when prompted. Protect the local key-handle file with a passphrase when practical.
Inspect the public-key fingerprint:
$ ssh-keygen -lf ~/.ssh/id_ed25519_sk.pub
The file without .pub is not a conventional exportable private key, but it remains sensitive because it contains the handle needed to use the authenticator.
Install and Test the Public Key #
Append the .pub file to the server account’s ~/.ssh/authorized_keys using an existing authenticated connection:
$ ssh admin@server.example.com 'umask 077; mkdir -p .ssh; cat >> .ssh/authorized_keys' < ~/.ssh/id_ed25519_sk.pub
Test the security key explicitly:
$ ssh -o IdentitiesOnly=yes -o PreferredAuthentications=publickey \
-o PasswordAuthentication=no -o KbdInteractiveAuthentication=no \
-i ~/.ssh/id_ed25519_sk admin@server.example.com
OpenSSH should request a touch when it signs the authentication challenge. Keep the existing recovery session open until this succeeds.
Require User Verification #
Some FIDO2 authenticators can require a PIN for user verification when producing each signature. Generate such a key with:
$ ssh-keygen -t ed25519-sk -O verify-required -f ~/.ssh/id_ed25519_sk_verify
Not every authenticator supports this option. Test the actual client, token, and server combination before depending on it.
Create a Resident Credential #
Set a PIN on the authenticator using its supported management procedure before creating a resident key. Then enroll the resident credential:
$ ssh-keygen -t ed25519-sk -O resident -O verify-required -f ~/.ssh/id_ed25519_sk_resident
To recover resident credentials on another trusted OpenSSH client, create an empty private directory and run ssh-keygen -K there:
$ mkdir -m 700 ~/recovered-fido-keys
# Create a protected destination
$ cd ~/recovered-fido-keys
# Avoid overwriting existing key files
$ ssh-keygen -K
# Download resident key handles from the touched authenticator
Inspect the recovered public keys and fingerprints before use. Do not assume the generated filenames identify the correct account.
Enroll a Backup Credential #
Repeat enrollment with a second authenticator and add its public key as a separate authorized_keys line. Test the backup token from a new client session.
Store the backup token separately from the primary token. Record which public-key fingerprint belongs to each device. Remove the corresponding authorized_keys line immediately after a token is lost or retired.
Operational Limits #
- Touch confirms user presence, not the identity of the person touching the device.
verify-requiredadds user verification only when the authenticator supports it.- A non-resident token alone is insufficient without its local key-handle file.
- A resident credential improves portability but increases the consequences of token theft.
- Disabling all other credentials before the backup token is tested can cause lockout.
See Configure Secure Remote Access with OpenSSH for server policy, PF exposure, logging, and recovery.