I’m writing this post to document my experience with SSH security keys, specifically when trying to make SSH keys resident on compatible FIDO2 tokens.

What finally pushed me to write it was frustration. Almost every article, guide, or walkthrough I came across assumed you were using a YubiKey 5C. I understand why. They are excellent devices. They work reliably, the tooling is mature, and the documentation is generally good.

They are also expensive.

In the UK, a YubiKey 5 series token is roughly fifty pounds. If you are doing this properly, you are not buying one. You are buying at least two. More realistically, you end up with several. Two for work, two for home, two for side projects, maybe another pair for redundancy. Before long, the cost stacks up and you are physically carrying far more keys than intended. I only recently separated my work, home, car, and observatory keys and that alone felt like progress.

This is not a criticism of YubiKeys. It is an attempt to remove the vendor tunnel vision and talk about what actually matters if your goal is resident SSH keys.


Why you would want to do this at all

Resident SSH keys solve dull but serious problems.

Traditional SSH relies on private key files living on disk. Even with passphrases, they get copied into backups, forwarded between machines, and left behind on systems you no longer fully trust. Over time, key sprawl is inevitable.

A resident SSH key flips that model.

The private key is generated inside the hardware token and never leaves it. There is nothing to copy, nothing to back up, and nothing for malware to quietly steal. Authentication becomes physical. You are present, you touch the device, and the cryptographic operation happens inside the token.

That has very real consequences.

Losing a laptop is no longer a key compromise
Backups stop containing long lived secrets
SSH agent forwarding becomes less dangerous
Key rotation becomes device based rather than file based

For anyone running servers, clusters, or long lived infrastructure, this is a genuine improvement.


FIDO standards without the fog

FIDO UAF was the original passwordless effort and is irrelevant here.

FIDO U2F is widely used for web MFA but does not support resident credentials. A U2F only device cannot store SSH keys.

FIDO2 is the one that matters. It supports resident credentials stored directly on the token and is what modern OpenSSH uses for hardware backed elliptic curve SSH keys.

If a device is not truly FIDO2 compliant, it will not work for this.


What a resident SSH key actually is

With a recent OpenSSH release, you can generate an Ed25519 SSH key that lives entirely on a FIDO2 token.

The private key never exists as a file. SSH sends a challenge, the token signs it internally, and returns the signature. Presence is enforced by touch and optionally a PIN.

If the host is compromised, there is nothing useful to steal.


How to create a resident EC SSH key on a FIDO2 device

This is the part most posts get wrong by being vendor specific. The steps below apply to any compatible FIDO2 token.

Prerequisites

You need:

A FIDO2 hardware key that supports resident credentials
OpenSSH 8.2 or newer
A system with working USB or NFC access

You can check your OpenSSH version with:

ssh -V

If you are below 8.2, stop here and upgrade.


Step 1: Insert your FIDO2 security key

Make sure only one FIDO2 token is inserted to avoid ambiguity.

If your token supports a PIN and does not yet have one set, OpenSSH will prompt you to create it during key generation.


Step 2: Generate a resident Ed25519 key

Run the following command:

ssh-keygen -t ed25519-sk -O resident -O verify-required -C "your comment here"

What this does:

-t ed25519-sk tells OpenSSH to use a FIDO backed elliptic curve key
-O resident stores the private key on the hardware token
-O verify-required enforces touch or PIN verification
-C sets a human readable comment

You will be prompted to touch the device and possibly set or enter a PIN.

The key is generated inside the token.


Step 3: Understand what gets written to disk

Despite using a resident key, two files are still created locally:

id_ed25519_sk
id_ed25519_sk.pub

The important point is this:

The private key file does not contain the private key.

It contains a reference to the hardware token and metadata. Losing this file is annoying but not a security event. The actual secret remains on the device.


Step 4: Load the resident key into ssh agent

Start the agent if needed:

eval "$(ssh-agent)"

Then load resident keys from the token:

ssh-add -K

This tells the agent to query the FIDO2 device for resident credentials.

You should see the key appear when running:

ssh-add -l

Step 5: Deploy the public key

Copy the public key to your server as normal:

ssh-copy-id user@host

Or manually append it to ~/.ssh/authorized_keys.

From the server’s point of view, nothing special is happening. It sees a normal Ed25519 public key.


Step 6: Test authentication

Connect as usual:

ssh user@host

You should be prompted to touch the device. No private key file is accessed. The signature happens on the token.


Notes and gotchas

Not all FIDO2 tokens support multiple resident keys
Some tokens have storage limits
Model selection matters more than brand
Firmware quality varies

If a device claims FIDO2 support but fails here, it often means it only supports non resident credentials.


Bitwarden as an interesting option

Bitwarden is not a hardware vendor, but it is relevant in this space.

Bitwarden can generate and store elliptic curve SSH keys as software secrets inside the vault. These are not hardware resident keys, but they are far better managed than loose private key files.

Bitwarden also supports FIDO2 hardware keys for MFA. That means access to your SSH keys can be protected by physical presence even if the keys themselves are software based.

This is not the same security model as resident SSH keys, but it is a useful middle ground and often a pragmatic compromise.


The can of worms this opens

Once you start down this road, it rarely stops at SSH.

You quickly end up looking at PIV slots, GPG keys, X.509 certificates, smartcard workflows, and passkeys. You start asking why SSH, email, code signing, VPNs, and web authentication all use different mechanisms when the same hardware could anchor them.

That is very much a can of worms, and it is one I am still investigating.

Resident SSH keys are usually the gateway. They are concrete, immediately useful, and expose the larger question of how much of your digital identity should live on disk and how much should live in hardware.


The bigger picture

YubiKeys are excellent. They deserve their reputation. But they are not unique.

The standards have matured, OpenSSH has caught up, and there is now a broader ecosystem of capable hardware. That lowers the cost of doing SSH properly and removes the sense that secure practice is a luxury purchase.

Security improves when good practice is boring, repeatable, and affordable. Resident SSH keys are finally at that point.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.