Security & Supply ChainDeveloper Tools

The Extra Step at Login: MFA Design Logic and Passkey's Model Shift

You type in your password, but instead of landing on the page, a box pops up asking for a six-digit code. The code is in an email. The email is in your spam folder. You switch tabs, scroll through two pages of unread messages, copy the code, paste it back — and it has already expired. Refresh. Try a different channel: SMS. This time it is faster. A notification slides down, four digits appear, the system fills them in for you. You are logged in.

These two flows do the same thing: after password verification, the website asks one more question and waits for the right answer. But the experience gap is large enough to ask what each approach is doing at the design level, and whether the smoother one pays a cost in security.

Why Passwords Are Not Enough

A password is a shared secret. You set a password when you register, and the website stores a hash. When you log in, you send the password, and the website checks it against the hash.

This model has three weak points.

First, database leaks. When a website is breached, password hashes fall into the attacker’s hands. A hash cannot be used to log in directly, but a weak password can be reverse-computed from its hash. And for people who reuse the same password, one site’s leak spreads to every other site.

Second, phishing. An attacker builds a login page identical to the real one and tricks you into entering your password. You enter the correct password — it just goes to the wrong place.

Third, reuse. Most people are bad at memorizing dozens of distinct passwords, so they reuse a base secret or add small variations to it.

These three weak points share the same origin. Password authentication works by telling the website the same secret every time you log in. The act of telling creates the opening for leaks.

The website stores this secret, so there is a possibility of it being stored insecurely. You hand the secret to the website, so there is a possibility of handing it to an impostor. And because different websites ask for the same secret, one leak spreads to everywhere else.

What MFA Tries to Achieve

The logic behind multi-factor authentication is straightforward: if the password can be stolen, make the theft useless. Even with the password, an attacker cannot log in without a second thing.

This “second thing” falls into standard categories. Something you know: password, PIN. Something you have: phone, hardware key. Something you are: fingerprint, face. The core requirement of MFA is to use at least two factors from different categories. Logging in requires something you know plus something you have, so a single-point leak is not enough to pass authentication.

What MFA solves, then, is not just the vague goal of “being more secure.” It solves three specific problems: making stolen passwords useless; preventing replay attacks; and forcing an attacker to breach a second factor from a different category after breaching the first.

These three goals define every design trade-off that follows.

Email Verification Codes

Email-based one-time codes were among the first widely adopted forms of MFA. The design logic is direct: every user provides an email during registration, and email is already the account recovery channel. Sending a code on top of the password is the smallest possible product change.

From the product side, this approach leverages an existing identity anchor. The website can assume: whoever has access to this email inbox is probably the account owner. No new software to install. No SIM card to swap. No new concepts to learn. An email is the lowest-effort second step from a product design standpoint.

But email as a verification channel has three structural problems.

Reliable delivery is not the default. Spam filters, sender reputation, and mail provider throttling can all delay or drop the message. This is not a random failure. Email protocols were designed as an asynchronous, retry-friendly system that does not require instant delivery. MFA demands the opposite: within 30 seconds of clicking “send code,” it must appear in the inbox. These two time expectations operate on different orders of magnitude.

An attacker may already be in your email. If the attacker has obtained your email password through the same password reuse, the email MFA’s second line of defense disappears. The code lands in an inbox the attacker can already access.

The experience problem is also significant. Email codes interrupt the login flow clumsily. You are in a browser; the code is in a mail client. You stop, switch to another app or tab, find the email, locate the right one among dozens of sender names and subject lines, copy the code, switch back, paste. Some mail clients support autofill, but this is not universal, especially in webmail and on desktop.

SMS Verification Codes

SMS codes are structurally identical to email codes: your phone number is also an identity anchor, the code travels through a carrier network, and you type it back.

But the experience has one essential difference: on most smartphones, the system-level autofill fills the code into the input field directly. You never leave the current app or browser tab. Compared to email’s switch-search-copy-paste four-step dance, SMS has a much shorter interaction path. See the notification, see the digits, they fill themselves in.

