Give every account more than one way back in. In a Node.js relying party, that means a second separately registered authenticator, a set of saved one-time recovery codes, or both, run through a recovery flow that is separate from normal passkey sign-in. Synced passkeys recover many device-loss cases on their own, but they do not cover every user or every failure, so the fallback needs to be designed as deliberately as the passkey itself.
Why a passkey needs a recovery path of its own
A passkey is a WebAuthn public-key credential. Your server stores the credential ID and the public key, while the private key stays inside the authenticator. Nothing on your side can be reset or re-sent to the user. If the private key is gone and the account has no other registered route, recovery has to happen outside WebAuthn, through identity checks you define.
As an Amazon Associate I earn from qualifying purchases.
The W3C Web Authentication Level 4 Working Draft, dated 2026-09-15, states: “Relying Parties SHOULD ensure that each user account has additional authenticators registered and/or an account recovery process in place.” Because this is a working draft that may change before it becomes a Recommendation, treat the sentence as current guidance rather than settled final text. The draft does not prescribe a single recovery ceremony, so the design choices below are yours to make.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Build the registration and authentication lifecycle first
Recovery depends on data your registration and sign-in code already capture, so get those flows right before adding a recovery endpoint. The examples below assume SimpleWebAuthn, whose server documentation identifies version 14.0.x. Function names and option shapes can change between major versions, so check them against the version you install.
#1 Best Overall
- POWERFUL SECURITY KEY: The YubiKey 5C NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5C NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
Registration
- Generate the registration challenge on the server and keep it bound to the session or pending account.
- Verify the returned origin and challenge against what the server issued, and check the relying-party ID.
- Persist the credential ID, public key, signature counter, transports, and device type.
- Persist backup eligibility and backup state when the library returns them (see the backup section below).
Authentication
- Issue options with
generateAuthenticationOptions()and store the challenge server-side for that sign-in attempt. - Verify the response with
verifyAuthenticationResponse(), passing the expected challenge, expected origin, expected RP ID, and the stored credential. - On success, write back the counter the verifier returns.
Counters are a signal, not a guarantee
The counter helps detect some cloned or misbehaving authenticators, but some authenticators legitimately always report zero. A counter that fails to increase should trigger review, not an automatic conclusion that the credential was cloned. Do not present the counter to users or staff as a reliable universal clone detector.
Choose recovery routes by risk
Each option solves a different failure and creates a different takeover risk. The table lists what each route helps with and what it costs.
| Option | What it helps with | Limits and trade-offs |
|---|---|---|
| Synced passkey | A credential manager or platform account can make the same passkey available on several devices. | The user may lose access to the synchronizing account or its own recovery route, so the relying party still needs a plan. Source: SimpleWebAuthn passkey guide (version 14.0.x) and W3C Web Authentication Level 4 Working Draft, 2026-09-15. |
| Additional registered authenticator | A separately registered phone, computer, or hardware security key gives the user another way to authenticate. | It must be enrolled before the loss and kept accessible. It does not restore the lost credential. Source: W3C Working Draft, 2026-09-15; Yubico guidance on FIDO2 security keys. |
| Saved recovery code | Gives a fallback when the user has no usable authenticator. | Codes are bearer secrets. They need high entropy, hashed storage, throttling, invalidation after use, and secure offline storage by the user. Source: NIST SP 800-63B, section 4.2.1, in the SP 800-63-4 series. |
| Issued code or identity recovery | Can help when saved codes and authenticators are both unavailable. | Delivery channels and identity proofing create their own takeover risks, so choose them through a documented risk analysis. Source: NIST SP 800-63-4 series, general account-recovery guidance. |
Compare routes on five things: whether the user can get back in after device loss, how well the route resists account takeover, operational complexity, user burden, and how long recovery takes. No single method is safest in the abstract. A route is only safe relative to a stated threat model, such as a stolen phone, a phished login, or a compromised email inbox.
Recommended Free Tools
Rank #2
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
Saved recovery codes
Recovery codes are the most common fallback to implement yourself, and most of the risk sits in the details. NIST SP 800-63B, section 4.2.1, says saved recovery codes should carry at least 64 bits of randomness, be stored hashed by the verifier, be subject to throttling, and be invalidated and replaced after use. The user should keep them offline and secure.
Generation
Generate each code from a cryptographically secure source. Sixteen random bytes give 128 bits, comfortably above the 64-bit minimum. Show the batch once, at the moment it is created, and make clear that the user must store it offline.
import { randomBytes, createHmac, timingSafeEqual } from "node:crypto";
// 16 random bytes = 128 bits, above the 64-bit minimum in NIST SP 800-63B
export function newRecoveryCode() {
return randomBytes(16).toString("base64url");
}
// One-way verifier-side hash; the secret is kept outside the database
export function hashRecoveryCode(code, serverSecret) {
return createHmac("sha256", serverSecret).update(code).digest();
}
export function recoveryCodeMatches(candidate, storedHash, serverSecret) {
const h = hashRecoveryCode(candidate, serverSecret);
return h.length === storedHash.length && timingSafeEqual(h, storedHash);
}
Storage and throttling
- Store only the hash. Never store plaintext codes, including in logs, admin tools, or support exports.
- Rate-limit recovery attempts per account and per source, and lock or slow the route after repeated failures.
- Compare with a constant-time function, as shown above, so the check does not leak timing information.
Redemption must be atomic and one-time
Two concurrent requests with the same valid code must not both succeed. A conditional update handles this in one statement:
Rank #3
- The information below is per-pack only
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
UPDATE recovery_codes
SET used_at = NOW()
WHERE id = ? AND account_id = ? AND used_at IS NULL;
If the affected row count is zero, reject the attempt. Only proceed to the recovery steps when the update succeeds.
Replacement and notification
After a code is used, invalidate it, issue a replacement, and notify the user through a channel already on the account. The notification should say that a recovery happened and give a path to report it if the user did not initiate it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Make recovery a separate, state-changing flow
Recovery should never be a branch of the passkey assertion endpoint. A backup code is not a WebAuthn assertion, and the server should treat it as a distinct, auditable account event.
Rank #4
- POWERFUL SECURITY KEY: The YubiKey 5C Nano is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C Nano secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: The YubiKey 5C Nano is designed to stay plugged into your device via USB-C. Simply tap it to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
- Start a recovery session that is separate from sign-in, with its own rate limits and audit log entry.
- Verify the recovery credential according to your policy: a saved code, a previously registered authenticator, or an issued-code or identity route.
- Apply any additional checks your risk model requires before enrolling a new passkey, such as a delay, a confirmation sent to existing contact details, or review by staff for high-value accounts.
- Enroll the new passkey through the normal registration flow, with a fresh server challenge.
- Revoke or review old authenticators in proportion to the risk. A user who recovered after suspected theft should not keep the old credential active by default.
- Invalidate the redeemed code, issue a replacement, and send the notification described above.
Backup eligibility is not backup state
Two passkey flags are easy to confuse. Backup eligibility indicates that a credential can be synchronized. Backup state indicates that it has been synchronized. Store both when your library provides them, but do not make public-facing acceptance depend on the backup-state flag. NIST cautions against that dependency. In practice, a credential that is eligible but not yet synced is still a valid credential, and a credential that reports a backup state should not be trusted more or less because of that flag alone.
Troubleshooting recovery branches
- User lost the phone that holds the passkey and has no other passkey. Offer a saved recovery code if one exists. If the user has a second registered authenticator, use that route instead.
- User has no codes and no authenticator. Move to the issued-code or identity route defined by your policy. Expect this to be slower and more expensive to operate.
- User’s synced passkey account is locked or inaccessible. The passkey may be unavailable even though the user still has the device. Treat this as a loss of that synced credential and follow the same route as device loss.
- Counter did not increase. Check whether the authenticator is one that always reports zero before taking any action. If the counter moved backwards on an authenticator that reports one, flag the credential for review.
- Second security key was never registered. It cannot be used for recovery. A key registered after the loss does not restore the lost private key.
What the standards settle and what they leave open
The NIST text on saved recovery codes is specific: “The saved recovery code may be presented as numeric or a printable ASCII representation (e.g., Base64) for manual entry or as a machine-readable optical label (e.g., QR code) that contains the recovery code.” That settles the format question, and it means a QR code is a valid way to present a code, provided it carries the same secret and receives the same protections.
WebAuthn itself leaves the recovery ceremony to the relying party. The draft expects additional authenticators or a recovery process, but it does not define how identity should be re-established. The rest of the design, including which routes to offer, how many codes to issue, and how long a recovery should wait before taking effect, is a product and risk decision that you should record in writing.
Keep the rules in the table, the recovery steps, and the code example in step with the library version you deploy. A WebAuthn library upgrade can change option names or the fields returned by the verifier, and a recovery flow that depends on them should be tested on the new version before it is released.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




