Passkeys vs Traditional MFA.
"MFA" was a strategy, not a primitive. Passkeys are the primitive. Origin binding, hardware boundary, no replayable secret. Here is what changes for an enterprise that takes phishing-resistance seriously.
Why “MFA” was a strategy, not a primitive
Multi-factor authentication started life as a deployment posture: the user presents two of something they know (password), something they have (OTP token, phone), or something they are (fingerprint). The factors were chosen for what they were not — not just a password — rather than for any cryptographic property the combination provided. By the late 2010s, this taxonomy was clearly broken. Push fatigue was an industrial issue; SS7 made SMS exfiltrable at scale; TOTP codes were typed by users into phishing pages within seconds of generation.
Passkeys are a different category of object. They are not "an additional factor". They are a cryptographic credential bound to a relying-party origin and stored in hardware. The question stops being "how many factors did the user present?" and becomes "what does the cryptographic ceremony actually prove?". Once you sit with that shift, the operational consequences cascade.
This post is the engineering version of that shift. Where do passkeys win, where do they not, and what does an honest deployment look like for an enterprise that has been running TOTP or push for half a decade.
The three factors, re-examined
Knowledge factor: passwords
Passwords have a single root failure mode: they are reusable and observable. Users reuse them across sites; once leaked at one site, they are usable at others. Phishing pages capture them in real time; humans cannot reliably distinguish a legitimate origin from a homoglyph attack. Server breaches publish them in dumps; even hashed-and-salted, GPU-accelerated cracking handles the long tail. There is no future where the password is the load-bearing primitive in workforce or consumer identity.
Possession factor: OTP / push
The classical second factor was meant to address password reuse. It does, partially. An OTP code generated from a TOTP seed and entered into a login page raises the bar — an attacker needs both the password and the TOTP seed (or a fresh OTP) to log in. SMS variants are weaker still, exposing the OTP delivery to telco interception.
The fundamental problem with OTP and push: they remain bearer tokens that the user can hand over. A phishing site that proxies a real auth flow can ask for a password, ask for a TOTP code, get both within the OTP's 30-second window, and complete a successful login on the back end. AdversaryInTheMiddle (AITM) toolkits like Modlishka, Evilginx, and Muraena have been off-the-shelf for years.
Push doesn't solve this either. Push fatigue (Microsoft documented multi-thousand-push attacks succeeding because users tap "approve" reflexively) and push interception via stolen Apple/Google credentials are both well-documented attack patterns.
Inherence factor: biometrics on the server
Biometric matching that happens on a server is a strictly worse design than biometric matching that happens locally. Server-side matching means the biometric template lives in a database; a breach exposes it; biometrics are not rotatable. It also means the network sees the authentication primitive, with all the AITM consequences that implies.
Local biometric matching, where the device's secure element verifies the user and emits an authenticator-internal user-verified flag, sidesteps both. Passkeys take the local-matching path. The biometric never leaves the device.
The passkey shift — what changes
Passkeys are public-key credentials. The private key never leaves the authenticator (hardware token, smart card, TPM, secure enclave). The relying party stores only the public key. Authentication is a digital signature ceremony: the RP issues a fresh challenge, the authenticator signs it (after the user's local UV), the RP verifies the signature.
Three structural properties drop out:
- Origin binding. The browser scopes credentials to the registered origin. A phishing site at
logIn.example.comcannot trick the authenticator into signing forlogin.example.com; the browser computesSHA-256(rpId)and refuses to find a credential. Phishing as an attack class becomes structurally impossible. - No replayable secret. The shared secret is the public key — freely publishable. There is nothing to leak in a server breach beyond the public material.
- Hardware boundary. The private key sits in a secure element / TPM / smart card. Compromise requires physical access (or a hardware-level attack against the secure element, which costs orders of magnitude more than software-level extraction).
Where passkeys win — and how decisively
Phishing: solved structurally. The user cannot accidentally hand the credential to an attacker, because the authenticator refuses to act outside its registered origin. This is the load-bearing win.
Credential stuffing: not applicable. There is no password to stuff. Even if a server-side database leaks, the public-key material is publishable by design.
Push fatigue: not applicable. The user makes one decision per ceremony — tap or no tap — with explicit origin context provided by the browser. There is no out-of-band approval channel for an attacker to flood.
Replay: solved structurally. Each ceremony is signed over a fresh server-issued challenge.
Bulk-attack economics: devastatingly improved for the defender. Phishing attacks scale to millions because they cost the attacker little per target. With passkeys, the attacker has no replayable artefact — no password, no OTP, nothing they can re-use even once. The attack cost shifts from "send phishing emails to a list" to "physically steal hardware from each individual victim". That is a fundamentally different economic regime.
Where passkeys don't win — and what to pair with
Account recovery: passkeys make recovery harder, because you can't simply reset a password. If the user's authenticator is lost, what's the path back in? Three answers in priority order:
- Enrol two authenticators per user. Lose one, the other works. Re-issue the lost one through the normal channel.
- For consumer use, accept syncable passkeys (BE=1). The cloud account is the recovery anchor; we trade some assurance for recoverability.
- For workforce use, build IT-mediated re-enrolment: in-person identity verification, short-lived TOTP, then a fresh hardware credential. Auditable. Single-shot.
Session theft: once authenticated, a session cookie is bearer. An attacker who steals the cookie has the session until expiry. Mitigations: short session lifetimes, device-binding (DPoP, signed JWTs), continuous device-posture re-check.
Cloud-account compromise (for syncable passkeys): a synced passkey lives in a platform vendor's cloud. If the vendor's cloud is compromised, or if the user's cloud account is compromised via a separate attack, the passkey is exposed. For high-assurance use, require BE=0 (device-bound), which removes this branch.
Consent-phishing within OAuth flows: even a phishing-resistant authentication doesn't stop the user from approving a malicious application's scope grants. App allow-listing and scope review remain necessary.
The BE/BS distinction, applied
WebAuthn level 3 added two flag bits to authenticatorData: BE (Backup Eligible) and BS (Backup State). These are not cosmetic. They are how the protocol tells the relying party whether a credential is device-bound or syncable.
For an enterprise, the policy is simple: high-assurance flows (privileged access, source code, infrastructure consoles) require BE=0. Convenience flows (everyday SaaS) accept BE=1. Tier the application catalogue accordingly.
For a consumer service, the policy is also simple: accept everything. The marginal user with a passkey on their iPhone is incomparably better protected than the same user with a password.
Migration paths from TOTP / push
Three patterns for moving from a legacy MFA to passkeys.
Pattern 1: dual-factor, then deprecate
Add WebAuthn as an additional factor alongside existing TOTP / push. Roll out to volunteer users first. Once enrolment is at 80%+, deprecate TOTP / push as a sign-in option, leaving them only for recovery. This is the lowest-risk path; it gives users time to adapt.
Pattern 2: forced-rollout by cohort
Mandate passkey enrolment for engineering / privileged-access cohorts first. Provide hardware (USB key + smart card). Schedule cohort-wide enrolment days at the IT desk. Within 90 days, deprecate password+OTP for these cohorts. Expand to other cohorts on a roadmap.
Pattern 3: greenfield IdP migration
Move the IdP itself: new IdP supports passkeys natively, old IdP remains for legacy systems. Migrate apps off the old IdP one at a time, with a hard cutover. Useful when an IdP replacement was already on the roadmap.
What ships in production: a posture sketch
The deployment we recommend for a workforce of 10,000+ employees:
- Two authenticators per user: OnePass Card (turnstile + desktop) plus OnePass USB Key (laptops). Both BE=0.
- FIDO Validation Server at the IdP, attestation-anchored against AAGUID allow-list, MDS BLOB synced daily.
- UV required for high-assurance flows; UP-only acceptable for low-risk session refresh.
- Recovery: in-person re-enrolment, never password fallback.
- Lifecycle: HR-driven, with revocation propagating to IdP within minutes of offboarding.
- Audit: AAGUID + serial logged on every registration; signCount on every assertion; anomalies (counter regression, AAGUID change) alert SecOps.
What this looks like for the user
Day one: tap the card on the desk reader, type the device PIN once. Browser opens to corporate IdP, already authenticated. Click to gmail / slack / jira / build / cloud / git — all federated. Tap when prompted by the IdP for sensitive actions (privileged ops, code-signing, prod access).
Lost card: walk to the IT desk, identity-verify in person, leave with a new card. New card is enrolled before they leave the desk; old card revoked across the IdP within seconds.
End of day, end of year, end of employment: the user's identity has never been a string of characters anyone could write down. It has been a piece of hardware they hold. The shift is operational, not just cryptographic.
Honest tradeoffs
Three real costs we want to be explicit about:
Cost 1: hardware procurement. Two authenticators per user is real money — typically $25-$60 per user depending on form factor. Compare against the cost of one phishing incident.
Cost 2: enrolment friction. First-time enrolment requires in-person verification — harder for distributed workforces. Mitigations: regional IT desk days, supervised enrolment over Zoom plus mailed-key with a tamper-evident envelope.
Cost 3: legacy-app integration. Some legacy apps don't speak SAML or OIDC. They become the long pole. Often the right answer is a reverse proxy that terminates the user session and forwards via a service account — not pretty, but it preserves the security posture for everything in front of the proxy.
Bottom line
Passkeys are not "MFA, just stronger". They are a different cryptographic primitive that retires entire attack classes (phishing, replay, credential stuffing, push fatigue) by virtue of being origin-bound and hardware-rooted. The migration cost is real and one-time; the operating cost is comparable or lower than legacy MFA. For an enterprise that takes phishing-resistance seriously, this is no longer an aspiration — it is the deployment.