This improvement comes not from any superiority of the SMS protocol. It comes from the operating system treating “verification codes in SMS messages” as a first-class pattern, with iOS and Android both building dedicated parsing and autofill. Email content, by contrast, is far more flexible in structure, making the same optimization harder in engineering terms.

So on the UX dimension, SMS is better than email — but what is better is the system integration, not the security model. The security model is the same category: an external channel delivering a one-time code. Email may be delayed by spam filters; SMS may be delayed by carrier routing. The shared weakness is that the code exists in plaintext on a channel that passes through third-party infrastructure.

SIM cloning and SS7 signaling network attacks are the two most discussed security flaws of SMS codes. But these attacks have a much higher barrier than password reuse and phishing. For the vast majority of ordinary users, the more relevant threat model for SMS is: can someone take over your phone number through social engineering at your carrier?

So on the security-versus-experience spectrum, SMS codes sit roughly here: much stronger than passwords alone, much better UX than email, but just as vulnerable as email against targeted attacks.

TOTP Authenticators

TOTP does something neither email nor SMS does: it does not send the code.

TOTP stands for Time-based One-Time Password. The core mechanism: during setup, the website and your authenticator share a secret key. This key is exchanged through a QR code, not through SMS or email. After that, your authenticator takes this key plus the current time window and computes a six-digit code locally. The website, using the same key and the same time window, independently computes the same result. If the numbers match, the verification passes.

The critical change is that the code no longer travels through any third-party channel. No SMS carrier involved. No email server involved. The authenticator computes it on-device, with no dependency on signal, network connectivity, or sender delivery quality.

From a security design perspective, this step shrinks the attack surface on the transmission path. The problem with email and SMS is not that the code itself is insecure; it is that the path delivering the code has too many links outside your control. TOTP removes the channel entirely and replaces it with both sides independently computing the same result.

There are costs. First, onboarding: you need to install an authenticator app, scan a QR code, and internalize the concept of “do not delete this credential.” Second, device loss: if you lose your phone or switch to a new one, whether your stored credentials can be recovered depends on whether your authenticator supports backup. Google Authenticator long lacked cloud backup, leading to cases where people contacted site support one by one after switching phones. Authy and later versions of Google Authenticator now support encrypted backup, which has eased this problem.

Passkey

The approaches covered so far share a premise: there is a password first, and MFA is added on top. The password is always the front door.

Passkey takes a different route. It replaces the password with asymmetric keys. During registration, your device generates a key pair. The private key stays on the device; the public key is sent to the website. During login, the website sends a random challenge, the device signs it, and the website verifies with the public key. No shared secret is transmitted or stored on the server at any point.

It works on the same principle as SSH key login. For readers unfamiliar with asymmetric keys, a rough analogy is prime factorization: multiplying two large primes is fast, but factoring the product back into the original primes is extremely hard. The security of public-key cryptography rests on one-way functions of similar character.

The three password vulnerabilities disappear. The website only stores a public key — a database breach is useless. The signature binds the website domain — a phishing page at a different domain cannot produce a valid signature. No password means no reuse.

One difference from an SSH private key file: in mainstream systems, the Passkey private key is not extractable. A web page can only ask the device “please sign this data for me.” The device returns the result; the private key never leaves the secure storage area. Even if a login page contains malicious scripts, it cannot steal the private key from your device.

Seen in the design lineage, Passkey is not adding another layer on top of MFA. It swaps authentication from “sharing a secret” to “holding a key without needing to send the key.” This change does not lie on the same extension line as the three methods before it.

From Patches to a Model Shift

Lay out the four approaches, and a clear evolutionary direction emerges: each step removes one assumption about what can be trusted.

The password model assumes users will not reuse passwords, websites will not leak hashes, and users will not click on phishing pages. All three assumptions fail.

Email MFA adds one assumption on top: the mail server is secure, and the code will arrive within the time limit. This assumption partially holds — most of the time email does go through. But it also assumes the email account has not been compromised, spam filters will not misclassify, and the user can locate the code among dozens of unread messages. Any step can break.

