Build1 publisher3 min readPublished
Passkeys trade portability for phishing resistance by keeping the private key on the device
FIDO's export format for passkeys has only begun shipping in iOS 26 and Android, with the FIDO Alliance counting 5 billion passkeys in use. The key that makes them phishing-resistant cannot be copied off the device, so adopters need a plan for lost devices and changed managers.
The Engineer · Build desk

What happened
- Each passkey is a key pair for one site, and the server keeps only the public key, so a leaked database holds nothing an attacker can log in with.
- Hardware security keys never export a passkey, by design.
- The protocol that sits beside FIDO's credential exchange format is still a working draft.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision Teams issuing hardware keys have to enrol a second credential per user up front, because a lost key takes with it a passkey that was never exportable.
- constraint While the exchange protocol is in draft, a support desk cannot promise users a supported move between password managers, so recovery flows must handle re-registration.
- exposure Part of the phishing defence runs in server code, so a team hand-writing its verifier takes on the exact-origin and single-use challenge checks itself.
The line that turns a WebAuthn credential into a passkey is `residentKey: "required"` [10]. It requests a discoverable credential, one the device can find without the site sending a username first [10]. Leave it out and you have an old-style second factor [10]. Beside it, `alg: -7` selects ES256, ECDSA on the P-256 curve [11]. The authenticator then makes a new key pair for that one site and returns a public key and a credential id for the server to store [12].
Sign-in is one signature over the authenticator data and a SHA-256 hash of a small JSON object called `clientDataJSON` [13]. The `origin` field in that object comes from the browser. It reads the address it actually loaded and checks it against the relying-party id before the authenticator signs [2]. Script on the page cannot set the field [2]. On a look-alike domain the user either has no passkey at all or gets a signature bound to the wrong origin, and the real server rejects it [3].
The server's half is three comparisons: the type is `webauthn.get`, the challenge equals the fresh, single-use value held in the session, and the origin matches exactly [14]. I'd use a maintained verification library for these. The source presents its own version as a simplified sketch, not a complete verifier [14].
Portability breaks on the same property. The private key cannot be read, so it cannot be copied out [6]. A phishing page has nothing to collect, and a user changing password managers has nothing to carry [6].
In my view, a rollout should treat each passkey as tied to the device or manager that created it. The server already stores a public key and credential id per registration [12], so a backup hardware key or a second laptop is one more registration. For hardware-key users, that second registration is the recovery plan, because the first credential will never leave its key [9]. For users on synced managers, recovery should still assume re-registration until the exchange protocol is finished [8].
Microsoft's sign-in figure describes Microsoft's users. Its 98% success rate for passkeys against 32% for passwords [5], inverted, gives failure rates of 2% and 68%, a 34-fold difference [1]. The source does not describe the population or the fallback flows behind the measurement. The ratio carries over to another team only if its password and passkey failure rates look like Microsoft's.
A post titled "I don't like passkeys" spent a day at the top of Hacker News with 616 points and 605 comments [15]. On Hacker News, kenrick95 wrote [16]: "Passkeys have a marketing problem where no one is able to describe simply what it is." The spec's older term was "discoverable resident credential," and the source gives that as the reason Apple, Google and Microsoft renamed it in 2022 [17].
What to watch
- The credential exchange protocol moving from working draft to a finished specification, which would let teams document manager-to-manager migration for users.
- Password managers beyond the iOS 26 and Android implementations shipping FIDO's credential exchange format.
- Microsoft publishing the user population and fallback flows behind its 98% passkey sign-in success figure.