Password-based SSH authentication has a straightforward weakness: the credential lives in memory, in a file, or in a human brain, and any of those can be compromised remotely. A hardware security key keeps the private key material inside a tamper-resistant chip that never exposes it to the operating system, which means a remote attacker who fully owns your session still cannot extract the key and use it elsewhere.
What You Need Before Starting
OpenSSH 8.2 or later is required to support FIDO2 hardware authenticators. Most current Linux distributions ship a version that qualifies — Debian 11, Ubuntu 20.04 LTS, Fedora 33, and Arch Linux rolling releases all meet this threshold. You can confirm your version by running ssh -V in a terminal.
You also need a FIDO2-capable security key. The YubiKey 5 series, Google Titan (USB-A variant), and SoloKeys Solo 2 all support the FIDO2 standard. Older keys that only support U2F or FIDO1 will not work with the SSH key types covered here. Some older YubiKey models, such as the YubiKey 4, support OpenPGP and PIV but not FIDO2, so confirm your model before proceeding.
On most Linux systems you will need to install the libfido2 library to give OpenSSH the ability to communicate with the key over USB. On Debian and Ubuntu, that package is libfido2-dev or libfido2-1 depending on whether you need runtime or development files. Fedora and RHEL users install libfido2. After installation, verify detection with the fido2-token -L command, which should list your connected key.
One more step before generating keys: udev rules. Without them, USB access to the key requires root. The libu2f-udev package (Debian/Ubuntu) or the fido2 udev rules from the libfido2 upstream repository will create the necessary device permissions for your user. After installing, unplug and replug the key, then rerun fido2-token -L as a normal user to confirm access.
Generating an SSH Key Backed by the Hardware Token
OpenSSH supports two FIDO2 key types: ecdsa-sk and ed25519-sk. The -sk suffix indicates that the private key operation is performed inside the security key rather than in software. Between the two, ed25519-sk is preferred because Ed25519 offers stronger security properties than ECDSA at equivalent key sizes, and the underlying curve is not susceptible to the weak random number generation vulnerabilities that have historically plagued ECDSA implementations.
To generate an ed25519-sk key pair, run:
ssh-keygen -t ed25519-sk -C "your@email.com"
OpenSSH will prompt you to touch your security key to confirm the operation. This touch requirement is enforced in hardware — the key will not sign anything without physical interaction, which prevents malware from silently using the key while it is plugged in. A PIN prompt may appear first if your key has FIDO2 PIN protection enabled, which YubiKeys support via the ykman fido set-pin command.
The output is a standard key pair: a private key file (by default ~/.ssh/id_ed25519_sk) and a public key file (~/.ssh/id_ed25519_sk.pub). The “private key” file is actually a handle — it contains a credential ID and some metadata that the security key uses to reconstruct the signing context, but it does not contain extractable private key material. Losing this file means losing access to that credential, so back it up alongside the security key itself.
Discoverable vs. Non-Discoverable Credentials
FIDO2 supports two credential storage modes. By default, ssh-keygen creates a non-discoverable credential, meaning the handle file on disk is required at authentication time. Adding the -O resident flag creates a discoverable credential (also called a resident key), stored entirely on the security key itself. With a resident credential, you can retrieve the handle on any machine using ssh-keygen -K after touching the key. YubiKey 5 series devices support up to 25 resident credentials. This mode is useful when authenticating from machines where you cannot store the handle file, but it also increases the sensitivity of the physical key — anyone holding the key could extract the public handle.
Configuring the Server and Client
Copy the public key to your remote server as you would with any SSH key:
ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub user@remote-host
Or manually append the contents of id_ed25519_sk.pub to ~/.ssh/authorized_keys on the server. The public key format is identical to a standard Ed25519 key except the type string reads sk-ssh-ed25519@openssh.com, which tells the server to expect a FIDO2 signature.
On the server side, ensure PubkeyAuthentication yes is set in /etc/ssh/sshd_config. No additional configuration is required specifically for FIDO2 keys — the server validates the signature format automatically when using OpenSSH 8.2 or later. If you want to enforce that only hardware-backed keys can authenticate, you can use the no-touch-required option to control touch behavior, or conversely restrict authorization by key type using AuthorizedKeysFile combined with careful key management practices.
On the client side, if you have multiple keys, specify which one to use in ~/.ssh/config:
Host remote-host
IdentityFile ~/.ssh/id_ed25519_sk
User youruser
When you initiate an SSH connection, OpenSSH will ask you to touch the security key. The LED on the key will flash, you touch it, and the authentication completes. The touch verification happens every time, which is by design.
Requiring a PIN on Every Use
By default, a FIDO2 key does not require a PIN to perform signing — just a touch. You can enforce PIN verification at the key level using ykman fido access change-pin for YubiKeys, and then regenerate your SSH key with the -O verify-required flag:
ssh-keygen -t ed25519-sk -O verify-required -C "your@email.com"
This embeds a flag in the credential that instructs the authenticator to demand PIN verification before signing, regardless of what the client requests. The result is two-factor authentication within the SSH flow itself: something you have (the physical key) and something you know (the PIN). The PIN is verified by the hardware device directly and never transmitted to the remote server.
Handling Key Loss and Backup Planning
A hardware security key is a single point of failure by design. If it breaks or is lost and you have no backup, you lose SSH access to every server where that key is authorized.
The practical solution is to enroll a second security key as a backup. Generate a second ed25519-sk key pair using a different physical key and add its public key to authorized_keys on every server you manage. Store the backup key somewhere physically secure and separate from your primary. Some administrators also keep a traditional Ed25519 software key locked away for emergency access, protected with a strong passphrase and stored on encrypted offline media. OpenSSH does not force you to use only hardware keys, so a mixed authorized_keys file with both hardware-backed and passphrase-protected software keys is a valid operational posture — the risk trade-off is explicit and deliberate rather than accidental.
The fido2-token -I /dev/hidraw0 command will display device information including the AAGUID, which uniquely identifies the authenticator model. Keeping a record of the AAGUID alongside your key serial number helps confirm which physical device a credential belongs to when auditing access across many servers.