kkeyroost

Learn · FIDO2

FIDO2, WebAuthn & passkeys

The modern, phishing-resistant way to sign in — as a second factor or as a full replacement for passwords.

keyroost screenshot — The FIDO2 tab: PIN state, unlock, and CTAP 2.1 security policy.
The FIDO2 tab: PIN state, unlock, and CTAP 2.1 security policy.

How it works (and why it can't be phished)

When you register a key with a site, the key generates a fresh keypair just for that site and hands over only the public half. To log in, the site sends a challenge; the key signs it — but only after checking that the request really came from the origin it registered with. A look-alike phishing domain produces a different origin, so the key simply won't sign. There's no shared secret to steal, type into a fake page, or leak in a breach.

The pieces: WebAuthn is the browser ↔ website API, CTAP is the browser ↔ key protocol, and FIDO2 is the two together. U2F is the older second-factor-only predecessor.

Second factor vs. passkey

The same key can play two roles:

A passkey stored on a hardware key is a device-bound passkey: it stays on the fob and doesn't sync. The phones-and-cloud passkeys you've seen sync across your devices for convenience. Same WebAuthn standard — different storage and recovery trade-offs. A key holds a limited number of discoverable credentials, so it's normal to mix passkeys for a few high-value accounts with second-factor use elsewhere.

Tip

Register two keys on every account that matters, and save the site's recovery codes offline. A passkey is wonderful right up until you're at a login box without the key.

The FIDO2 PIN

Many operations (especially passkeys) require a PIN you set on the key. It's worth being clear about what it is and isn't:

Don't put your PIN in a command line

With keyroost, a PIN comes from a hidden prompt in your terminal, or in a script from --pin env:NAME or --pin stdin — never as a plain argument, and the tool never prints or stores it.

What keyroost does with FIDO2

k

Enumerate authenticators and read authenticatorGetInfo; check PIN retries; set / change the PIN and unlock with it; list, inspect, and delete resident credentials; enroll, rename and delete fingerprints; set CTAP 2.1 policy (Always require user verification, CLI fido config always-uv; minimum PIN length, forced PIN change, enterprise attestation); read and manage the key's largeBlob store and extract a stored OpenSSH certificate; and reset a key. Read-only inspection needs no PIN.

In the desktop app, keyroost reaches FIDO2 keys over USB-HID and over NFC / PC-SC readers. Tap an NFC key to a contactless reader and the same operations work, so a key with no USB plug (or one you'd rather not insert) can still be inspected and managed. On the command line, FIDO2 commands use USB-HID; fido info --reader and fido reset --reader also work with a card in a reader.

In the app, the FIDO2 tab's management views sit behind one unlock. Once you enter the PIN, capability-gated sub-view tabs appear for whatever the key advertises: Passkeys (resident credentials), Fingerprints on biometric keys (see Fingerprints), and Storage for the key's largeBlob area (see Storage) — a key that doesn't advertise one of those simply gets no tab for it. Settings is always present on a CTAP2 key: it carries the FIDO2 reset (a baseline CTAP2 command) as well as the security-policy controls such as Always require user verification and minimum PIN length, which appear only when the key advertises authnrCfg and lists that setting in its getInfo (see Settings). Locking returns to the gate and clears the session for all of them. Until the key is unlocked (for example when the PIN is forgotten or blocked), the reset is shown on its own, so a key can always be reset without its PIN.

keyroostctl fido info
keyroostctl fido pin status
keyroostctl fido credential list               # asks for the PIN (hidden)
keyroostctl fido credential delete <hex>       # asks y/N, then for the PIN
keyroostctl fido credential list --pin env:KR_PIN   # in a script: PIN from a variable
keyroostctl fido reset                          # asks y/N, then waits for a replug and a touch

Deleting a credential or fingerprint and resetting name the key and ask y/N first. A script has no terminal to ask on, so it adds --yes (-y); so does a command whose PIN is piped in with --pin stdin. fido reset on a USB key then asks you to unplug it and plug it back in within 60 seconds (keyroost notices the replug itself), checks it is the same key, and asks for a touch.

On Windows

Windows reserves direct FIDO access for elevated processes, so managing a key needs administrator rights. keyroost detects an unprivileged session and offers to open Windows' built-in security-key settings or relaunch itself as administrator.

Privacy

A credential listing reveals which services you have accounts with — treat it as private and don't run it speculatively.

Authoritative resources

From the command line: see Passkeys (FIDO2) on the Command line page.