SMS MFA switches channels and assumptions along with it: the carrier network is secure, the phone number cannot be SIM-swapped, SMS delivers instantly. Compared to email, delivery reliability improves significantly, but signaling-layer attacks remain.

TOTP removes the dependency on channels entirely. It no longer assumes “an external service will deliver the code to you.” Instead, it assumes “the device clock is accurate, and the locally stored shared secret has not been leaked.” The attack surface shrinks to the local device.

Passkey removes the final assumption: it no longer requires a shared secret. The server-side database stores nothing that can reconstruct the login credential. An attacker cannot obtain the private key because the private key never passes through the server and never participates in transmission. The attacker can only try to impersonate you at the local device level, which requires breaking both the device unlock and the authenticator’s security boundary simultaneously.

The pattern in this evolutionary line is not “getting more secure.” Most of these approaches were adequate relative to the threats of their era. The pattern is: each generation shrinks one implicit assumption the previous generation relied on. From “every user has good password habits” to “email always arrives on time” to “local storage will never be breached” to “no shared secret needed at all.”

So Passkey is not just better MFA. It changes direction on the authentication design path: rather than continuing down the line of “adding more verification factors,” it swaps what needs to be verified from a shared secret to an asymmetric key.

Practical Advice

For daily use, a tiered approach is sufficient.

High-value accounts — Google, Apple, GitHub, banks, password managers, domain registrars, Cloudflare — should get Passkey plus at least one backup recovery method. Keeping two hardware security keys, one for daily use and one locked away as backup, is a more robust approach than relying on a single sync mechanism.

For ordinary websites, platform-synced Passkeys — iCloud Keychain, Google Password Manager, or 1Password — are enough. They are more secure than any password you can remember, faster than SMS and email MFA, and lower-friction than TOTP onboarding.

If a website does not yet support Passkey, use a TOTP authenticator with password manager autofill. This combination is not as secure as Passkey, but it is far better than SMS or email MFA. Avoid using email alone as the second factor on critical accounts.

One easily overlooked reminder: do not set up a single Passkey and then delete all recovery methods. Passkey security depends on your continued access to the device or account holding the private key. If you use iCloud Keychain, your Apple ID security becomes more critical. Make sure your Apple ID itself has strong 2FA or Passkey enabled, and that you have available recovery contacts or a recovery key. If you use 1Password, keep your Emergency Kit and master password backed up in a safe place. The more authentication centralizes onto a few devices or accounts, the more those accounts need redundant protection.

What Developers Should Choose

There are typically two paths for adding MFA: use a third-party authentication service, or build it yourself. Going with a third party is the most common approach. The benefit is that the SDK handles fallback logic between multiple MFA methods, session management, and anomaly detection out of the box.

Here are several services that cover the full MFA stack:

Auth0 (owned by Okta) has the broadest coverage, supporting everything from SMS to TOTP to Passkey, with the most complete enterprise SSO and compliance audit features. Pricing is on the higher end, suitable for scenarios with existing enterprise customers or strong compliance requirements.

Clerk and Stytch emphasize developer experience, with well-polished documentation and SDKs. Both cover passwords, social login, SMS, TOTP, and Passkey, with early support for Conditional UI. Clerk’s React and Next.js integration is particularly deep.

WorkOS focuses on B2B SaaS, with solid enterprise SSO plus MFA capabilities and targeted optimization for enterprise customer onboarding flows. Pricing is also on the higher end.

Hanko and Corbado are passkey-first services, with the entire authentication flow designed around passkey from the ground up. The pure-passkey route provides the cleanest experience, but it requires a user base with relatively new devices.

Supabase Auth and Firebase Auth offer out-of-the-box MFA support, including TOTP and multi-device Passkey, suitable for teams already using these platforms as their backend. Integration cost is low, but customization space is relatively limited.

If you choose to build your own stack, Twilio and Infobip are common choices for SMS delivery, TOTP can be computed server-side with open-source libraries, and Passkey can be integrated through libraries like SimpleWebAuthn that wrap the WebAuthn standard. Rolling your own gives maximum flexibility, but you will need to maintain the fallback chain between different MFA methods and manage SMS delivery rates yourself.