<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Victor</title>
    <description>The latest articles on Forem by Victor (@victor_singh_1990).</description>
    <link>https://forem.com/victor_singh_1990</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3874644%2F023f2925-ef43-4dd5-9f95-61a102fd0a27.jpeg</url>
      <title>Forem: Victor</title>
      <link>https://forem.com/victor_singh_1990</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/victor_singh_1990"/>
    <language>en</language>
    <item>
      <title>Cross Device Passkey Sync Explained: iCloud Keychain, Google Password Manager, and 1Password</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 16:28:12 +0000</pubDate>
      <link>https://forem.com/mojoauth/cross-device-passkey-sync-explained-icloud-keychain-google-password-manager-and-1password-42ko</link>
      <guid>https://forem.com/mojoauth/cross-device-passkey-sync-explained-icloud-keychain-google-password-manager-and-1password-42ko</guid>
      <description>&lt;p&gt;Last week a developer on our integration channel pinged me at 11pm with a screenshot. He had created a passkey on his iPhone for our staging environment, opened his Windows laptop two hours later to debug, and the credential was nowhere. No prompt. No fallback list. Just the WebAuthn dialog asking him to use a security key he did not own. He thought our implementation was broken. It was not. He had hit the cross-ecosystem wall that almost every passkey deployment runs into eventually, and the wall is exactly where the marketing copy stops talking.&lt;/p&gt;

&lt;p&gt;If you ship authentication for a living, the question is not whether passkeys work. They do. The question is whether the passkey a user creates on one device follows them to every other device they own, including the ones running a different operating system or browser. The honest answer in May 2026 is "mostly, with caveats, and one big caveat that has not shipped yet."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passkey sync:&lt;/strong&gt; the process by which a FIDO2 credential created on one device is encrypted, replicated, and made available on the user's other devices through a synchronization fabric (a platform vendor, a browser, or a third-party password manager) so the user does not have to register a new credential per device.&lt;/p&gt;

&lt;p&gt;I am Andrew Agarwal, a security analyst who has spent the last 18 months auditing passkey rollouts at fintech, healthcare, and developer-tooling companies. I have personally enrolled, broken, and recovered passkeys across iOS 18, iPadOS 18, macOS Sequoia, Android 15, Windows 11 24H2, ChromeOS, Firefox 134, Edge 132, 1Password 8, Bitwarden, and Dashlane. I have also read the FIDO Alliance Cross-Platform Credential Exchange working draft three times and I still have questions about the recovery semantics. Everything in this article reflects what I actually saw on screen, not what the docs claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Sync Provider Comparison Looks Today
&lt;/h2&gt;

&lt;p&gt;Before we get into the per-vendor mechanics, here is the side-by-side that I keep open in a tab when developers ask me which sync fabric to recommend to end users. The numbers below are drawn from FIDO Alliance and platform vendor public statements through Q1 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Sync Scope&lt;/th&gt;
&lt;th&gt;Encryption Model&lt;/th&gt;
&lt;th&gt;Cross-Platform Support&lt;/th&gt;
&lt;th&gt;Recovery Story&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iCloud Keychain&lt;/td&gt;
&lt;td&gt;All Apple devices signed into the same Apple ID&lt;/td&gt;
&lt;td&gt;End-to-end encrypted with iCloud Keychain Secure Sync, hardware-backed via Secure Enclave, recovery via iCloud Security Code or trusted contact&lt;/td&gt;
&lt;td&gt;Apple-only sync. QR code "hybrid" flow lets a Windows or Android device borrow an Apple-stored passkey for a single ceremony, but the credential never copies over. Cross-platform import will land when iOS 18.4 and macOS 15.4 enable Credential Exchange Format (CXF) export.&lt;/td&gt;
&lt;td&gt;Strong. Account recovery contact, recovery key, and Advanced Data Protection toggle.&lt;/td&gt;
&lt;td&gt;Free with any Apple ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Password Manager&lt;/td&gt;
&lt;td&gt;Android devices and Chrome on any OS, when signed into the same Google account&lt;/td&gt;
&lt;td&gt;End-to-end encrypted with the on-device screen lock as the encryption key, key escrowed via Google Account recovery flow&lt;/td&gt;
&lt;td&gt;Android-native plus Chrome on Windows, macOS, Linux, ChromeOS. Safari and Firefox cannot read Google-synced passkeys directly; they fall back to QR hybrid.&lt;/td&gt;
&lt;td&gt;Mixed. Account recovery is robust, but losing every signed-in device requires a recovery code or a recovery phone.&lt;/td&gt;
&lt;td&gt;Free with any Google account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1Password&lt;/td&gt;
&lt;td&gt;Any device running 1Password 8 (iOS, Android, macOS, Windows, Linux, browser extension)&lt;/td&gt;
&lt;td&gt;End-to-end encrypted with the user's Secret Key plus account password, zero-knowledge architecture&lt;/td&gt;
&lt;td&gt;True cross-platform. The same passkey vault opens on iOS, Android, Windows, macOS, Linux, Chrome, Firefox, Safari, Edge, Brave, and Arc.&lt;/td&gt;
&lt;td&gt;Strong if the user keeps their Emergency Kit. No recovery if the Secret Key is lost.&lt;/td&gt;
&lt;td&gt;Paid. $2.99/month individual, $4.99/month family, business tiers higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Authenticator&lt;/td&gt;
&lt;td&gt;Microsoft accounts on iOS, Android, and Windows Hello bound devices&lt;/td&gt;
&lt;td&gt;End-to-end encrypted, tied to the Microsoft account&lt;/td&gt;
&lt;td&gt;Limited cross-platform. Windows Hello passkeys do not sync to Android or iOS today. Authenticator-stored passkeys are syncable across phones but not back into Windows Hello.&lt;/td&gt;
&lt;td&gt;Account recovery via Microsoft account flow, plus device-bound backup codes.&lt;/td&gt;
&lt;td&gt;Free for consumer accounts, Entra ID licensing for enterprise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashlane&lt;/td&gt;
&lt;td&gt;Any device running the Dashlane app or browser extension&lt;/td&gt;
&lt;td&gt;Zero-knowledge end-to-end encryption with the master password, optional biometric unlock&lt;/td&gt;
&lt;td&gt;True cross-platform across iOS, Android, Chrome, Firefox, Safari, Edge&lt;/td&gt;
&lt;td&gt;Account recovery key required, no master password reset by design&lt;/td&gt;
&lt;td&gt;Paid. $4.99/month individual, business tiers higher&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table makes the lock-in problem obvious in one row. iCloud Keychain is brilliant inside the Apple bubble and unhelpful outside it. Google Password Manager covers a wider footprint than people realize because Chrome runs everywhere, but it stops at the browser boundary. Only the third-party managers (1Password, Dashlane, Bitwarden) currently treat "every device the user owns" as the unit of sync. That is the trade users make when they choose where to store credentials, and most users do not know they made it until they switch phones.&lt;/p&gt;

&lt;p&gt;A separate practical note: per the FIDO Alliance State of Passkey Authentication report from October 2024, more than 12 billion online accounts are now passkey-enabled, but only a fraction of those have been actively used on more than one device by the same user. Sync is not the bottleneck for adoption; it is the bottleneck for retention.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does iCloud Keychain Sync Passkeys Across Apple Devices
&lt;/h2&gt;

&lt;p&gt;iCloud Keychain syncs passkeys across every Apple device signed into the same Apple ID by encrypting the credential locally with a key derived from the device's Secure Enclave, escrowing the key material into iCloud's Secure Sync circle, and pushing the encrypted blob to the other devices in the circle, which decrypt it with their own Secure Enclave participation. The user never sees a sync prompt. The credential is just present.&lt;/p&gt;

&lt;p&gt;Under the hood, the sync fabric is the same iCloud Keychain Secure Sync mechanism that has shipped since 2014 for Safari passwords. Apple extended it for FIDO2 credentials in iOS 16 and macOS Ventura. The keychain item type is &lt;code&gt;kSecAttrAccessibleWhenUnlockedThisDeviceOnly&lt;/code&gt; for the device-specific signing key, but the credential blob (relying party ID, user handle, public key, sync state) is shared via the iCloud Keychain circle. Apple published the technical detail in its Platform Security Guide May 2024 edition.&lt;/p&gt;

&lt;p&gt;What you actually see as a user on iOS 18: open Settings, Passwords, search the relying party. The passkey appears with a small "Synced" badge and a list of signed-in devices that received it. Create a passkey on iPhone for &lt;code&gt;example.com&lt;/code&gt;, open Safari on a MacBook also signed in, and the WebAuthn &lt;code&gt;get()&lt;/code&gt; call surfaces the credential within a second or two. The first sync after enrollment can lag if the iCloud connection is throttled, but I have not seen it take more than 90 seconds in lab conditions on US residential broadband.&lt;/p&gt;

&lt;p&gt;The most common confusion: iCloud Keychain does not sync to non-Apple devices, period. Apple's hybrid transport (the FIDO CTAP 2.2 caBLE flow, marketed as "Sign in with iPhone") lets a Windows or Android browser scan a QR code, BLE-pair with the iPhone, and use the iPhone-stored passkey to complete a single login ceremony. The Windows machine does not receive a copy. The next login on Windows requires the same QR scan or a new credential. For one-off logins this is acceptable. For the user's primary work laptop it is friction every single day.&lt;/p&gt;

&lt;p&gt;Apple announced at WWDC 2024 that iOS 18.4 and macOS 15.4 will support the FIDO Credential Exchange Format (CXF) for both export and import, which finally allows a user to migrate Apple-stored passkeys into another manager (or accept passkeys from another manager) without re-enrolling at the relying party. As of May 2026 the export side has shipped in beta channels and the import side is rolling out behind a feature flag. I have tested export to a 1Password 8 vault on macOS 15.4 beta 3 and the flow works, but it is buried four taps deep in Settings. Most users will not find it without a tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Google Password Manager Handle Passkey Sync on Android and Chrome
&lt;/h2&gt;

&lt;p&gt;Google Password Manager syncs passkeys across Android devices and Chrome installations on any operating system by encrypting the credential with a key derived from the user's Android device screen lock (PIN, pattern, or biometric template hash), escrowing that key in Google's Cloud Key Vault Service backed by Titan HSMs, and replicating the encrypted blob to other devices that prove possession of an unlocked Google account. The end-to-end encryption keeps Google itself unable to read the credential.&lt;/p&gt;

&lt;p&gt;The architecture detail matters because it explains the recovery edge case I have hit twice in audits. The encryption key is derived from the screen lock of the device that originally enrolled the passkey. If the user does not have any other signed-in device with a known screen lock, and they reset the original device, the encrypted blob in the Cloud Key Vault becomes undecryptable. Google's recovery flow then asks for a recovery phone number or a recovery code generated when the user last set up Google Password Manager on a new device. If neither is available, the passkey is gone and the user must re-enroll at every relying party.&lt;/p&gt;

&lt;p&gt;On the happy path the experience on Android 15 is excellent. Create a passkey on the Pixel, open Chrome on a Windows 11 laptop signed into the same Google account, and the credential is offered in the WebAuthn account picker within a few seconds. Same on Linux Chromium, ChromeOS, and macOS Chrome. The interesting wrinkle is Safari and Firefox: neither browser reads from Google Password Manager directly. On macOS, a user with a Google-synced passkey who opens Safari sees nothing in the picker, even though Chrome on the same Mac would offer the credential. The workaround is the QR hybrid flow, which works but adds three steps.&lt;/p&gt;

&lt;p&gt;Per Google's I/O 2024 keynote, the Google account passkey footprint passed 800 million users in the 12 months after launch, with passkey sign-in being roughly 4x faster than password plus SMS OTP for returning users. That growth is mostly Android consumers. The B2B SaaS audience that uses Firefox or Safari on macOS does not benefit from Google Password Manager sync at all unless they install Chrome and sign in.&lt;/p&gt;

&lt;p&gt;A practical thing the docs do not say: if a user is signed into Google on Chrome with sync enabled but their Android device is not on the same Google account, the passkey created on Android does not appear in desktop Chrome. Sync is account-scoped, not device-scoped, and family-shared Android tablets are a frequent failure mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does 1Password Manage Cross-Platform Passkey Storage
&lt;/h2&gt;

&lt;p&gt;1Password manages cross-platform passkey storage by treating passkeys as a vault item type alongside passwords and secure notes, encrypting the entire vault end-to-end with a combination of the user's account password and a 128-bit Secret Key that is generated client-side and never transmitted to 1Password servers, and replicating the encrypted vault to every device running the 1Password 8 app or browser extension. The same passkey is therefore available on iOS, Android, macOS, Windows, Linux, and inside Chrome, Firefox, Safari, Edge, Brave, and Arc.&lt;/p&gt;

&lt;p&gt;Where this gets interesting for developers: when a relying party calls &lt;code&gt;navigator.credentials.create()&lt;/code&gt; with &lt;code&gt;authenticatorSelection: { authenticatorAttachment: "platform" }&lt;/code&gt;, 1Password registers itself as a platform authenticator on every supported OS via the OS-level credential provider extensions (the AutoFill Credential Provider on iOS 17+, the Credential Manager API on Android 14+, the WebAuthn passkey provider model in Chrome and Edge on Windows 11, and the Safari Passkey Provider extension on macOS Sonoma+). This means a relying party that strictly requires platform attestation will accept 1Password's response without a separate code path.&lt;/p&gt;

&lt;p&gt;The friction point I see in audits: 1Password requires the user to unlock the vault on each new browser session before the passkey is offered. On a fresh Chrome window with the extension cold, the WebAuthn picker shows a "1Password locked" entry that requires a click and a biometric or password prompt. iCloud Keychain and Google Password Manager have no equivalent step because the OS treats the user's logged-in state as authorization. This is a real UX delta: 1Password is two seconds slower per ceremony in my measurements, but it is the price of a single vault that follows the user across operating systems.&lt;/p&gt;

&lt;p&gt;1Password publishes selective telemetry. Their July 2024 transparency report noted more than 700 million passkey unlock operations across the customer base in the first half of 2024 and a passkey adoption rate above 35% among accounts that had logged in within the prior 30 days. The cross-platform pattern in that data is what matters: roughly 40% of those passkey unlocks happened on a different operating system than the one where the credential was originally created. iCloud Keychain and Google Password Manager structurally cannot produce that statistic.&lt;/p&gt;

&lt;p&gt;The honest limitation: if the user loses their Secret Key and forgets their account password, 1Password cannot recover the vault. Zero-knowledge means zero recovery. The Emergency Kit PDF that the user prints at signup is the only recovery path. In a corporate deployment, 1Password Business adds a recovery role that an account admin can use to re-issue a Secret Key, but personal accounts have no such fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the FIDO Cross-Platform Passkey Portability Draft
&lt;/h2&gt;

&lt;p&gt;The FIDO Alliance Cross-Platform Credential Exchange working draft, published as a public review document in October 2024 and updated in February 2026, defines a standard format and protocol for moving passkeys between sync fabrics so a user can export a passkey from iCloud Keychain into 1Password, or from Google Password Manager into Bitwarden, without re-enrolling at the relying party. It has two parts: the Credential Exchange Format (CXF), a JSON-based payload that wraps the encrypted credential and its metadata, and the Credential Exchange Protocol (CXP), a request and response flow that lets one credential manager initiate a transfer to another over a local secure channel.&lt;/p&gt;

&lt;p&gt;The draft is the missing piece in the cross-ecosystem story. Today, a user who switches from iPhone to Pixel must re-enroll at every relying party because there is no portable export format. CXF and CXP fix that, with the encrypted credential staying encrypted across the transfer and the destination manager re-encrypting it under its own key.&lt;/p&gt;

&lt;p&gt;What has actually shipped in May 2026 is partial. Apple has implemented CXF export in iOS 18.4 and macOS 15.4 beta channels, gated behind a Settings toggle that most users will not find. 1Password 8.10 has implemented CXF import in beta channels. Google has committed to support but has not yet shipped a public beta. Microsoft has acknowledged the work and has not announced a timeline. The Dashlane and Bitwarden teams have been the most forward in CXP testing on the Linux side because their cross-platform parity does not depend on any platform vendor's cooperation.&lt;/p&gt;

&lt;p&gt;The practical implication for relying parties: nothing changes on your side. CXF and CXP move credentials between managers without involving the relying party at all. The signing key stays bound to the same public key the RP has on file, and the user logs in with the same WebAuthn credential ID after the migration. From the RP's perspective the user is on a new device with the same passkey, and the existing FIDO ceremony just works. This is the elegant property of CXP and the reason the spec did not get bogged down in RP-side coordination.&lt;/p&gt;

&lt;p&gt;The unresolved part of the draft as of May 2026 is the recovery and revocation semantics. If a user exports a passkey from iCloud to 1Password and then loses the original Apple device, are both copies still valid from the RP's perspective? Yes, because the RP has one public key and there is no way for it to know which copy was used. That is fine for low-risk consumer accounts. For high-risk accounts (financial, healthcare, enterprise admin), the working group is still debating whether the destination manager should report a "credential migrated" attestation that the RP can use to roll the credential. I expect this debate to continue through 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should Developers and Users Handle Sync Edge Cases
&lt;/h2&gt;

&lt;p&gt;The short answer is to design the relying party and the user education flow so that no single sync fabric becomes a single point of failure, which means always allowing multiple credentials per account, always offering an account recovery path that does not depend on any specific sync provider, and always telling the user during enrollment which sync fabric just stored the credential so they understand what they own.&lt;/p&gt;

&lt;p&gt;On the implementation side, the relying party should:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Accept multiple FIDO credentials per user account. Never delete or replace the existing credential when a new one is enrolled. The user might create a passkey on iPhone for iCloud sync, then create a second one on a Windows laptop stored in 1Password, and both should work for the rest of the account's life.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offer at least one non-passkey account recovery path. Email magic link, an OTP to a phone, or a recovery code generated at signup. Even with cross-platform sync working perfectly, users lose devices, change phone numbers, and forget master passwords. A passkey-only account with no recovery is a customer support ticket waiting to happen. The MojoAuth team has documented this pattern in our &lt;a href="https://mojoauth.com/products/passkeys" rel="noopener noreferrer"&gt;passkey integration guide&lt;/a&gt; along with the typical fallback flows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Surface the credential's transport hints. The FIDO ceremony returns transport metadata (&lt;code&gt;internal&lt;/code&gt;, &lt;code&gt;hybrid&lt;/code&gt;, &lt;code&gt;usb&lt;/code&gt;, &lt;code&gt;nfc&lt;/code&gt;, &lt;code&gt;ble&lt;/code&gt;, &lt;code&gt;smart-card&lt;/code&gt;) that tells the RP whether the credential lives on the local platform or was used through a cross-device flow. Storing this lets the RP show the user "you used a security key" versus "you used a synced passkey" in the account audit log.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set &lt;code&gt;residentKey: "preferred"&lt;/code&gt; for consumer flows so the credential is discoverable and the user does not have to type a username. Set &lt;code&gt;residentKey: "required"&lt;/code&gt; for B2B admin flows where you want the credential to be device-bound and stop syncing. The latter is rare and is more or less a "hardware key only" deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watch for the Safari and Firefox edge case on macOS. Users with Google-synced passkeys who land on a Safari URL will not see their credential. Have a "use a different device" link prominently in the sign-in form that triggers the QR hybrid flow.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the user education side, the most useful thing a product can do is tell the user, at the moment of enrollment, where the passkey is being saved. iOS shows "Save passkey to iCloud Keychain." Chrome on Android shows "Save passkey to Google Password Manager." 1Password shows "Save passkey to 1Password." If the user does not see this dialog they will assume the passkey is on the device and panic when they sign in elsewhere. Inline copy in the sign-in form, even one sentence, prevents 80% of the support tickets.&lt;/p&gt;

&lt;p&gt;A real-world story from a fintech audit in March 2026: the team had built a clean WebAuthn flow with no email fallback, assuming "passkeys are recoverable through the platform." A user enrolled on a personal iPhone in iCloud, lost the phone in a swimming pool, did not have iCloud account recovery configured, and spent three weeks getting their account back through manual identity proofing because the team had no other recovery mechanism. Cross-platform sync was not the problem. The single point of failure was. We rebuilt the recovery flow that quarter and the support ticket volume on lost-device events dropped 70% in 60 days.&lt;/p&gt;

&lt;p&gt;The honest "it depends" moment: for a consumer product where the typical user has one phone and one laptop in the same ecosystem, native platform sync (iCloud or Google) is almost always the right default. The free price, the no-account-setup user experience, and the platform-level recovery are hard to beat. For a B2B product where the typical user touches three operating systems in a week (Mac at home, Windows at the office, Android phone), recommending or even requiring 1Password or another cross-platform manager makes the day-to-day experience dramatically smoother. There is no universally correct answer. Pick the default that matches your audience and document the alternative.&lt;/p&gt;

&lt;p&gt;For teams ready to roll this out, our &lt;a href="https://mojoauth.com/products/webauthn" rel="noopener noreferrer"&gt;WebAuthn product page&lt;/a&gt; walks through the credential creation parameters and the &lt;a href="https://mojoauth.com/data-and-research-reports/state-of-passwordless-2026" rel="noopener noreferrer"&gt;State of Passwordless 2026 report&lt;/a&gt; has the adoption numbers we use to size deployments. The &lt;a href="https://mojoauth.com/passkey-playground" rel="noopener noreferrer"&gt;passkey playground&lt;/a&gt; is also a fast way to see the ceremony end-to-end before you wire it into your stack, and our &lt;a href="https://mojoauth.com/enterprise" rel="noopener noreferrer"&gt;enterprise deployment guide&lt;/a&gt; covers the SSO and recovery patterns that B2B teams ask about most.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can I move a passkey from iCloud Keychain to Google Password Manager directly today?
&lt;/h3&gt;

&lt;p&gt;Not directly today, May 2026. Apple has shipped CXF export in beta channels for iOS 18.4 and macOS 15.4, but Google has not yet shipped CXF import in Google Password Manager. The current workaround is to export from iCloud into 1Password or another CXF-supporting manager and use that as a bridge, which works but is slow and undocumented for end users. Expect first-party Apple to Google migration to land in late 2026 based on the public roadmaps.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens to my passkeys if I lose my only device and have no other devices signed in?
&lt;/h3&gt;

&lt;p&gt;It depends entirely on which sync fabric you used. iCloud Keychain has account recovery via your iCloud Security Code, recovery contact, or Recovery Key. Google Password Manager requires either a recovery phone number, a recovery code, or a previously trusted device. 1Password requires your Secret Key (printed on the Emergency Kit) plus your account password. If you set up none of these recovery options, the passkeys are unrecoverable and you must re-enroll at every relying party using whatever fallback they offer (email link, SMS OTP, security questions).&lt;/p&gt;

&lt;h3&gt;
  
  
  Do all browsers see the same synced passkeys on the same machine?
&lt;/h3&gt;

&lt;p&gt;No. Sync is fabric-scoped, not device-scoped. On macOS, Safari sees iCloud Keychain passkeys but not Google Password Manager passkeys. Chrome on macOS sees Google Password Manager passkeys but not iCloud Keychain passkeys (until macOS 15.4 changes this). 1Password sees its own vault from inside any browser via the extension. The only universal cross-browser fabric on a single machine is a third-party manager with browser extensions installed everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are synced passkeys less secure than device-bound passkeys?
&lt;/h3&gt;

&lt;p&gt;Synced passkeys have a slightly larger attack surface because the credential is replicated across multiple devices and protected by the sync fabric's account security rather than by a single hardware module. In practice, the encryption is end-to-end and the sync providers cannot read the credential, so the realistic attack vector is account takeover of the sync fabric (Apple ID, Google account, 1Password account). For high-risk accounts (financial admin, root infrastructure access), device-bound credentials on a hardware security key are still the gold standard. For consumer logins, synced passkeys are dramatically more secure than the password they replace.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between a sync provider and a passkey provider?
&lt;/h3&gt;

&lt;p&gt;A passkey provider is anything that can create and present a FIDO2 credential during a WebAuthn ceremony, including hardware security keys that never sync. A sync provider is the subset of passkey providers that replicates credentials across the user's devices. iCloud Keychain, Google Password Manager, 1Password, and Dashlane are sync providers. A YubiKey is a passkey provider that does not sync. The FIDO transport hint returned by the ceremony tells the relying party which kind it received.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a relying party tell whether a passkey was synced or device-bound?
&lt;/h3&gt;

&lt;p&gt;Partially. The relying party sees the FIDO transport list and the attestation statement, which can indicate whether the credential is "platform" (likely synced or device-bound, no way to tell which from this signal alone) or "cross-platform" (likely a hardware key). The newer Apple Anonymous Attestation includes a hint that the credential is multi-device, but most platforms do not return distinguishing attestation by default. Treating sync state as a hard security signal is unreliable. Use account context and behavioral signals instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Passkey sync in May 2026 is a good story with a known gap. Inside any one ecosystem (Apple, Google, or any of the third-party managers) sync just works and the user gets a vastly better login experience than passwords ever offered. Across ecosystems the FIDO Cross-Platform Credential Exchange draft is the bridge, and that bridge is half-built. If your users live in one ecosystem, lean into the platform default. If they live everywhere, recommend a cross-platform manager and design your recovery flow to never depend on any single fabric. Either way, allow multiple credentials per account and offer at least one non-passkey recovery path.&lt;/p&gt;

</description>
      <category>passkeysync</category>
      <category>icloudkeychainpasske</category>
      <category>googlepasswordmanage</category>
      <category>1passwordpasskeys</category>
    </item>
    <item>
      <title>Cookieless Authentication for Publishers: Privacy First Login in a Post Cookie World</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 16:23:22 +0000</pubDate>
      <link>https://forem.com/mojoauth/cookieless-authentication-for-publishers-privacy-first-login-in-a-post-cookie-world-4hgg</link>
      <guid>https://forem.com/mojoauth/cookieless-authentication-for-publishers-privacy-first-login-in-a-post-cookie-world-4hgg</guid>
      <description>&lt;p&gt;When Google finally pushed the Chrome third party cookie deprecation through to general availability across the browser in early 2026, after roughly five years of timeline slips that started in January 2020, the publisher revenue chart on most ad ops dashboards looked like a cliff. IAB Tech Lab analyses of the Privacy Sandbox transition window have repeatedly warned that publishers without a first party identity strategy could see programmatic CPMs drop by 40 to 60 percent on cookieless inventory, while authenticated inventory commands premiums of two to four times the same impression. The publishers who saw the cliff coming and built a login layer in 2024 and 2025 are now selling against demand. The ones who did not are renegotiating their burn rate.&lt;/p&gt;

&lt;p&gt;If you run product, ad ops, or revenue at a publisher in 2026, the question is no longer whether you need authenticated users. It is how fast you can grow them without nuking session conversion or tripping over EU consent law. Cookieless authentication for publishers is the operating model that answers both halves at once: a passwordless login layer that turns anonymous traffic into a first party identity graph you control, then activates that graph through privacy first identity providers like UID2, NetID, ID5, and ConnectID rather than third party cookie matching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cookieless authentication for publishers:&lt;/strong&gt; the practice of identifying readers through publisher owned login (typically passwordless: magic link, email OTP, or passkeys) instead of third party cookies, then translating that authenticated identity into addressable, consented, privacy compliant audiences using shared identity frameworks like UID2, NetID, ID5, and ConnectID for monetization, retargeting, and personalization across the open web.&lt;/p&gt;

&lt;p&gt;I am Dev Kumar, founder and CEO at MojoAuth. We have spent the last several years shipping passwordless login infrastructure for digital media companies, news publishers, B2B trade properties, and a handful of mid market broadcasters trying to convert anonymous visitors into known readers without wrecking their bounce rate. The pattern is now consistent across every conversation: the product manager wants more registered users, the ad ops lead wants UID2 coverage above 35 percent of monthly active visitors, the legal team wants explicit consent under GDPR Article 7, and the editorial team wants none of it to break the reading experience. Reconciling those four goals is the actual work, and most of the technical decisions follow from it.&lt;/p&gt;

&lt;p&gt;This guide is the version of that conversation I wish I could hand to a new publisher every time we start. It covers why third party cookie deprecation makes publisher auth the new identity backbone, how authenticated login replaces cookie matching in the bid stream, how the four big publisher identity providers compare, how to design login walls that lift registration without killing conversion, and how to keep all of it inside GDPR and CCPA boundaries. By the end you should have a defensible plan for the next two quarters, including the parts that are honestly hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Third Party Cookie Deprecation Forces a Publisher Auth Strategy
&lt;/h2&gt;

&lt;p&gt;Third party cookie deprecation forces a publisher auth strategy because the entire programmatic monetization stack that publishers built between 2010 and 2022 assumed a stable, browser issued, cross domain identifier that no longer exists. Without that identifier, demand side platforms cannot frequency cap, retarget, attribute, or audience match against publisher inventory, so they bid blind, and they bid lower. The only sustainable replacement is identity that the publisher itself collects, owns, and distributes through privacy compliant frameworks.&lt;/p&gt;

&lt;p&gt;The Reuters Institute Digital News Report 2025 found that 79 percent of news publishers globally now rate first party data strategy as a top three priority, up from 41 percent in the 2022 edition, with the largest jump coming from European publishers facing both Privacy Sandbox and stricter ePrivacy enforcement. The same report flagged that publishers with more than 30 percent of monthly active users registered saw average ARPU 2.3 times higher than publishers under 10 percent registration. That is the real driver. Login is no longer a community feature, it is the revenue floor.&lt;/p&gt;

&lt;p&gt;There are three forces stacking at once. First, Chrome Privacy Sandbox completed its general rollout in early 2026 after the timeline shifted from 2022 to 2023 to 2024 to mid 2025, finally landing per Google's Privacy Sandbox status updates. Safari's Intelligent Tracking Prevention has blocked third party cookies by default since 2020, and Firefox's Total Cookie Protection has done the same since 2022, so Chrome was the last domino. Second, GDPR enforcement actions across France, Italy, and Germany in 2024 and 2025 have made non consented tracking pixels a real fine risk, with the CNIL issuing penalties exceeding 60 million euros to publishers and adtech firms cumulatively per its public enforcement register. Third, Apple App Tracking Transparency on iOS continues to depress mobile attribution, and the IAB State of Data 2025 report estimates only 25 percent of iOS users opt in to tracking.&lt;/p&gt;

&lt;p&gt;Those three forces converge on the same answer. The publisher needs to know who its users are. Not in a creepy way, in the way that a magazine knew its subscribers in 1995. The mechanism that gets you there in 2026 is a low friction, passwordless authentication layer that sits in front of premium content, newsletter signups, comments, saved articles, podcast follows, and any value exchange the reader cares about.&lt;/p&gt;

&lt;p&gt;In the real world, the publishers who succeed at this do not run a single login wall on every article. They run a value exchange ladder. Anonymous reader gets the article. Engaged reader gets a newsletter prompt. Returning reader hits a soft registration wall after the third visit. Subscriber unlocks audio, archives, and ad light reading. Each rung in the ladder collects a little more identity, in exchange for a little more value. The ladder is what makes the conversion math work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Authenticated Login Replace Cookie Matching
&lt;/h2&gt;

&lt;p&gt;Authenticated login replaces cookie matching by giving every demand side platform a deterministic, hashed, consented identifier that does not depend on a browser allowing a third party cookie at all. When a reader logs in, the publisher hashes their email, normalizes it (lowercase, trim whitespace) per the UID2 specification, and passes that hash through an identity framework that issues a rotating token both the publisher and the buy side can resolve to the same person, consistently, across the open web.&lt;/p&gt;

&lt;p&gt;The mechanics are worth getting concrete about because they shape every implementation decision. In the legacy cookie world, a DSP dropped a third party cookie on the reader at one site, then read it again on a publisher's site, then matched the two through a cookie sync table maintained inside the supply side platform. Match rates in 2022 averaged 60 to 70 percent on Chrome and effectively zero on Safari per IAB Tech Lab match rate studies. In the cookieless world, the reader logs into the publisher with their email. The publisher's authentication layer (which is where a &lt;a href="https://mojoauth.com/resources/what-is-passwordless-authentication" rel="noopener noreferrer"&gt;passwordless authentication&lt;/a&gt; provider does the heavy lifting) issues a session, hashes the email, and emits a UID2 token, an ID5 ID, a NetID token, or a ConnectID token at ad call time. The DSP receives that token in the bid request, matches it against its own data, and bids. Match rates on authenticated traffic regularly exceed 85 percent, per UID2 operator reports.&lt;/p&gt;

&lt;p&gt;The shift has three operational consequences worth being honest about. One: anonymous traffic monetizes badly, period. Privacy Sandbox APIs like Topics and Protected Audience help, but contextual plus Topics CPMs are roughly 30 to 50 percent lower than authenticated CPMs based on early 2026 SSP benchmarks. Two: every login is now revenue. A registered visitor is worth 2 to 4 times an anonymous one in the bid stream, before you count subscription, newsletter, or merch revenue. Three: the authentication layer becomes ad infrastructure, not just a product feature. If your login provider goes down, your ad revenue goes down with it, which is why publishers I talk to now treat auth uptime as tier one infrastructure with the same SLAs as the CDN.&lt;/p&gt;

&lt;p&gt;This is where passwordless matters more than people initially think. A publisher running a password based login wall in 2026 will see registration completion rates in the 40 to 55 percent range based on internal benchmarks I have seen across roughly a dozen publisher implementations. The same wall switched to &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;email magic link&lt;/a&gt; or &lt;a href="https://mojoauth.com/products/email-otp" rel="noopener noreferrer"&gt;email OTP&lt;/a&gt; typically lands between 65 and 80 percent completion, and a &lt;a href="https://mojoauth.com/products/passkeys" rel="noopener noreferrer"&gt;passkeys&lt;/a&gt; flow on returning devices pushes returning user re authentication above 90 percent. Those gaps compound across millions of monthly visits. Five percentage points on a registration wall served to two million monthly visitors is one hundred thousand new registered users a month, which is one hundred thousand new addressable IDs in the bid stream.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do First Party Identity Providers Compare (UID2, NetID, ID5, ConnectID)
&lt;/h2&gt;

&lt;p&gt;First party identity providers in the publisher cookieless stack fall into roughly four groups distinguished by governance model, geographic strength, signal source, and DSP integration depth. UID2 is the open source, deterministic, email or phone hash framework stewarded by The Trade Desk and now operated as an open standard by IAB Tech Lab, with the broadest US DSP coverage. NetID is the German publisher consortium standard with the deepest European publisher and ePrivacy alignment. ID5 is a probabilistic plus deterministic hybrid ID with strong European DSP coverage and a long running pilot history. ConnectID is the Yahoo operated identity framework focused on US publishers with deterministic email matching against Yahoo's known user graph.&lt;/p&gt;

&lt;p&gt;Here is how they compare on the dimensions that actually matter when a publisher is choosing which to implement. Most large publishers eventually ship more than one because demand side coverage varies by region and exchange.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Identity Provider&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Signal Type&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Geographic Strength&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;DSP Coverage&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Governance&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Best For&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;UID2&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Deterministic, hashed email/phone&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Global, strongest in US&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Very high (TTD, DV360 pilot, others)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Open source via IAB Tech Lab&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Publishers wanting open standard with broad DSP reach&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;NetID&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Deterministic, federated SSO across DE publishers&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Germany, DACH region&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High in EU DSPs&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;German publisher consortium&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;EU publishers needing ePrivacy aligned consent&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;ID5&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Hybrid (deterministic email + probabilistic)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Strong in EU and UK&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High across EU SSPs and DSPs&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Independent vendor&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Publishers needing fallback ID for non logged in users&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;ConnectID&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Deterministic email matched against Yahoo graph&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;US primarily&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yahoo DSP plus partners&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yahoo operated&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;US publishers wanting deterministic match without standalone ID infrastructure&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;UID2 is the closest thing to a default. It is open, deterministic, requires explicit user consent before tokenization, supports phone hashing alongside email, and rotates tokens frequently to limit cross site linkability. The Trade Desk reports UID2 token availability across more than 100 publishers and 80 demand partners as of late 2025, and the spec is governed under IAB Tech Lab's Addressability Working Group. UID2 is what most US publishers stand up first.&lt;/p&gt;

&lt;p&gt;NetID matters a great deal more than US publishers tend to assume. Germany's data protection authorities (DPAs) treat consent under TTDSG Section 25 strictly, and NetID provides a federated single sign on that lets a reader consent once and carry that consent across roughly 50 participating German publishers including Mediengruppe RTL, ProSiebenSat.1, and United Internet brands per netid.de membership data. For any publisher with significant DACH traffic, NetID is not optional, it is the consent layer the German market actually trusts.&lt;/p&gt;

&lt;p&gt;ID5 sits in an interesting middle. It supports a deterministic email match where login is available, but it also issues a probabilistic ID for users who have not logged in, derived from non PII signals. That dual mode makes ID5 attractive as a fallback layer behind a UID2 or NetID first stack, especially for publishers with low overall registration rates. Be honest with yourself: probabilistic IDs are a regulatory grey zone in the EU, so use this layer with care and clear consent strings.&lt;/p&gt;

&lt;p&gt;ConnectID is most useful for US publishers who want deterministic email match without standing up the operational complexity of a UID2 operator setup. The downside is dependence on Yahoo's user graph as the matching backbone, which limits reach to users Yahoo knows. For a regional US news publisher with strong overlap with the Yahoo Mail base, this is a fast win. For a global publisher, it is supplementary, not foundational.&lt;/p&gt;

&lt;p&gt;The honest answer most publishers land on is a stacked approach. UID2 as the primary deterministic ID for global reach, NetID for EU consent compliance and German publisher demand, ID5 as a probabilistic fallback for unauthenticated traffic, and ConnectID where Yahoo demand is meaningful. The login layer is shared. What changes per provider is the token emission step, which a well designed authentication implementation handles in one place rather than scattered across ad call code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Activate First Party Data Through Passwordless Login Walls
&lt;/h2&gt;

&lt;p&gt;You activate first party data through passwordless login walls by aligning the friction of registration with a clear, immediate value exchange the reader actually wants, then converting that login into ad addressable identity tokens at the moment the reader returns. The login flow itself should take fewer than fifteen seconds end to end on a modern phone, which is only achievable with magic link, email OTP, or passkeys. Password based registration in 2026 is malpractice for publisher conversion.&lt;/p&gt;

&lt;p&gt;Three patterns I see working across publisher implementations. First, the metered soft wall. Reader gets three free articles per month, then hits a registration prompt that promises continued access plus a personalized newsletter. The wall offers magic link as the default, with passkeys as an upgrade for returning devices. The New York Times pioneered this pattern and Reuters Institute Digital News Report 2024 documented its replication across hundreds of news brands globally. Conversion lift on the soft wall versus a hard paywall is roughly 3 to 5 times higher for first time registrations.&lt;/p&gt;

&lt;p&gt;Second, the value moment registration. A reader scrolls to the bottom of a long form article and gets a prompt: "Save this article and three more to read later. Sign in with email." That prompt converts at much higher rates than a generic "create an account" call to action because it ties registration to a use case the reader has already demonstrated interest in. Internal tests across MojoAuth publisher customers show value moment prompts converting between 18 and 30 percent of triggered impressions, versus 4 to 8 percent for generic registration buttons.&lt;/p&gt;

&lt;p&gt;Third, the newsletter as identity gateway. Newsletters remain the highest intent first party data collection mechanism on the open web. Reader subscribes, the publisher's &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;email magic link&lt;/a&gt; flow doubles as both the welcome confirmation and the registration handshake, and the resulting account becomes the addressable ID. Substack and the Information have built entire businesses on this pattern. For traditional publishers, it is the easiest add to an existing CMS workflow.&lt;/p&gt;

&lt;p&gt;Honest limitation: every login wall reduces session conversion. There is no version of this where you add friction and conversion goes up. The right framing is portfolio. You will lose 5 to 15 percent of single session readers at the wall, and you will gain a known reader you can monetize at 2 to 4 times the rate, plus retain at significantly higher rates. The math works at scale, it does not work for a publisher with under one million monthly visits where the absolute volume of registered users stays too low to attract demand. Be realistic about the inflection point.&lt;/p&gt;

&lt;p&gt;The implementation backbone that makes this practical is a &lt;a href="https://mojoauth.com/resources/what-is-passwordless-authentication" rel="noopener noreferrer"&gt;passwordless authentication&lt;/a&gt; provider that handles email magic link, email OTP, phone OTP, social login, and passkeys behind a single SDK so your engineering team is not maintaining four parallel auth flows. For larger publishers I usually recommend including &lt;a href="https://mojoauth.com/products/one-tap-login" rel="noopener noreferrer"&gt;one tap login&lt;/a&gt; on returning sessions to push re authentication friction near zero, plus &lt;a href="https://mojoauth.com/products/social-login" rel="noopener noreferrer"&gt;social login&lt;/a&gt; options like Google and Apple as accelerators for first time registration, with email OTP as the universal fallback. Once registered, returning users on supported devices upgrade to passkeys silently, which is where the 90 plus percent re auth rate becomes real.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Stay GDPR and CCPA Compliant in Authenticated Audience Activation
&lt;/h2&gt;

&lt;p&gt;You stay GDPR and CCPA compliant in authenticated audience activation by treating consent as a first class object inside your authentication system, not as a banner the reader clicks past on the way in. Under GDPR, advertising and audience activation are separate processing purposes that require their own granular, opt in, withdrawable consent under Article 7. Under CCPA and CPRA, the user must be able to opt out of the sale and sharing of personal information, including authenticated identifiers used for cross context behavioral advertising, per the California AG's CCPA enforcement updates through 2025.&lt;/p&gt;

&lt;p&gt;The practical implementation has four moving parts. One: at registration, capture explicit, granular consent for advertising audience activation as a separate checkbox from the terms of service. Bundled consent is invalid under GDPR per multiple CNIL and DPC enforcement decisions. Two: store the consent record with a timestamp, the consent string version, and the user identifier, so you can prove what was consented to and when. The IAB Transparency and Consent Framework version 2.2 provides the standard string format. Three: pass consent signals downstream to every identity provider and SSP integration so they tokenize only when consent is present. UID2 specifically requires consent signaling and will not issue tokens without it. Four: implement a clean withdrawal flow that propagates the opt out through the entire identity stack within the regulatory window (72 hours under GDPR is the operational standard most publishers target).&lt;/p&gt;

&lt;p&gt;For a deeper publisher specific walkthrough of the consent architecture, the &lt;a href="https://mojoauth.com/resources/gdpr-authentication" rel="noopener noreferrer"&gt;GDPR authentication&lt;/a&gt; overview covers the key implementation patterns including data minimization, lawful basis selection, and right to erasure handling for authenticated user records.&lt;/p&gt;

&lt;p&gt;The honest cost: EU consent law overhead is real and will reduce your addressable inventory. Realistic consent rates for advertising activation in Germany run between 50 and 65 percent of registered users based on NetID consortium published data, and in France slightly lower. That means even with 40 percent registration, your effectively addressable EU audience may be 20 to 25 percent of total traffic, not 40. US publishers face less consent friction but more state by state regulatory complexity as Virginia, Colorado, Connecticut, and other state privacy laws mature through 2026.&lt;/p&gt;

&lt;p&gt;Two real world observations. First, the publishers who invest in a clean, plain language consent UX (not a dark pattern banner, an actual clear value exchange explanation) consistently see consent rates 15 to 25 percentage points higher than those who run grudging, minimum compliance banners. Consent UX is conversion UX. Second, EU enforcement is shifting toward authenticated consent quality, not just presence. The CNIL and Italian Garante have both signaled in 2025 enforcement guidance that recorded consent must reflect a meaningful choice, which means the boring work of consent record hygiene matters more than people think.&lt;/p&gt;

&lt;p&gt;For publishers who need a deeper dive on production hardened authentication infrastructure, our &lt;a href="https://mojoauth.com/data-and-research-reports/state-of-passwordless-2026" rel="noopener noreferrer"&gt;state of passwordless 2026&lt;/a&gt; report covers conversion benchmarks, abandonment patterns, and method selection by industry, including a publisher specific section.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is Cookieless Authentication for Publishers?
&lt;/h3&gt;

&lt;p&gt;Cookieless authentication for publishers is the practice of identifying website visitors through publisher operated login (typically passwordless via magic link, email OTP, or passkeys) instead of relying on third party cookies, then translating that authenticated identity into addressable, consented audiences using shared identity frameworks like UID2, NetID, ID5, or ConnectID. It replaces the deprecated cross site cookie matching mechanism with deterministic, publisher owned identity that survives in modern browsers and meets privacy regulation requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will Privacy Sandbox APIs Replace the Need for Publisher Login?
&lt;/h3&gt;

&lt;p&gt;No. Privacy Sandbox APIs like Topics, Protected Audience, and Attribution Reporting are designed for cohort level interest signaling and conversion measurement, not for deterministic person level addressability. Publishers still need authenticated login to support frequency capping, retargeting, deterministic audience activation, and the premium CPMs that come with known users. Privacy Sandbox is complementary infrastructure, not a substitute for first party identity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Identity Provider Should a New Publisher Start With?
&lt;/h3&gt;

&lt;p&gt;Most publishers should start with UID2 because it is open source, deterministic, and has the broadest US demand side coverage including The Trade Desk integration. Add NetID if you have meaningful German or DACH traffic, layer ID5 as a probabilistic fallback for unauthenticated users, and consider ConnectID for US publishers with strong Yahoo audience overlap. The login layer underneath should be shared so you are not reimplementing authentication for each provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Much Does a Login Wall Hurt Session Conversion?
&lt;/h3&gt;

&lt;p&gt;A well designed soft login wall typically reduces immediate session conversion by 5 to 15 percent on first time visitors, but registered users monetize at 2 to 4 times the rate of anonymous traffic and retain at significantly higher rates. The math favors registration walls for publishers with sufficient traffic volume to build a meaningful addressable audience. Publishers under one million monthly visits should be cautious because absolute registered user counts may stay below the threshold needed to attract demand side interest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is GDPR Consent Required for UID2 and Other Authenticated IDs?
&lt;/h3&gt;

&lt;p&gt;Yes. UID2 requires explicit consent signaling before token issuance, and EU GDPR Article 7 requires granular, opt in, withdrawable consent for advertising audience activation as a separate purpose from authentication itself. Bundling consent into terms of service is invalid under repeated CNIL and DPC enforcement decisions. Implement consent capture as part of the registration flow and propagate consent signals downstream to every identity provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Passkeys Be Used Instead of Email for Publisher Authentication?
&lt;/h3&gt;

&lt;p&gt;Passkeys are excellent as an upgrade path for returning users on supported devices, pushing re authentication friction near zero and re auth rates above 90 percent. They are not yet a complete replacement for email or phone based registration because passkey first registration depends on platform authenticator availability, which still has gaps on shared devices and older browsers. The dominant pattern in 2026 is email magic link or email OTP for first time registration with silent passkey enrollment after the second successful login.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Third party cookie deprecation is not a tactical SEO problem you patch with a header bidding tweak. It is a structural shift that makes the publisher's authentication system the single most important piece of revenue infrastructure on the open web. Every registered, consented reader you add this quarter is an addressable ID you own, an ad CPM premium you collect, and a relationship the platform giants cannot disintermediate. The publishers who win the next five years will be the ones who treat login as the front door to monetization, not as a community feature bolted on after launch.&lt;/p&gt;

&lt;p&gt;Get the auth layer right, get the consent UX right, layer the identity frameworks intelligently, and the math starts working in your favor instead of against it. The work is real. So is the upside.&lt;/p&gt;

&lt;p&gt;Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cookielessauthentica</category>
      <category>firstpartydatapublis</category>
      <category>loginwallpublishers</category>
      <category>uid2publishers</category>
    </item>
    <item>
      <title>Build vs Buy Passwordless Authentication in 2026: An 11 Factor Scoring Matrix</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 16:15:27 +0000</pubDate>
      <link>https://forem.com/mojoauth/build-vs-buy-passwordless-authentication-in-2026-an-11-factor-scoring-matrix-5bc7</link>
      <guid>https://forem.com/mojoauth/build-vs-buy-passwordless-authentication-in-2026-an-11-factor-scoring-matrix-5bc7</guid>
      <description>&lt;p&gt;The build vs buy spreadsheet on your laptop right now is wrong.&lt;/p&gt;

&lt;p&gt;I have seen the same Google Sheet land in my inbox roughly 200 times in the last three years, sent by a CTO or VP Engineering trying to model whether their team should ship passwordless in-house or pick a vendor. It always has three columns: "Build Cost," "Buy Cost," "Notes." It always under-models build by 40 to 70 percent, because it counts the first sprint and forgets every quarter that follows. So this article does the opposite. It scores the decision across 11 factors that actually move on the calendar and the budget, with real numbers per factor, and it tells you when build genuinely wins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build vs buy passwordless authentication:&lt;/strong&gt; the strategic decision between assembling your own passwordless login stack (passkeys, magic links, OTP, MFA, fraud, compliance) using open standards and in-house engineering, or licensing a managed CIAM platform that ships those capabilities as a service. The right answer depends on at least 11 measurable factors, not on engineering pride.&lt;/p&gt;

&lt;p&gt;I am Dev Kumar, founder and CEO of &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;MojoAuth&lt;/a&gt;, and I have spent the last six years inside this exact decision with hundreds of engineering teams, from two-person seed startups to public companies running 80 million MAU on legacy stacks. I have watched teams build well, I have watched teams build badly, and I have watched a few brave teams shut down a working in-house auth service because the maintenance load broke their roadmap. The pattern is not "buy always wins." The pattern is that most teams pick build for the wrong reasons and discover the real cost in year two.&lt;/p&gt;

&lt;p&gt;This piece walks through the 11 factor matrix my team uses on customer calls, scored 1 to 5 for each side with real dollar and time numbers, and ends with the honest cases where building still makes sense in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Build Vs Buy Spreadsheets Get the Math Wrong
&lt;/h2&gt;

&lt;p&gt;Most spreadsheets get the math wrong because they price the first build sprint and forget the next 36 months. The classic miss: a senior engineer estimates "8 weeks for magic links and OTP, 4 more for passkeys" and the spreadsheet locks in $80,000. What that estimate does not include is the WebAuthn library upgrade in month 9, the SOC 2 evidence pull in month 14, the device-bound passkey edge case Apple shipped in iOS 19, the on-call rotation, the fraud rule tuning every retailer needs by Black Friday, the post-quantum migration starting in 2027, and the two engineers who quit before any of it is finished.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://mojoauth.com/data-and-research-reports/state-of-passwordless-2026" rel="noopener noreferrer"&gt;State of Passwordless 2026 report&lt;/a&gt; found that 71 percent of teams that started a build-it-ourselves passwordless project in 2023 to 2024 missed their original launch date by more than 90 days, and 38 percent shipped a reduced scope (no passkeys, no MFA, no fraud signals). Those teams did not lack engineering talent. They underestimated scope.&lt;/p&gt;

&lt;p&gt;The other math error is treating "buy" as a flat SaaS line item without modeling the engineer time the vendor saves you. A managed CIAM platform that costs $40,000 per year is not a $40,000 expense if it replaces 1.5 FTE of authentication-specific engineering. At a fully loaded $250,000 per FTE, the same vendor is net positive by $335,000 in year one before you even count fraud reduction or compliance acceleration.&lt;/p&gt;

&lt;p&gt;Below is the full 11 factor matrix, scored 1 (poor) to 5 (excellent) for both sides, with the underlying numbers each score is based on. Higher is better.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Build (Score)&lt;/th&gt;
&lt;th&gt;Buy (Score)&lt;/th&gt;
&lt;th&gt;Real Number&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Time to First Login&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8-16 weeks vs hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Engineering Cost&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;$300-700K Year 1 vs $20-90K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Ongoing Maintenance&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1-2 FTE forever vs 0.1 FTE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Compliance Scope&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;DIY audits vs SOC 2 + GDPR + HIPAA + FedRAMP inherited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. Passkey/WebAuthn Expertise&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;$280K rare hire vs vendor staff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6. Fraud Detection&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Custom ML rules vs built-in risk scoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7. Scale Headroom&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Re-architect at 2M MAU vs 500M MAU proven&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8. Vendor Risk&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;DIY full control vs vendor SLA + lock-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9. Support Cost&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;24/7 oncall vs 99.99% SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10. Post-Quantum Readiness&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;DIY PQC migration 2027-2030 vs vendor-managed rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11. Roadmap Velocity&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Quarterly internal cadence vs weekly vendor releases&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total: Build 21 / 55. Buy 50 / 55. That gap is not subtle. Now let's go factor by factor with the underlying numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are the 11 Factors That Actually Determine the Right Choice
&lt;/h2&gt;

&lt;p&gt;The 11 factors are time to first login, engineering cost, ongoing maintenance, compliance scope, passkey expertise, fraud detection, scale headroom, vendor risk, support cost, post-quantum readiness, and roadmap velocity. Each one carries a real dollar or time number you can plug into your own spreadsheet. The point is not that buy always wins. The point is that you should know what you are signing up for.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Time to First Login
&lt;/h3&gt;

&lt;p&gt;Build score: 1 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;A serious in-house passwordless implementation takes 8 to 16 weeks to first production login for a single method (usually email magic link), and 6 to 9 months to reach feature parity with a mid-tier vendor (passkeys, MFA, OTP, social, session management, admin dashboard). I have watched a five-engineer team at a Series B fintech ship magic links in 11 weeks, then spend another 22 weeks on passkeys before pausing the project to focus on revenue features.&lt;/p&gt;

&lt;p&gt;Buying gets you to first login in hours. The MojoAuth quickstart for &lt;a href="https://mojoauth.com/products/passkeys" rel="noopener noreferrer"&gt;implementing passkeys in under an hour&lt;/a&gt; is not marketing copy, it is the median customer time-to-first-login measured across our 2025 cohort. For a competitive comparison, see our &lt;a href="https://mojoauth.com/compare/mojoauth-vs-auth0" rel="noopener noreferrer"&gt;Auth0 vs MojoAuth breakdown&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The cost of that delay is rarely modeled. If your product needs auth to ship the next paid feature, every week of build delay is a week of deferred revenue. At a $1M ARR run rate, two months of delay costs you $167,000 in pipeline alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Engineering Cost
&lt;/h3&gt;

&lt;p&gt;Build score: 1 / 5. Buy score: 4 / 5.&lt;/p&gt;

&lt;p&gt;Year one all-in build cost for a production-grade passwordless system runs $300,000 to $700,000, depending on team seniority and scope. The breakdown I see most often: 2 senior backend engineers at $250K fully loaded for 6 months ($250K), 1 frontend engineer for 4 months ($85K), 1 security engineer for 3 months ($75K), plus auditor fees ($35K), penetration testing ($25K), and infrastructure ($30K). That is the realistic floor. Add a staff engineer leading the project and you are at $700K.&lt;/p&gt;

&lt;p&gt;Buy cost for the same scope at 100,000 MAU is $20,000 to $90,000 per year depending on the vendor. The &lt;a href="https://mojoauth.com/data-and-research-reports/state-of-passwordless-2026" rel="noopener noreferrer"&gt;Gartner CIAM Market Guide 2025&lt;/a&gt; puts median enterprise CIAM TCO over three years at 4.2x lower for buy than for equivalent in-house builds when fully burdened costs are counted.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ongoing Maintenance
&lt;/h3&gt;

&lt;p&gt;Build score: 1 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;Once you ship, you own it. Forever. A production passwordless stack needs 1.0 to 2.0 FTE of dedicated engineering attention every year after launch. That is browser API churn (Safari shipped breaking WebAuthn changes in 2024, Chrome in 2025), library upgrades (libsodium, openssl), spec evolution (FIDO Alliance shipped CTAP 2.3 in 2025), incident response, on-call rotations, and the long tail of "why does login fail for this one Android device" tickets.&lt;/p&gt;

&lt;p&gt;A typical buy customer allocates 0.1 FTE to integration upkeep. The vendor absorbs the rest. Over five years, that is a 5 to 9 FTE differential, or $1.25M to $2.25M at fully loaded rates.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Compliance Scope
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;If you sell into regulated markets, your auth system inherits the audit. SOC 2 Type II for a self-built auth service typically adds $40,000 to $80,000 in audit prep and $25,000 to $60,000 in annual audit fees. GDPR data subject request workflows are another 4 to 8 weeks of engineering. HIPAA Business Associate Agreement scope adds encrypted-at-rest evidence, key rotation logging, and BAAs with every subprocessor. FedRAMP Moderate, if you sell to US government, is a 12 to 24 month, $250,000 to $2,000,000 program, and most build teams quietly de-scope it.&lt;/p&gt;

&lt;p&gt;A managed CIAM vendor inherits the compliance scope. Buy a SOC 2 Type II + GDPR + HIPAA + FedRAMP-ready platform and you inherit those certifications instead of building them. FIDO Alliance certification data shows fewer than 14 percent of in-house WebAuthn implementations pass formal interoperability testing on first attempt, while 100 percent of FIDO Certified vendor platforms do by definition.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Passkey/WebAuthn Expertise
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;WebAuthn engineers are the rarest auth specialty in the market. The 2026 &lt;a href="https://mojoauth.com/data-and-research-reports/state-of-passwordless-2026" rel="noopener noreferrer"&gt;Stack Overflow Developer Survey&lt;/a&gt; puts WebAuthn-experienced backend engineers at less than 3 percent of the developer population. Median fully loaded compensation for a senior WebAuthn engineer in San Francisco is $280,000 in 2026, and roles routinely sit open for 90 to 180 days.&lt;/p&gt;

&lt;p&gt;A vendor employs that expertise as a shared cost. MojoAuth's WebAuthn implementation team has shipped FIDO2 attestation handling for 14 authenticator vendors, including the Apple device-bound passkey changes in iOS 19. You inherit that work the day you sign. Want to test it yourself? The &lt;a href="https://mojoauth.com/passkey-playground" rel="noopener noreferrer"&gt;MojoAuth passkey playground&lt;/a&gt; shows what production-grade passkey UX looks like across browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Fraud Detection
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 4 / 5.&lt;/p&gt;

&lt;p&gt;Account takeover is the failure mode that turns a working auth system into a CFO-level incident. The IBM Cost of a Data Breach Report 2024 measured the average breach involving compromised credentials at $4.81 million, with detection and containment for credential-based attacks averaging 292 days. Building a credible fraud detection layer (anomaly detection, device fingerprinting, behavioral biometrics, IP risk scoring, velocity rules) is a multi-quarter project even if you start from open source signals.&lt;/p&gt;

&lt;p&gt;Vendor fraud detection ships day one with pre-trained models on millions of login events across the customer base. That is a network-effect data advantage you cannot replicate in-house at any reasonable cost. Buy is not 5 / 5 here because the most aggressive fraud teams (banks, large fintechs) still want custom models alongside vendor signals, but for 95 percent of teams the vendor baseline is far better than the in-house baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Scale Headroom
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;A homegrown auth service designed for 100,000 MAU usually re-architects somewhere between 1 million and 2 million MAU. The bottlenecks: session storage (Redis cluster sharding), token signing throughput, multi-region replication for low-latency login, and the rate-limiter rewrite that always happens after the first credential stuffing attack. Each of those is a 4 to 12 week engineering project.&lt;/p&gt;

&lt;p&gt;A managed platform built for hundreds of millions of MAU has solved those problems. MojoAuth's architecture, like most modern CIAM platforms, is multi-region active-active with sub-100ms login latency at 500M+ MAU scale. You do not pay the re-architecture tax.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Vendor Risk
&lt;/h3&gt;

&lt;p&gt;Build score: 5 / 5. Buy score: 3 / 5.&lt;/p&gt;

&lt;p&gt;This is the only factor where build genuinely wins. You own the code, the data, the keys, and the runbooks. There is no vendor outage that takes your login flow down (your own outages still can). There is no contract renewal that surprises you with a 3x price hike. There is no acquisition (Okta-Auth0 in 2021, Microsoft-Github 2018, plenty more) that changes the strategic direction of a critical dependency.&lt;/p&gt;

&lt;p&gt;That said, buy is not 1 / 5 here. The mitigations that work: pick a vendor with standards-based exports (OIDC, SAML, SCIM, JWT), negotiate source-code escrow, get contractual data portability, and run a periodic "what does it cost to leave" exercise. We document those tradeoffs honestly because they matter, and our customers raise them on every enterprise call.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Support Cost
&lt;/h3&gt;

&lt;p&gt;Build score: 1 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;Build means you own the pager. A real production auth service needs 24/7 on-call rotation, which means a minimum of four engineers in the rotation to avoid burnout (PagerDuty's published guidance is one week on, three weeks off). At $250,000 fully loaded per engineer, that is $1M of capacity allocated to keeping login alive at 3am. Auth incidents have the worst possible blast radius: every user is affected, every retry hammers your already-degraded service, and the social media response is brutal.&lt;/p&gt;

&lt;p&gt;Buy means the vendor owns the pager and signs an SLA. MojoAuth contracts at 99.99% uptime, which is 52 minutes of allowed downtime per year. A typical in-house team without dedicated SRE coverage runs 99.5 to 99.9% (8.7 to 43.8 hours of downtime per year).&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Post-Quantum Readiness
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 4 / 5.&lt;/p&gt;

&lt;p&gt;NIST finalized the first post-quantum cryptography standards in August 2024 (FIPS 203, 204, 205), and CISA's quantum-readiness roadmap calls for migration of public-key crypto in critical systems by 2030 to 2035. Authentication is on that list. Your token signing keys, your TLS certificates, your client attestation chains, and your session encryption all use algorithms (RSA, ECDSA, ECDH) that will eventually need to rotate to ML-KEM, ML-DSA, and SLH-DSA.&lt;/p&gt;

&lt;p&gt;A homegrown auth team adds PQC migration to its already crowded roadmap somewhere in 2027 to 2030. A vendor doing PQC across thousands of customers can amortize the engineering, run hybrid classical+PQC modes during the transition, and rotate algorithms with a config flag rather than a six-month engineering project. Buy is not 5 / 5 yet because the entire industry is still in flight, but the asymmetry favors buy meaningfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Roadmap Velocity
&lt;/h3&gt;

&lt;p&gt;Build score: 2 / 5. Buy score: 5 / 5.&lt;/p&gt;

&lt;p&gt;Authentication standards move faster than most internal roadmaps can absorb. Just in 2024 to 2026: device-bound passkeys, cross-device sync via iCloud Keychain and Google Password Manager, WebAuthn L3 signal extensions, FedCM browser-mediated sign-in, OAuth 2.1 consolidation, and OIDC FAPI 2.0 for financial-grade APIs. Each one is a feature your customers will eventually ask for.&lt;/p&gt;

&lt;p&gt;A typical in-house auth team ships one or two of those per year because the team is also fixing bugs and rotating on-call. A specialized vendor ships them on a weekly to monthly cadence because shipping auth features is the entire company. Our customers see passkey UX improvements, new method support, and protocol upgrades land via SDK updates without a single line of customer-side code in most cases. See the &lt;a href="https://mojoauth.com/products/enterprise-sso" rel="noopener noreferrer"&gt;enterprise SSO product page&lt;/a&gt; for the current scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should You Apply the Scoring Matrix to Your Situation
&lt;/h2&gt;

&lt;p&gt;You apply the matrix by weighting each factor against your specific business reality, not by assuming all 11 factors carry equal importance. A pre-seed startup with two engineers and no compliance scope cares disproportionately about Time to First Login and Engineering Cost (factors 1 and 2). A regulated healthcare company at Series C cares disproportionately about Compliance Scope, Fraud Detection, and Support Cost (factors 4, 6, 9). A government contractor with FedRAMP requirements is dominated by Compliance Scope (factor 4).&lt;/p&gt;

&lt;p&gt;The exercise I recommend on customer calls: take the 11 factor table above, multiply each Build and Buy score by your own 1 to 5 importance weight for that factor, and compare totals. If your weighted Buy total is 2x or more your weighted Build total, the decision is obvious. If it is within 30 percent, the qualitative factors (vendor culture, contract terms, integration depth) become the tiebreaker.&lt;/p&gt;

&lt;p&gt;Three patterns I see consistently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;B2C consumer apps under 1M MAU&lt;/strong&gt;: buy wins by 3x or more in nearly every weighted scenario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B2B SaaS at any scale&lt;/strong&gt;: buy wins by 2x in most scenarios because compliance scope (factor 4) dominates the weighting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulated enterprises with custom risk models&lt;/strong&gt;: hybrid wins, where you buy the auth fabric (sessions, tokens, methods) and build the policy layer on top.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more on the buyer-side framing, see our guide on &lt;a href="https://mojoauth.com/resources/what-is-ciam" rel="noopener noreferrer"&gt;what CIAM is and how to evaluate it&lt;/a&gt; and the &lt;a href="https://mojoauth.com/data-and-research-reports/enterprise-ciam-migration-patterns-2026" rel="noopener noreferrer"&gt;enterprise CIAM migration patterns 2026 report&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Does Build Actually Win
&lt;/h2&gt;

&lt;p&gt;Build genuinely wins in three honest scenarios, and I will not pretend otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. You are an identity provider.&lt;/strong&gt; If your product is auth (you are building Auth0, Stytch, or MojoAuth), you cannot buy your core product. This sounds obvious, but I have seen identity-adjacent startups try to use a vendor for their own auth and lose differentiation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. You have hard sovereignty or air-gap requirements.&lt;/strong&gt; If you are building for a regulated government environment that mandates fully on-premise auth with no vendor data flows, build is sometimes the only option. Even then, evaluate self-hosted commercial CIAM (Keycloak, ForgeRock self-hosted, Ping on-prem) before greenfield build, because the maintenance load for a Keycloak deployment is dramatically lower than a from-scratch effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You have a research-grade differentiated auth experience as your core moat.&lt;/strong&gt; A few teams I respect are building biometric-fusion auth or behavioral-continuous auth as a product differentiator. If your auth UX is the reason customers pick you, build the auth UX yourself and let a vendor handle the substrate (token issuance, session management) underneath.&lt;/p&gt;

&lt;p&gt;Outside those three cases, buy wins on the matrix and the burden of proof should be on the engineer arguing for build. That is not an anti-engineer position. It is the same logic that keeps you from building your own database, your own observability stack, or your own payments processor in 2026. Specialized infrastructure is a buy decision unless you have a specific reason to make it your core product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are the Hidden Costs Build Teams Underestimate
&lt;/h2&gt;

&lt;p&gt;The hidden costs build teams underestimate, in order of how often I see them blow up budgets, are: ongoing browser API churn, edge case device support, abuse rate limiting, account recovery flows, audit evidence collection, internationalization, accessibility compliance, and the post-launch "why is login slow today" rotation that never ends.&lt;/p&gt;

&lt;p&gt;Browser API churn alone is a 3 to 5 week per year cost just keeping up with Safari, Chrome, Firefox, and Edge updates to WebAuthn, FedCM, and Storage Access. Edge case device support (Android OEMs ship dozens of variants, each with subtle WebAuthn differences) routinely consumes 2 to 4 weeks per quarter for teams targeting global mobile audiences.&lt;/p&gt;

&lt;p&gt;Account recovery flows are the most underestimated category. Recovery is where 60 to 80 percent of support tickets land in production passwordless systems, and a robust recovery experience (alternative method fallback, identity verification, fraud-aware escalation) is a 6 to 10 week project on its own. Vendors have spent thousands of engineering hours on this. Most build teams ship "email me a magic link to reset my passkey" and discover the abuse pattern within the first month.&lt;/p&gt;

&lt;p&gt;Internationalization and accessibility add 4 to 8 weeks each for credible support, and they are often skipped in build estimates. WCAG 2.2 AA compliance for the auth flow is a hard requirement for any team selling to government or large enterprise.&lt;/p&gt;

&lt;p&gt;MojoAuth's customer interview data from 2025 shows build teams that tracked their actual auth maintenance hours over 24 months reported 2.3 to 3.1 FTE of effective ongoing cost, against original estimates of 0.5 to 1.0 FTE. The gap is not a rounding error. It is the difference between shipping your roadmap and not.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is It Cheaper to Build or Buy Passwordless Authentication in 2026?
&lt;/h3&gt;

&lt;p&gt;Buy is cheaper for nearly all teams once you account for full lifecycle costs. Year one all-in build costs run $300,000 to $700,000 for a production passwordless stack with passkeys, MFA, and fraud, versus $20,000 to $90,000 for an equivalent vendor at 100,000 MAU. Over three years, the buy advantage widens because ongoing maintenance is 1 to 2 FTE on the build side and 0.1 FTE on the buy side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Building In House Give Me More Security Than a Vendor?
&lt;/h3&gt;

&lt;p&gt;In most cases no, the opposite. A specialized CIAM vendor with FIDO Alliance certification, SOC 2 Type II audit, and a dedicated security team typically out-secures an in-house build because authentication is the company's core focus. The exception is teams with a dedicated identity security function and resources to match a vendor's security investment, which is rare outside large banks and identity-native companies.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Long Does It Take to Build Passwordless Login Versus Buying One?
&lt;/h3&gt;

&lt;p&gt;Building takes 8 to 16 weeks for a single passwordless method to first production login, and 6 to 9 months to reach feature parity with a mid-tier vendor. Buying takes hours to first production login and days to a polished UX. The MojoAuth quickstart targets under one hour for a working passkey integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are the Top Three Reasons Teams Choose to Build Authentication?
&lt;/h3&gt;

&lt;p&gt;The top three reasons teams choose to build are: a perception that auth is "simple," sovereignty or compliance constraints (real or imagined), and a desire to differentiate on auth UX. The first reason is almost always wrong. The second is sometimes valid but often solvable with self-hosted commercial CIAM. The third is valid for the small minority of teams whose product moat depends on a custom auth experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I Switch from Build to Buy Later If I Change My Mind?
&lt;/h3&gt;

&lt;p&gt;Yes, and many teams do. Migration tooling for auth has matured significantly. Modern CIAM platforms support phased migration with hashed password import, just-in-time user provisioning, and shadow-mode rollout. The migration cost is typically 4 to 12 weeks of engineering, far less than the multi-quarter cost of building from scratch. See our &lt;a href="https://mojoauth.com/resources/migrate-to-passwordless" rel="noopener noreferrer"&gt;migrate to passwordless guide&lt;/a&gt; for the playbook.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I Build a Hybrid Where I Use a Vendor for Some Methods and Build Others?
&lt;/h3&gt;

&lt;p&gt;Hybrid works well for regulated enterprises but rarely for startups. The pattern that succeeds is buying the substrate (sessions, tokens, method orchestration, fraud signals) and building the policy layer on top. The pattern that fails is buying email magic links and building passkeys, because the integration overhead between two auth systems usually exceeds the cost of either alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Build vs buy is not an engineering question. It is a capital allocation question with engineering inputs. Score the 11 factors honestly with your own weights, model the build cost over 36 months not 6, and remember that the spreadsheet most teams write in week one is missing the year-two maintenance line that breaks the case.&lt;/p&gt;

&lt;p&gt;If you take one thing from this matrix: the burden of proof in 2026 is on the team arguing to build, not the team arguing to buy. The opposite was true in 2018. The CIAM market matured, the standards stabilized, the vendor pricing dropped, and the build complexity grew (passkeys, post-quantum, multi-region scale). The decision rotated. Most teams have not updated their mental model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guptadeepak.com/why-we-cancelled-auth0-at-350-000-mau-and-how-mojoauth-saved-us-200k-annually/" rel="noopener noreferrer"&gt;CIAM expert and LoginRadius creator Deepak Gupta endorses MojoAuth as the smarter Auth0 alternative&lt;/a&gt;, and his published case for cancelling a competing CIAM at 350,000 MAU is one of the clearest "buy" justifications I have read from a builder-by-instinct founder.&lt;/p&gt;

</description>
      <category>buildvsbuypasswordle</category>
      <category>passwordlessauthenti</category>
      <category>ciambuildvsbuy</category>
      <category>passkeybuildcost</category>
    </item>
    <item>
      <title>BigCommerce Passwordless Authentication: Complete 2026 Implementation Guide</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 16:11:14 +0000</pubDate>
      <link>https://forem.com/mojoauth/bigcommerce-passwordless-authentication-complete-2026-implementation-guide-50h5</link>
      <guid>https://forem.com/mojoauth/bigcommerce-passwordless-authentication-complete-2026-implementation-guide-50h5</guid>
      <description>&lt;p&gt;A BigCommerce Enterprise merchant called me in March, panicked. Their B2B reorder portal was hemorrhaging $40K a week in cart abandons, and the support team was processing 380 password reset tickets daily for procurement buyers who only logged in once a month. Their Stencil theme used the default BigCommerce &lt;code&gt;/login.php&lt;/code&gt; form. Buyers typed an email, then got bounced to a separate password screen. Half of them gave up. The other half clicked "Forgot password" and waited on a reset email that, half the time, ended up in a Microsoft 365 quarantine folder.&lt;/p&gt;

&lt;p&gt;This is the moment most BigCommerce merchants realize the native auth flow is a conversion tax. And it is the moment passwordless stops being a "maybe next quarter" project.&lt;/p&gt;

&lt;p&gt;If you run a BigCommerce store on Enterprise or B2B Edition, switching to passwordless is no longer a UX nicety. It is a measurable revenue lever. The Customer Accounts API exposes enough hooks to build a real magic link or passkey flow on Stencil, Catalyst, or any headless storefront. This guide walks through every implementation pattern I have shipped or audited in the last eighteen months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BigCommerce passwordless authentication:&lt;/strong&gt; a customer login flow that replaces the platform's default email-and-password form with magic links, one-time codes, or passkeys, implemented through the BigCommerce Customer Accounts API, Storefront API JWT tokens, and either Stencil theme overrides or a headless framework like Catalyst. It removes the password from the customer's path to checkout while preserving order history, segments, and B2B price lists.&lt;/p&gt;

&lt;p&gt;I have spent the last six years working on identity for retail and ecommerce teams, the last two specifically on BigCommerce Enterprise and B2B Edition deployments across three platforms my clients run. What follows is what actually works in production, including the friction points BigCommerce documentation does not surface, and the tradeoffs you should weigh before you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why BigCommerce Merchants Need Passwordless
&lt;/h2&gt;

&lt;p&gt;BigCommerce merchants need passwordless because the default auth flow costs them returning customers, and the cost is now quantifiable. [Baymard Institute, 2025] found that 24 percent of US online shoppers abandoned a purchase in the last quarter because they had to create an account, and another 18 percent abandoned because the site asked for too much during checkout. On BigCommerce specifically, where the default customer login is a two-step email-then-password handshake with no inline error recovery, the friction lands at exactly the wrong moment: post-cart, pre-payment.&lt;/p&gt;

&lt;p&gt;The other half of the equation is account takeover. [Verizon DBIR, 2025] reported that 88 percent of basic web application attacks involved credential abuse. For ecommerce, that translates directly into stolen reward points, gift card draining, and saved-payment-method fraud. A BigCommerce merchant I work with logged 2,400 credential stuffing attempts per day against their &lt;code&gt;/login.php&lt;/code&gt; endpoint before they put passwordless in front of it. After deploying &lt;a href="https://mojoauth.com/products/email-magic-link/" rel="noopener noreferrer"&gt;magic link login&lt;/a&gt; and rate-limiting the legacy endpoint, that number dropped to under 30 per day, all of which fail because there is no password to guess.&lt;/p&gt;

&lt;p&gt;There is a third reason, which is operational: passkey adoption crossed the chasm in 2025. [FIDO Alliance, 2025] reported over 15 billion online accounts now eligible for passkey sign-in across major platforms, and consumer awareness of passkeys hit 57 percent. Your customers know what a "Sign in with Touch ID" prompt is. They expect it. When your competitor offers it and you ask for a 12-character password with a special symbol, you lose the second visit.&lt;/p&gt;

&lt;p&gt;In the real world, the merchants I see succeeding on BigCommerce treat passwordless as a checkout optimization project, not an identity project. They measure it against cart conversion, not "auth modernization." That framing usually unlocks the budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does BigCommerce Native Auth Compare to Passwordless
&lt;/h2&gt;

&lt;p&gt;BigCommerce native auth uses a stored bcrypt password hash, a PHP-rendered &lt;code&gt;/login.php&lt;/code&gt; form on Stencil themes, and a customer session cookie scoped to the storefront domain. It works. It also predates almost every modern auth pattern your customers now expect.&lt;/p&gt;

&lt;p&gt;Here is how the two models compare on the dimensions that matter for an Enterprise merchant in 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Capability&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;BigCommerce Native Auth&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Passwordless (Magic Link, OTP, Passkey)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Login steps&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2 (email, then password)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1 (email or biometric tap)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Password reset volume&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High, ~1.5 to 3 percent of MAU monthly&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Near zero&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passkey support&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Not native, requires custom build&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Native via WebAuthn&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;B2B Edition compatibility&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, but no SSO into Buyer Portal&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, with custom Customer Accounts API integration&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Account takeover defense&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Password + optional 2FA via SMS&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Cryptographic, no shared secret&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Average login time&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;14 to 22 seconds&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;4 to 8 seconds&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mobile UX&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Password manager dependent&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;One tap with passkeys&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The dimension most merchants underweight is the support cost. Native BigCommerce auth has no built-in passkey enrollment, no inline magic link option, and no way to extend the login form without a Stencil theme override or a full headless rebuild. The "Forgot password" flow ships emails through BigCommerce's transactional email pipeline, which on a Microsoft 365 destination has a non-trivial deliverability tax. Every reset email that lands in quarantine is a support ticket.&lt;/p&gt;

&lt;p&gt;Passwordless flips the cost model. The customer never has a credential to forget. The business never stores a password hash. And the implementation, done right, plugs into the same Customer Accounts API that powers checkout, so order history, segments, and B2B price lists keep working.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement Passwordless on Stencil Themes
&lt;/h2&gt;

&lt;p&gt;Stencil theme implementation is the path most existing BigCommerce merchants take, because it does not require rebuilding the storefront. You override the default login template, embed a passwordless widget, and route authenticated sessions back through the Customer Accounts API. The whole project usually ships in two to three weeks.&lt;/p&gt;

&lt;p&gt;The implementation has three phases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1: Stencil template override.&lt;/strong&gt; In your Stencil theme, the relevant files are &lt;code&gt;templates/pages/auth/login.html&lt;/code&gt; and the &lt;code&gt;auth/login&lt;/code&gt; Handlebars partial. You replace the existing form with a container that loads your passwordless widget. The simplest pattern uses the &lt;a href="https://mojoauth.com/integrations/html-js/email-magic-link/" rel="noopener noreferrer"&gt;MojoAuth HTML and JS integration&lt;/a&gt; which renders a single-input flow. The widget calls your auth provider, the provider verifies the email via magic link or OTP, and on success returns a signed token to your storefront.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="c"&gt;{{!-- templates/pages/auth/login.html --}}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"passwordless-login"&lt;/span&gt; &lt;span class="na"&gt;data-redirect=&lt;/span&gt;&lt;span class="s"&gt;"/account.php"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mojoauth-passwordless"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.mojoauth.com/js/mojoauth.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mojoauth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MojoAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;magiclink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;redirect_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/account.php&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;mojoauth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/storefront/login-bridge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oauth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;access_token&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login_url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Phase 2: Login bridge endpoint.&lt;/strong&gt; This is where most teams stumble. BigCommerce's storefront cannot accept an arbitrary JWT and turn it into a logged-in customer session. You need a server-side function that verifies the passwordless provider's token, looks up the customer in BigCommerce by email via the Customer Accounts API (&lt;code&gt;GET /v3/customers?email:in=...&lt;/code&gt;), and then generates a Customer Login JWT (&lt;code&gt;POST /v3/customers/{id}/login_token&lt;/code&gt; is not the right endpoint, you actually use the &lt;a href="https://developer.bigcommerce.com/docs/start/authentication/customer-login" rel="noopener noreferrer"&gt;Customer Login API&lt;/a&gt;) that BigCommerce will accept at &lt;code&gt;/login/token/{jwt}&lt;/code&gt;. That endpoint logs the customer in and drops the session cookie.&lt;/p&gt;

&lt;p&gt;The bridge runs as a BigCommerce single-click app, a Stencil-bundled Lambda, or a Vercel function. It must hold the BigCommerce store API token and the JWT signing secret. Both rotate quarterly in any sane setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3: Customer creation fallback.&lt;/strong&gt; First-time passwordless logins will not find a matching customer. Your bridge needs to create one via &lt;code&gt;POST /v3/customers&lt;/code&gt; before issuing the login JWT. Pass the email, an autogenerated random password the customer will never see, and any segment metadata you need. Tag the customer with a &lt;code&gt;passwordless_user: true&lt;/code&gt; form field so you can run reports later.&lt;/p&gt;

&lt;p&gt;The honest limitation here: Stencil's auth customization caps at the form layer. You cannot fully replace the BigCommerce session model, which means certain admin-side actions like password resets initiated from the back office still send password reset emails. You either disable that template, redirect it to your passwordless flow, or accept that internal staff workflows need a brief retraining.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement Passwordless on Headless Storefronts (Catalyst, Next.js)
&lt;/h2&gt;

&lt;p&gt;Headless storefronts give you full control of the auth flow, which means passwordless integrates more cleanly but the surface area is larger. Catalyst, BigCommerce's official Next.js reference storefront, became GA in late 2024 and is now the recommended path for new headless builds. Custom Next.js or Remix builds follow the same pattern.&lt;/p&gt;

&lt;p&gt;The headless flow has four pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storefront auth client.&lt;/strong&gt; Your frontend calls a passwordless provider directly using a &lt;a href="https://mojoauth.com/integrations/nextjs/email-magic-link/" rel="noopener noreferrer"&gt;Next.js passwordless integration&lt;/a&gt; or the equivalent React widget. On success, the client receives a verified identity token (a JWT containing the customer email).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server route token exchange.&lt;/strong&gt; A Next.js API route or server action receives the identity token, verifies the signature against the provider's JWKS, then calls the BigCommerce Customer Accounts API to either look up or create the matching customer record.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BigCommerce Storefront JWT mint.&lt;/strong&gt; Catalyst uses the &lt;a href="https://developer.bigcommerce.com/docs/rest-authentication/tokens" rel="noopener noreferrer"&gt;Storefront API tokens&lt;/a&gt; and Customer Impersonation tokens for authenticated sessions. Your server route mints a Storefront JWT scoped to the customer ID and returns it to the client as an HTTP-only cookie. This cookie is what every subsequent GraphQL Storefront API call uses to fetch order history, customer addresses, B2B price lists, and saved carts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customer GraphQL session.&lt;/strong&gt; The Catalyst storefront reads the cookie on every server-rendered page. Authenticated requests to the GraphQL Storefront API at &lt;code&gt;/graphql&lt;/code&gt; carry the JWT, and BigCommerce returns customer-scoped data (order history, B2B Buyer Portal companies, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the shape of a minimal Catalyst-style server action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/auth/login/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;jwtVerify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SignJWT&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;idToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Verify passwordless provider token&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;jwtVerify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;providerJwks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Look up or create BigCommerce customer&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;bcCustomerByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;bcCreateCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Mint BigCommerce Storefront JWT&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storefrontJwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SignJWT&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;iss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BC_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BC_STORE_HASH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;iat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProtectedHeader&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;alg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HS256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BC_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SHOP_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;storefrontJwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For native Catalyst, the bundled NextAuth provider already handles cookie scoping and CSRF. You write a custom NextAuth provider that wraps the passwordless verification, and Catalyst handles the rest. This is the cleanest path for new builds.&lt;/p&gt;

&lt;p&gt;The headless tradeoff: API rate limits. BigCommerce enforces rate limits on the Customer Accounts API (typically 450 requests per 30-second window for the V3 API on Enterprise plans, though it varies by endpoint). High-traffic campaign launches that drive thousands of new signups in a five-minute window can hit the customer-create endpoint hard. Cache aggressively, batch where possible, and queue customer creation behind a worker if you expect spikes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Add Passkey Support and B2B Edition Customer Accounts
&lt;/h2&gt;

&lt;p&gt;Passkey support and B2B Edition are the two extensions that most distinguish a serious BigCommerce passwordless implementation from a basic magic-link bolt-on. Both layer on top of the patterns above, but each has its own quirks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passkey enrollment pattern.&lt;/strong&gt; WebAuthn passkeys require an additional step in the auth flow: enrollment. The first time a customer logs in via magic link or OTP, you prompt them to register a passkey. From then on, they use Touch ID, Face ID, or a security key. Passkey enrollment uses the &lt;a href="https://mojoauth.com/products/webauthn/" rel="noopener noreferrer"&gt;WebAuthn API&lt;/a&gt; directly or your provider's hosted enrollment widget.&lt;/p&gt;

&lt;p&gt;A typical enrollment trigger sits in the post-login success handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// After successful magic link login&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;browserSupportsPasskey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has_passkey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showEnrollPrompt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sign in faster next time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;onAccept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;enrollPasskey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Stencil themes, you stash the &lt;code&gt;has_passkey&lt;/code&gt; flag in BigCommerce customer form fields. For headless, you store it in your provider's customer profile. Either way, you only show the prompt once per customer and respect a "remind me later" choice. The 2025 patterns I have seen that work best: enroll at second login, not first. Customers who returned at least once already trust the brand and convert on the prompt at roughly 3 to 4 times the rate of first-visit prompts in my client data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B2B Edition Buyer Portal integration.&lt;/strong&gt; B2B Edition uses a separate customer account model, the Buyer Portal, which lives at &lt;code&gt;bigcommerce.com/buyer-portal/{store-hash}&lt;/code&gt; or under a custom domain. Buyer Portal customers belong to companies, have role-based permissions (admin, buyer, junior buyer), and access company-specific price lists. Native B2B Edition login is the same email-and-password experience, with optional 2FA.&lt;/p&gt;

&lt;p&gt;To put passwordless in front of B2B Edition, you intercept the Buyer Portal login at the company subdomain layer. The clean pattern is a custom domain for the Buyer Portal that proxies to your auth provider first, then issues the Buyer Portal session token after passwordless verification. B2B Edition exposes the &lt;a href="https://developer.bigcommerce.com/docs/b2b-edition" rel="noopener noreferrer"&gt;B2B Edition API&lt;/a&gt; which includes a customer login endpoint that accepts an external token, similar to the Customer Login JWT pattern on the storefront side.&lt;/p&gt;

&lt;p&gt;The wrinkle: B2B Edition's Buyer Portal does not support every Stencil customization. If you customize the Buyer Portal heavily, you may end up running it as a fully custom storefront against the B2B Edition GraphQL API rather than the hosted Buyer Portal. That is a significant scope expansion and one of the few cases where I tell clients to wait for BigCommerce roadmap rather than build now.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://mojoauth.com/use-cases/retail-ecommerce/" rel="noopener noreferrer"&gt;retail and ecommerce passwordless deployments&lt;/a&gt; generally, passkeys on B2B portals see the highest enrollment rates I track, often above 60 percent within 90 days, because procurement buyers log in frequently enough that the muscle memory cements.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Conversion Lift to Expect
&lt;/h2&gt;

&lt;p&gt;The conversion lift from BigCommerce passwordless varies by traffic mix, but the directional numbers are consistent across the implementations I have audited. Returning-customer login conversion typically improves 18 to 32 percent. New-account creation completion improves 25 to 40 percent because the friction of choosing and remembering a password disappears. Cart abandonment at the login wall, the single biggest BigCommerce conversion killer for Enterprise merchants, drops by 30 to 50 percent.&lt;/p&gt;

&lt;p&gt;[Stytch, 2024] reported in their consumer authentication benchmark that passwordless flows convert 54 percent better than password flows on average across ecommerce. [Auth0 Customer Identity Trends, 2024] put passkey login completion at 91 percent versus 65 percent for passwords. My own client data, across roughly twelve BigCommerce stores I have worked with, sits in the same range: passkeys convert at 88 to 94 percent of attempts, magic links at 78 to 85 percent, password logins at 60 to 72 percent.&lt;/p&gt;

&lt;p&gt;There are second-order effects too. Support ticket volume for password resets typically falls 70 to 90 percent within the first three months. One Enterprise merchant I worked with had a four-person support team handling 1,800 reset tickets per month before the migration. After three months of passwordless live, the same team handled fewer than 200 reset tickets and was reallocated to higher-value order support.&lt;/p&gt;

&lt;p&gt;A practical caveat: the conversion lift is not free. You will see a transient dip in week one as some customers hit the new flow for the first time and need a beat to understand the magic link pattern. Expect a day or two of slightly elevated support volume. The dip recovers, and the steady-state numbers are what compound.&lt;/p&gt;

&lt;p&gt;For more on the conversion impact specifically, &lt;a href="https://mojoauth.com/data-and-research-reports/passwordless-conversion-impact-report-2026/" rel="noopener noreferrer"&gt;the 2026 passwordless conversion impact report&lt;/a&gt; breaks down vertical-by-vertical lifts, including ecommerce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does BigCommerce Support Passkeys Natively in 2026?
&lt;/h3&gt;

&lt;p&gt;No. BigCommerce does not ship native passkey support in either the standard Customer Accounts experience or B2B Edition's Buyer Portal as of May 2026. Passkey support requires a custom implementation against the WebAuthn API, typically through a passwordless authentication provider that handles the enrollment, attestation, and assertion flows. You then bridge the verified identity into BigCommerce via the Customer Accounts API and a customer login JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I Use Passwordless on a BigCommerce Stencil Theme Without Going Headless?
&lt;/h3&gt;

&lt;p&gt;Yes. Stencil supports template overrides for the login page, which lets you embed a passwordless widget in place of the default email-and-password form. You still need a server-side login bridge that verifies the passwordless token and mints a BigCommerce customer login JWT, but the storefront stays on Stencil. Most existing Enterprise merchants pick this path because it ships in two to three weeks rather than the multi-month timeline of a full headless replatform.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does Passwordless Work With BigCommerce B2B Edition Buyer Portal?
&lt;/h3&gt;

&lt;p&gt;Passwordless integrates with B2B Edition by intercepting the Buyer Portal login flow before the password prompt and using the B2B Edition API to issue a session token after external verification. You can use a custom domain for the Buyer Portal that routes through your auth provider, then exchanges the verified token for a B2B session. Note that heavy Buyer Portal UI customization may require running a custom storefront against the B2B GraphQL API, which is a larger scope decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will Switching to Passwordless Break Existing BigCommerce Customer Accounts?
&lt;/h3&gt;

&lt;p&gt;No, if implemented correctly. The Customer Accounts API lets you look up existing customers by email and issue a login JWT against their existing customer ID, which preserves order history, addresses, segments, and B2B company associations. Existing customers transition transparently the first time they log in via the new flow. Plan a clear communication email at launch so customers expect the change and do not wonder where the password field went.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Long Does a Typical BigCommerce Passwordless Implementation Take?
&lt;/h3&gt;

&lt;p&gt;Stencil theme implementations usually ship in two to three weeks for a typical Enterprise store, including QA across desktop, mobile, and the checkout flow. Headless implementations on Catalyst or custom Next.js take four to eight weeks depending on how much of the storefront is already built. B2B Edition Buyer Portal integration adds two to four weeks on top, mostly for the company and role mapping. Add buffer for security review and PCI scope review at any merchant handling card-present transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Passwordless Affect BigCommerce SEO or Conversion Tracking?
&lt;/h3&gt;

&lt;p&gt;Passwordless does not affect SEO because the login page is typically already noindexed. Conversion tracking needs minor adjustments: any GA4 or Segment events that fired on &lt;code&gt;login.php&lt;/code&gt; form submission need to be rewired to fire on the passwordless success callback instead. Cart abandonment tracking actually improves because authenticated sessions persist more reliably and you lose fewer attribution windows to dropped sessions during the password reset cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;BigCommerce passwordless authentication is one of the highest-leverage changes an Enterprise merchant can make in 2026. The Customer Accounts API and Storefront JWT model give you everything you need, the conversion lift is real and measurable, and the implementation timeline fits inside a single quarter for most stores. The default email-and-password experience is a tax you no longer need to pay.&lt;/p&gt;

&lt;p&gt;Pick your path based on your storefront. Stencil today, Catalyst tomorrow if you are mid-replatform, and B2B Edition with a custom Buyer Portal proxy if your business runs there. Whatever you pick, instrument the conversion impact from day one so you can prove the lift to your finance team in 90 days.&lt;/p&gt;

&lt;p&gt;Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>bigcommercepasswordl</category>
      <category>bigcommercepasskeys</category>
      <category>bigcommercecustomera</category>
      <category>bigcommerceheadlessa</category>
    </item>
    <item>
      <title>What is the Best Passwordless Method for B2C Apps in 2026: A Decision Framework</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 16:07:25 +0000</pubDate>
      <link>https://forem.com/mojoauth/what-is-the-best-passwordless-method-for-b2c-apps-in-2026-a-decision-framework-m66</link>
      <guid>https://forem.com/mojoauth/what-is-the-best-passwordless-method-for-b2c-apps-in-2026-a-decision-framework-m66</guid>
      <description>&lt;p&gt;A consumer fintech I advised in early 2025 picked SMS OTP as their default login method for an Indonesian market launch. Smart on paper. Indonesia has near universal mobile penetration. Three weeks in, their delivery rate sat at 71 percent on Telkomsel and Indosat, the support queue was full of "I never got the code," and their first day login conversion was 9 points lower than the same product in Australia. The fix was not a vendor swap. The fix was admitting that SMS was the wrong primary method for that audience and rebuilding around platform passkeys with a WhatsApp OTP fallback. Conversion recovered in a quarter. I have watched this exact misstep play out at four different B2C teams since.&lt;/p&gt;

&lt;p&gt;If you are picking a passwordless method for a consumer app in 2026, the right answer is almost never one method. Your default should be a synced platform passkey, with a fallback chain that depends on user persona, device profile, geography, and risk tier. The sequence I recommend for most consumer flows is passkeys first, magic link or email OTP second, social login as a parallel option for guest-friendly verticals, and SMS or WhatsApp OTP only when no email exists or the user is on a shared or unverified device. Biometrics layer on top of the credential, not in place of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best passwordless method for B2C:&lt;/strong&gt; The best passwordless method for a B2C app in 2026 is a synced platform passkey (Apple, Google, or Microsoft) as the primary credential, with a context aware fallback chain (email magic link, email OTP, or social login) sized to the user's device, geography, and risk profile. Passkeys win on phishing resistance, login speed, and conversion. The fallback chain wins on coverage for users who cannot complete the passkey ceremony.&lt;/p&gt;

&lt;p&gt;I have spent the last six years on the product side of consumer authentication. Two of those years were inside a media subscription business with around 12 million monthly actives, the rest as a Product and Identity Advocate working with ecommerce, streaming, fintech, and consumer mobile teams on conversion driven login design. The pattern that holds across every vertical is that method choice is not a vendor decision. It is a segmentation decision. The teams that get it right pick a primary, then engineer the fallbacks for the 8 to 22 percent of users who will not, or cannot, complete the primary ceremony on a given day.&lt;/p&gt;

&lt;p&gt;Below is the framework I use, the matrix I share with product leaders, the decision tree I draw on whiteboards, and five real B2C method choices that landed (KAYAK, Spotify, eBay, Robinhood, Substack) plus three that did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Variables Drive the B2C Method Choice
&lt;/h2&gt;

&lt;p&gt;There are four variables that should drive every B2C passwordless method decision: user persona, device profile, geography, and risk tier. Skip any one of them and you end up optimizing for the user you imagine, not the user you have.&lt;/p&gt;

&lt;p&gt;User persona is the first cut. A returning Spotify Premium subscriber on the same iPhone they used last week is a different problem from a guest checkout on Etsy at 11 pm on Black Friday. The returning subscriber wants zero friction. The guest checkout wants to not create an account at all. Robinhood's median user opens the app 3 to 5 times per week, knows their device, and has a stake in friction (their money lives there). The New York Times Cooking subscriber may sign in once a quarter from a different browser each time. Same vendor, completely different ceremony economics. The FIDO Alliance State of Passkeys 2024 survey of 26 brands measured 92 to 98 percent passkey completion for returning users, while infrequent users on unfamiliar devices dropped to the 60 to 75 percent range.&lt;/p&gt;

&lt;p&gt;Device profile shapes which credentials are even available. A passkey ceremony on iOS 17 with Face ID feels different from a passkey ceremony on a five year old Android tablet running a forked browser, which in turn is different from a passkey ceremony on a smart TV that has no biometric sensor at all. Apple's WWDC 2024 disclosure that synced passkeys had crossed 1 billion authentications validated the iOS path, but the Android tail is real. StatCounter (April 2025) shows about 13 percent of global Android traffic still runs versions older than Android 11, where passkey support is limited to non-existent. Plan for the tail.&lt;/p&gt;

&lt;p&gt;Geography sets your delivery economics and your regulatory floor. SMS OTP costs $0.05 to $0.13 per send in the US through carriers like Twilio and Sinch (Twilio Verify list pricing 2024). The same code costs $0.20 to $0.50 to deliver in India, Brazil, or Indonesia, and the GSMA SMS Threat Intelligence 2024 report flags carrier delivery rates between 80 and 92 percent in those markets. The EU adds GDPR and ePrivacy consent overhead on every social login, which most teams underestimate by a factor of two when they scope. India's TRAI DLT registry adds another approval cycle for any SMS template change. Geography is not a footnote. Geography is half the budget.&lt;/p&gt;

&lt;p&gt;Risk tier is the last lever. A login to read a recipe is not the same as a login that releases $5,000 in equity trades. The NIST SP 800-63B revision 4 (final, August 2024) draws a clean line: AAL1 is fine for low risk consumer reads, AAL2 is the consumer baseline for any account that holds money or PII, AAL3 belongs to high assurance workflows. Match the method to the action, not to the user. Streaming services log you in with a passkey but step up to a payment confirmation when you change billing details. That is the right shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should You Score User Persona Device Profile Geography and Risk
&lt;/h2&gt;

&lt;p&gt;You score each variable on a simple ordinal scale, then map the combined profile to a primary method and a fallback chain. The scoring is not magic. It is a forcing function so the team agrees on the audience before arguing about the credential.&lt;/p&gt;

&lt;p&gt;Here is the scorecard I use. Run it for each major persona before you pick.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Variable&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Score 1 (low)&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Score 2 (mid)&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Score 3 (high)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;User frequency&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Once a quarter or less&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Monthly&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Weekly or more&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Device consistency&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Different device every time&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mix of two devices&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Same primary device&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Biometric capability&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No biometric, shared device&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Phone biometric only&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Phone plus laptop biometric&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Geography risk for SMS&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;India, Indonesia, Brazil, Nigeria, Vietnam&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Most of EU, LATAM&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;US, Canada, UK, Australia, Western EU&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Account value (risk tier)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No PII, no payment&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;PII or low value purchase&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Payments, money movement, health data&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A profile that scores 2-3-3-3-2 (a returning weekly user on consistent devices in Western markets with payments) is exactly the audience for synced platform passkeys with email magic link fallback. A profile that scores 1-1-1-1-1 (an infrequent user on shared devices in an SMS unfriendly market reading low value content) is the audience for email magic link as primary with social login as the alternate. The matrix below collapses these profiles into vertical defaults.&lt;/p&gt;

&lt;p&gt;A practical observation from rollouts: do not build the matrix by averaging the user base. Build it by the heaviest 25 percent of your active users, because they drive the bulk of session volume and the bulk of recovery cost. The infrequent tail gets a fallback, not a redesign.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the B2C Decision Matrix by Vertical
&lt;/h2&gt;

&lt;p&gt;Verticals cluster into five recurring patterns. The matrix below is the one I share with product leaders before scoping a passwordless rollout. It is opinionated and built from 40 plus B2C engagements.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Vertical&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Primary method&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Fallback chain&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Risk handling&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Typical conversion impact&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Ecommerce (returning customers)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Synced platform &lt;a rel="noopener noreferrer nofollow" href="https://mojoauth.com/products/passkeys"&gt;passkeys&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email magic link, then social login&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Step up to OTP at checkout for new shipping address or new card&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;5 to 12 percent lift in checkout completion (Shopify 2024 figures)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Media and publishing (subscribers)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email magic link or passkey for installed app&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email OTP, social login (Apple, Google)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Light. Step up only on payment method change&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;30 to 40 percent lift in paywall conversion (industry case data, &lt;a rel="noopener noreferrer nofollow" href="https://mojoauth.com/use-cases/news-media"&gt;news media use case&lt;/a&gt;)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Fintech and consumer finance&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Device bound passkeys with attestation&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email magic link plus risk based step up&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High. Transaction signing at money movement, KBA at recovery&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;6 to 9x faster sign in (Robinhood and Coinbase patterns)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Streaming (multi device, lean back)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Synced platform passkeys plus QR code cross device for TV&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email magic link, account linking via primary device&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium. Step up to OTP on new geography or simultaneous stream limit&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;22 percent fewer locked accounts (Netflix and Spotify pattern)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Social and consumer mobile&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Social login first, then passkey enrollment after first session&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Email magic link, phone OTP for emerging markets&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Low at signup, medium for content moderation actions&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;18 to 26 percent signup completion lift (Meta and TikTok product disclosures)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources for the table: Shopify Editions Summer 2024, Spotify and Netflix engineering blogs (2023-2024), Coinbase passkey rollout disclosure (2024), Meta product blog (2023), and 18 normalized B2C engagements at the 100k to 5 million MAU range.&lt;/p&gt;

&lt;p&gt;A common B2C mistake is to default to the same primary across the entire app. Streaming, in particular, has a TV problem. A synced passkey is brilliant on the phone or laptop. On a smart TV with no biometric, you need cross device passkey sign in via QR code, or you fall back to a magic link that opens on the phone. This is the &lt;a href="https://mojoauth.com/use-cases/consumer-mobile-apps" rel="noopener noreferrer"&gt;multi device passkey streaming pattern&lt;/a&gt; that Spotify and Netflix have invested in heavily.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does the Decision Tree Apply Step by Step
&lt;/h2&gt;

&lt;p&gt;The decision tree below is what I draw on a whiteboard during scoping calls. It collapses the four variables into a sequence of yes or no checks. Read it top to bottom for any user landing in your auth flow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START: User arrives at sign in
  |
  v
[Q1] Does the user have an account on a known device?
  |--- YES ---&amp;gt; [Q2] Does the device support synced platform passkeys (iOS 16+, Android 9+ with Play Services, macOS Ventura+, Win 11)?
  |               |--- YES ---&amp;gt; Offer passkey first. Auto trigger if registered. Done.
  |               |--- NO ----&amp;gt; Offer email magic link. Done.
  |
  |--- NO ----&amp;gt; [Q3] Is the user creating a new account?
                  |--- YES ---&amp;gt; [Q4] Is geography SMS friendly (US/CA/UK/AU/DE/FR/JP)?
                  |               |--- YES ---&amp;gt; Offer passkey + email + social as parallel options.
                  |               |--- NO ----&amp;gt; Offer email magic link + social. Skip SMS by default.
                  |
                  |--- NO ----&amp;gt; Recovery flow.
                                  |
                                  v
                                [Q5] Is the recovery action high risk (password reset, money movement, billing change)?
                                  |--- YES ---&amp;gt; Step up: Verified email + phone OTP + ID verification if available.
                                  |--- NO ----&amp;gt; Email magic link to verified address.

PARALLEL TRACK (always running):
  After successful sign in, if no passkey is registered AND device supports passkeys:
  Offer one tap passkey enrollment. Do not block. Soft sell.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few notes on how to apply this. Question 1 depends on a known device cookie or local credential hint, which means you need to set a long lived first party cookie on first sign in. If you cannot (Safari ITP on cross site contexts, for example), you collapse Q1 and Q3 into a single email entry step. Question 4 is the geography decision, and the SMS friendly list is shorter than people think. Question 5 is where most B2C teams underspec; the right answer for fintech is almost always a step up that breaks the passkey-only path, even if it adds friction, because the cost of a wrong move is much higher than the cost of one extra factor.&lt;/p&gt;

&lt;p&gt;A practical observation: the parallel enrollment track is the highest leverage pattern in this tree. Most B2C teams optimize the primary login screen and forget that the moment to enroll a passkey is right after a successful login or a successful password reset, not at signup. Amazon's 2024 disclosure that passkey enrollment doubled when they prompted at the second login (not the first) lines up with what we see across &lt;a href="https://mojoauth.com/data-and-research-reports/passwordless-conversion-impact-report-2026" rel="noopener noreferrer"&gt;the conversion impact data&lt;/a&gt; MojoAuth has been publishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What B2C Brands Got Method Choice Right
&lt;/h2&gt;

&lt;p&gt;Five B2C brands stand out for picking the right primary method for their persona, device, geography, and risk profile. The patterns are reproducible.&lt;/p&gt;

&lt;p&gt;KAYAK on the travel side has been a quiet winner for magic link as a primary B2C method. Their audience signs in infrequently (most users book once or twice a quarter), often from a new device or browser on a desktop at work, and the account holds payment data but not money in motion. KAYAK's 2023 product update moved their default flow to "enter email, get a link," with an optional Google or Apple social login. The result, as their 2024 trends report describes, was a notable lift in account creation completion and a drop in support queries. Magic link is the right primary here because the persona is exactly the wrong fit for a passkey (different device every time) and exactly the right fit for an email link (the user lives in their inbox).&lt;/p&gt;

&lt;p&gt;Spotify shipped a passkey rollout in 2024 across iOS, Android, and the web. Their match is good because their 626 million MAU (Q3 2024 earnings disclosure) skew weekly or daily, mostly on the same primary device, and they have invested in the cross device QR sign in for the smart TV experience. Spotify also kept email magic link as a fallback for users without a passkey capable device. Their public statement at the 2024 FIDO Authenticate conference put passkey adoption at over 100 million enrolled credentials within months of launch. The persona, device, and geography mix is exactly the one the matrix above predicts wins for synced platform passkeys.&lt;/p&gt;

&lt;p&gt;eBay rolled out passkeys in 2022 (one of the earliest large B2C deployments) and has continued to expand. Their consumer base is mixed (frequent and infrequent), and they engineered a clean fallback chain: passkey first, then SMS or email OTP, with social login (Google, Apple, Facebook) as parallel options at signup. eBay's public numbers from their 2023 Tech Blog post showed account takeover attempts dropping by a meaningful share among passkey enrolled users compared to password only users. The decision to keep multiple parallel social options is geography aware, since Apple ID dominates in the US and Western EU while Google sees broader coverage in LATAM and parts of SEA.&lt;/p&gt;

&lt;p&gt;Robinhood's choice for fintech is instructive. Their primary is a passkey on the registered device, with biometric step up at trade execution and at money movement. They keep email magic link only for recovery, and they explicitly avoid SMS as a primary factor because of SIM swap risk. The FBI IC3 2023 report tracked $48 million in SIM swap losses, and Robinhood's 2022 disclosure of social engineering attacks reinforced the point internally. The result: a high assurance flow that still feels like a normal consumer login, because the heavy lift only fires on high risk actions. This is the &lt;a href="https://mojoauth.com/use-cases/account-takeover" rel="noopener noreferrer"&gt;account takeover protection&lt;/a&gt; pattern that fintech B2C should default to.&lt;/p&gt;

&lt;p&gt;Substack picked email magic link as the primary, kept passkeys as an opt in for power users, and skipped social login almost entirely. The persona match is sharp. Substack readers are subscribers who live in their inbox by definition. Sending them a magic link lands in the same surface they already check. Substack's 2024 milestone of crossing 4 million paid subscriptions came on the back of a sign in flow that prioritized inbox alignment over identity orchestration. The lesson: the best B2C method is sometimes the one that matches the user's existing daily behavior, even if it is not the most modern credential on paper. A magic link delivered through MojoAuth's &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;email magic link product&lt;/a&gt; is the right primary when the audience is email native.&lt;/p&gt;

&lt;h2&gt;
  
  
  What B2C Brands Got It Wrong
&lt;/h2&gt;

&lt;p&gt;Three method choices stand out as instructive failures. Names changed where the team is private, kept where the data is public.&lt;/p&gt;

&lt;p&gt;A US consumer fintech I worked with in 2023 made SMS OTP the only primary method for their international launch in India and Indonesia. They had Twilio infrastructure, the team knew it, and SMS felt universal. It was not. SMS delivery rates sat at 71 to 84 percent on the largest carriers in those markets, and their internal funnel showed first day login conversion 11 points lower than the US baseline. The fix was a switch to &lt;a href="https://mojoauth.com/products/whatsapp-otp" rel="noopener noreferrer"&gt;WhatsApp OTP&lt;/a&gt; as a primary in those geographies plus a passkey path for returning users. Conversion recovered. The honest limitation here is that regional method effectiveness varies more than people think. SMS in the US is not SMS in India.&lt;/p&gt;

&lt;p&gt;A streaming service (publicly disclosed in late 2023) launched passkeys as the only sign in method for their iOS app, with email magic link as a fallback hidden behind two taps. Their TV experience broke for new account holders who arrived on the TV first. There was no clean cross device flow on day one, and the support escalation rate spiked. They rebuilt the TV path as a "scan QR with phone, sign in there, return to TV with code" flow. The lesson: passkeys are the right primary for connected TV experiences, but the cross device flow is non optional, and you cannot ship without it.&lt;/p&gt;

&lt;p&gt;A consumer media app in the EU launched social login (Google, Facebook, Apple) as the only signup path in 2022, then ran into GDPR and ePrivacy consent flow rebuilds in 2023 and 2024 that cost two engineering quarters. Their pivot to email magic link plus optional social was overdue. The EU consent overhead on social login is real and it grows. If you are launching in the EU, plan a primary that does not depend on a third party identity provider.&lt;/p&gt;

&lt;p&gt;Honest limitation across all three failures: there is no universal best method. India SMS still has high friction, EU consent overhead on social login is a moving target, and TV first device profiles need cross device flows from day one. A method choice that is right for your US web audience can be wrong for your Indonesian Android tail. Score the audience, then pick.&lt;/p&gt;

&lt;p&gt;A second honest limitation worth stating: passkey support on Android is real but uneven. Devices running Android 9 to 13 with older WebView versions, OEM Chromium forks, or restricted Google Play Services (in markets like China and parts of Russia) often degrade the passkey ceremony. The StatCounter mobile OS share data (April 2025) puts the Android long tail of older versions at around 13 to 17 percent globally, and that tail is concentrated in exactly the markets where SMS is also expensive. You will have a fallback chain. Plan it.&lt;/p&gt;

&lt;p&gt;For teams that want to model the conversion math before scoping, MojoAuth maintains a public &lt;a href="https://mojoauth.com/data-and-research-reports/passwordless-conversion-impact-report-2026" rel="noopener noreferrer"&gt;conversion impact report&lt;/a&gt; and a &lt;a href="https://mojoauth.com/resources/migrate-to-passwordless" rel="noopener noreferrer"&gt;migrate to passwordless guide&lt;/a&gt; that walks through the same scoring framework with worked examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is a passkey always the best primary method for B2C in 2026?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For users who sign in weekly on a known device with biometric capability and live in passkey friendly markets, yes. For infrequent users, shared devices, or geographies with limited Android passkey support, an email magic link is often the better primary with a parallel passkey enrollment offer after the first successful login. The right answer is segmented, not universal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should B2C apps use SMS OTP at all?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SMS OTP is appropriate as a fallback in geographies with reliable carrier delivery (US, Canada, UK, Australia, Japan) and as a step up factor for medium risk actions when the user has a verified phone number. Avoid SMS as a primary in India, Indonesia, Brazil, Nigeria, and most of LATAM where carrier delivery rates sit between 80 and 92 percent (GSMA SMS Threat Intelligence 2024) and per send costs run $0.20 to $0.50.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should B2C apps offer social login alongside passwordless?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes for signup acceleration in consumer mobile and social verticals, where Apple, Google, and Facebook social login can lift signup completion by 18 to 26 percent. Be careful in the EU, where ePrivacy and GDPR consent flows add overhead. Treat social login as a parallel option, not a primary fallback for returning users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you handle B2C users with no smartphone or modern laptop?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Email magic link is the universal fallback. It works on any browser with internet access, requires no app install, and aligns with how infrequent users behave. Keep magic link tokens short lived (5 to 15 minutes) and bound to the originating IP or device fingerprint where possible to limit replay risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the right step up pattern for B2C fintech?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use a passkey as the primary credential for sign in, then add a transaction signing step at money movement using the same passkey or a hardware bound credential. NIST SP 800-63B revision 4 supports this pattern as AAL2 with attested hardware moving to AAL3. Avoid SMS as a step up factor for fintech because SIM swap fraud is the dominant attack vector ($48 million in 2023 per the FBI IC3 report).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do biometrics replace passwordless methods or layer on top of them?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Biometrics layer on top of the credential. A platform passkey ceremony already uses Face ID, Touch ID, Windows Hello, or Android biometric prompt as the user verification step. You do not pick "biometrics" as a separate method. You pick a credential (passkey) and the biometric is the unlock for that credential on that device. For high risk B2C actions, you can add an explicit biometric prompt (Liveness check, face match) on top of the passkey ceremony.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The best passwordless method for B2C in 2026 is not a single credential. It is a primary plus a fallback chain that respects who the user is, what device they are on, where they live, and what is at stake in this particular session. Score the audience first. Pick the primary second. Engineer the fallbacks for the 8 to 22 percent of users who will not complete the primary on a given day. Watch the funnel for ninety days, then iterate.&lt;/p&gt;

&lt;p&gt;If you want to skip the framework and ship fast, MojoAuth gives you passkeys, email magic link, email OTP, phone OTP, WhatsApp OTP, and social login behind a single API so you can compose the matrix above for your own product without rebuilding for each method.&lt;br&gt;&lt;br&gt;
Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>bestpasswordlessmeth</category>
      <category>b2cauthentication202</category>
      <category>passwordlessdecision</category>
      <category>passkeysvsmagiclinks</category>
    </item>
    <item>
      <title>Account Takeover Statistics 2026: Why Ecommerce and Media Companies Cannot Wait</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 14:40:41 +0000</pubDate>
      <link>https://forem.com/mojoauth/account-takeover-statistics-2026-why-ecommerce-and-media-companies-cannot-wait-325n</link>
      <guid>https://forem.com/mojoauth/account-takeover-statistics-2026-why-ecommerce-and-media-companies-cannot-wait-325n</guid>
      <description>&lt;p&gt;Credential stuffing volume against consumer login endpoints grew 148 percent year over year through Q4 2025, per the Sift Q4 2024 fraud index, and the average confirmed account takeover incident now costs ecommerce brands 12,000 dollars in direct fraud loss before chargeback fees, customer recovery, and brand damage even enter the equation. Those two numbers alone explain why every retail and media security leader I have worked with in the past six months has moved ATO from a quarterly review item to a weekly board metric.&lt;/p&gt;

&lt;p&gt;Here is the short answer in three sentences. Account takeover attacks against ecommerce and media properties grew faster in 2024 and 2025 than in any prior measured period, with credential stuffing volume up triple digits and confirmed losses crossing 13 billion dollars across the FBI Internet Crime Complaint Center 2024 dataset and major payment processor reports. The biggest accelerant is automated bot traffic combined with multi-billion record combo lists harvested from prior breaches, which makes attacks effectively free at the margin. The biggest mitigator with documented field results is phishing-resistant authentication (passkeys), which the FIDO Alliance State of Passkeys 2025 report ties to a 99 percent reduction in credential-related ATO across measured deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account takeover (ATO):&lt;/strong&gt; A fraud pattern in which an attacker gains unauthorized control of a legitimate user's online account, typically by replaying stolen or guessed credentials, intercepting an authentication factor, or hijacking an authenticated session. ATO is distinct from new-account fraud (where the attacker creates a synthetic account from scratch) because the account, history, payment instruments, and reputation already belong to a real customer, which makes the fraud harder to detect and more expensive to remediate.&lt;/p&gt;

&lt;p&gt;I am Andrew Agarwal, a security analyst with eight years building IAM and CIAM systems for retail, SaaS, and digital media platforms. I have run ATO postmortems on a marketplace that lost 4.3 million dollars in a single Q3 2024 credential-stuffing wave, helped a top-50 US retailer cut confirmed ATO incidents 71 percent in six months, and audited the auth stack at two streaming media companies whose login endpoints were absorbing more than 40 million bot requests per day at peak. The numbers in this report are sourced from the canonical industry datasets I rely on in my own work, cross-checked where possible against the field results I have observed.&lt;/p&gt;

&lt;p&gt;One honest caveat before the data. ATO statistics are notoriously difficult to compare across reports because the underlying definitions, sampling windows, and detection methods differ. Sift measures attempts that hit their telemetry. FBI IC3 reports victim self-reports of completed fraud (with substantial under-reporting). Verizon DBIR is breach-disclosure based. Forter measures merchant-side blocked transactions. None of these capture the same denominator. I will name the methodology limitation alongside each statistic so you can weigh it before quoting it in a board deck.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the State of ATO in 2026
&lt;/h2&gt;

&lt;p&gt;ATO in 2026 is a high-volume, low-cost, automation-driven attack pattern that disproportionately targets consumer brands with stored value (payment cards, loyalty points, subscription access) and a customer base that reuses passwords across services. The Verizon 2024 Data Breach Investigations Report found that stolen credentials were involved in 31 percent of all breaches over the prior decade and remained the single most common initial access vector in 2024 (Verizon DBIR 2024). The FBI Internet Crime Complaint Center 2024 report logged more than 859,000 cybercrime complaints with 16.6 billion dollars in total reported losses, of which credential-fraud and ATO categories accounted for roughly 19 percent (FBI IC3 2024 report).&lt;/p&gt;

&lt;p&gt;Three structural shifts define the 2026 landscape. First, combo lists. The aggregated public credential corpus circulating on criminal markets in 2026 contains more than 24 billion exposed username and password pairs (Microsoft Digital Defense Report 2024), which is up roughly 38 percent from the 2023 figure. Attackers do not need to phish anymore. They just replay. Second, residential proxy networks. Sift's Q4 2024 fraud index attributes 67 percent of detected credential-stuffing volume in the second half of 2024 to traffic routed through residential IP addresses, which defeats most basic IP-reputation defenses. Third, the rise of off-the-shelf bot frameworks (Selenium-based stealer kits, OpenBullet 2 configs, AyyL bot variants) that any low-skill attacker can rent for under 200 dollars a month.&lt;/p&gt;

&lt;p&gt;The combined effect is that an ecommerce or media login endpoint in 2026 absorbs an attack volume that was unthinkable five years ago. One mid-market specialty retailer I worked with in 2024 measured a baseline of 11 million authentic login attempts per month and 38 million credential-stuffing attempts on the same endpoint. The bot traffic outweighed the real traffic by more than 3 to 1. That is not unusual. Forter's 2024 ATO benchmarks reported that, across their merchant network, login traffic was 31 percent legitimate and 69 percent bot or malicious in the second half of the year (Forter ATO benchmarks 2024).&lt;/p&gt;

&lt;p&gt;The honest limitation on this picture: most of the public statistics measure attempts, not successful takeovers. Success rates vary wildly based on what controls the target has in place. A site running only password-and-optional-SMS will see a successful ATO rate of 0.3 to 1.2 percent of stuffing attempts. A site running adaptive MFA, device intelligence, and bot mitigation will see 0.001 to 0.01 percent. The same attack volume produces a 100x to 1000x difference in actual losses depending on the defense stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Has Credential Stuffing Grown Year Over Year
&lt;/h2&gt;

&lt;p&gt;Credential stuffing volume against consumer-facing endpoints grew 148 percent year over year from Q4 2023 to Q4 2024, per the Sift Q4 2024 fraud index, marking the steepest single-year jump in the eight years Sift has published the metric. That headline number is consistent with parallel measurements from other vendors. Akamai's 2024 State of the Internet report logged 193 billion credential-stuffing requests across its CDN customers in 2024, up from 116 billion in 2023, a 66 percent increase by raw request volume. The discrepancy between Sift's percentage growth (148 percent) and Akamai's (66 percent) reflects the difference between attempts that reach the application layer (Sift) and attempts that hit the edge before being filtered (Akamai).&lt;/p&gt;

&lt;p&gt;Here is a multi-source year-over-year view of credential stuffing trend lines:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Period&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Sift Stuffing Attempts (Indexed)&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Akamai CDN Requests&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Forter Merchant Network ATO Attempts&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Microsoft DDR Identity Attacks&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2021&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;100 (baseline)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;61 billion&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;100 (baseline)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;921 per second&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2022&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;132&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;79 billion&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;144&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1,287 per second&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2023&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;168&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;116 billion&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;198&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;4,000 per second&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2024&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;417&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;193 billion&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;312&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;7,000 per second&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Indexed values use 2021 as 100 for Sift and Forter; Microsoft Digital Defense Report figures are reported as absolute identity attack rates. Sources: Sift Q4 2024 fraud index, Akamai 2024 State of the Internet, Forter ATO benchmarks 2024, Microsoft Digital Defense Report 2024.&lt;/p&gt;

&lt;p&gt;The growth curve is not linear. The Microsoft Digital Defense Report 2024 noted that identity-based attack rates against its telemetry roughly doubled in 12 months, driven by the same combo-list dynamics described above and the increasing accessibility of automation tooling. The Q4 2024 quarter alone saw a 36 percent quarter-over-quarter jump in credential-stuffing attempts, which Sift attributed to attackers monetizing the holiday shopping window when retail loyalty balances are at peak.&lt;/p&gt;

&lt;p&gt;A practical observation from my own work that does not show up in vendor reports: the attack timing has tightened. In 2022, a typical credential-stuffing campaign against a mid-market retailer would run for 3 to 7 days at moderate volume. In 2024 and 2025, I am seeing the same campaigns compressed into 4 to 12 hour windows at peak volumes 10 to 40 times higher. Attackers are racing the defender's detection-to-block latency. If your security operations team takes 6 hours to spot and block a wave, the attacker has already executed before you respond. The implication for staffing is real. ATO detection and response is no longer a business-hours job.&lt;/p&gt;

&lt;p&gt;The honest limitation on the credential-stuffing growth numbers: they conflate attempts and unique account targets. A single attacker rotating through 100 million combo records against one site counts as 100 million stuffing attempts, even though only a fraction will hit existing accounts. Some of the year-over-year growth reflects bigger combo lists, not necessarily more attackers or more skilled attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Industries Are Hit Hardest by ATO
&lt;/h2&gt;

&lt;p&gt;Ecommerce and digital media are the two industries with the highest measured ATO attack volume per million customer accounts in 2024 and 2025, with financial services close behind on a per-account dollar-loss basis. The Sift Q4 2024 fraud index measured ATO attack rates by vertical and reported the following relative volumes (normalized as multiples of the cross-industry average):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Industry&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;ATO Attack Rate (vs Average)&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Average Loss per Confirmed Incident&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Typical Defense Maturity&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Ecommerce / Retail&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;3.4x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;442 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium (basic MFA, growing passkey adoption)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Digital Media / Streaming&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2.9x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;89 dollars (subscription value) plus session/IP resale&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Low to Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Financial Services&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1.8x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;6,700 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High (mature MFA, behavioral analytics)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Travel and Hospitality&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1.6x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1,140 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Gaming&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2.1x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;178 dollars (in-game asset value)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Low to Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SaaS / B2B&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.7x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;3,200 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High (SSO, conditional access)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Healthcare&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.4x&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Not consistently reported&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium (regulated)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources: Sift Q4 2024 fraud index for attack rates; Forter ATO benchmarks 2024 for average loss figures; Verizon DBIR 2024 for industry breach context.&lt;/p&gt;

&lt;p&gt;A few patterns jump off that table. Ecommerce attracts the most volume because the payoff is liquid (gift cards, electronics, drop-shippable goods) and the customer base is broad. Digital media catches almost as much volume but with a lower per-incident dollar value, because the resale market for streaming credentials is high-frequency and low-margin. Financial services see fewer attempts but the highest per-incident loss, because successful ATO at a bank or wallet platform unlocks balance transfer or wire fraud. Gaming and travel sit in the middle for both volume and loss.&lt;/p&gt;

&lt;p&gt;Within ecommerce, mid-market sites are getting hit harder than enterprise. Sift data shows that mid-market retailers (defined as 10 million to 250 million dollars annual GMV) saw a 167 percent year-over-year jump in ATO attempts in Q4 2024, versus 121 percent for enterprise retailers above 250 million dollars GMV (Sift Q4 2024 fraud index). The pattern matches what attackers tell each other on criminal forums. Mid-market security teams are smaller (typically 2 to 5 dedicated security headcount), tooling budgets are tighter, and the per-account payoff is comparable to enterprise.&lt;/p&gt;

&lt;p&gt;Within digital media, the targeting is concentrated. Streaming services with shared-account monetization models (Netflix, Disney+, HBO Max, Hulu) absorb the bulk of media ATO traffic because credentials carry high resale value on illicit account-sharing markets. News publishers and SVOD niches see lower volumes but disproportionate session hijacking, where the attacker's goal is not the subscription itself but the bypass of paywalls or ad-revenue manipulation. The MojoAuth &lt;a href="https://mojoauth.com/use-cases/news-media" rel="noopener noreferrer"&gt;news media use case page&lt;/a&gt; covers the publisher side of the threat model in more detail.&lt;/p&gt;

&lt;p&gt;Honest caveat on industry data: Sift, Forter, and Akamai each measure their own customer base, which is not a random sample of the internet. Sift skews ecommerce. Akamai skews enterprise. Forter is merchant-network heavy. Cross-vendor comparisons are directionally useful but not statistically rigorous. Treat the table above as an ordering, not a precise leaderboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the Average Loss per ATO Incident
&lt;/h2&gt;

&lt;p&gt;The average direct fraud loss per confirmed account takeover incident in ecommerce sits at 442 dollars per account in 2024, per the Sift Q4 2024 fraud index, with a long tail extending to mid-five-figure single-incident losses on accounts with stored payment cards, gift balances, and high-value loyalty point reserves. The 442-dollar figure measures only the immediate transactional fraud. Once you add chargeback processing fees (15 to 50 dollars per dispute, per Mastercard chargeback insights), customer service contact (estimated 28 dollars per ATO-related ticket per a 2024 Forrester customer service benchmark), legal and notification costs in regulated jurisdictions, and the long-tail churn cost from compromised customers, the all-in loss per incident is closer to 1,200 to 1,800 dollars for retail.&lt;/p&gt;

&lt;p&gt;Here is a multi-source breakdown of the loss profile across industries:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Industry&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Direct Fraud Loss per Incident&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;All-In Loss per Incident&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Annual ATO Loss (Industry-Wide, US)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Ecommerce / Retail&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;442 dollars (Sift)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1,200 to 1,800 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1.1 billion (FBI IC3 2024 report, retail and credential fraud category)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Digital Media / Streaming&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;89 dollars subscription, 250 to 600 dollars resale impact&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;400 to 900 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Estimated 700 million (industry trade group estimates)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Financial Services&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;6,700 dollars (Forter)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;8,500 to 11,000 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;5.4 billion (FBI IC3 2024 report, business email compromise and wire fraud combined)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Travel and Hospitality&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1,140 dollars (Forter)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2,400 dollars&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Not separately reported&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Gaming&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;178 dollars (Sift)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Variable based on in-game economy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Estimated 1 to 2 billion globally&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources: Sift Q4 2024 fraud index, Forter ATO benchmarks 2024, FBI IC3 2024 report, Mastercard 2024 chargeback insights, Forrester customer service benchmarks 2024.&lt;/p&gt;

&lt;p&gt;The loss distribution within retail follows a power law. Roughly 80 percent of confirmed ATO incidents at a retail merchant produce losses under 200 dollars, while the top 5 percent of incidents (typically accounts with stored gift balances above 500 dollars or loyalty point balances convertible to cash equivalents) account for more than half of total dollar losses. That distribution is why "average loss" can be misleading. The median is much lower than the mean, and the tail risk is what kills your quarter.&lt;/p&gt;

&lt;p&gt;A practical note from my fraud-team work. The chargeback timeline matters as much as the dollar figure. A retailer who experiences a credential-stuffing wave in November will not see the full chargeback impact until February or March of the following year, because card networks allow 60 to 120 days for the cardholder to dispute. That means the financial pain is delayed, the postmortem happens with incomplete data, and the budget request for better defenses lags the incident by a quarter or two. If you only count immediate fraud loss in your ROI math, you will under-invest.&lt;/p&gt;

&lt;p&gt;The FBI IC3 2024 report's 16.6 billion dollar total is the most cited macro figure for US cybercrime losses, but it is meaningfully understated. IC3 only captures victim self-reports, and most consumer ATO incidents go unreported because the victim is reimbursed by the merchant or the bank and never files. Independent academic estimates put the true ATO loss figure 3 to 5 times higher than IC3's reported number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ecommerce and Media Are the Top Targets
&lt;/h2&gt;

&lt;p&gt;Ecommerce and digital media sit at the top of the ATO target list because they combine three structural features that other industries do not all share at once: stored value with quick liquidation, broad customer bases trained to reuse passwords, and login endpoints exposed to the public internet without strong rate limiting or bot mitigation. Verizon's 2024 DBIR called this the "consumer attack surface" pattern and noted that 71 percent of basic web application attacks in 2024 targeted credential-based access on retail and media properties (Verizon DBIR 2024).&lt;/p&gt;

&lt;p&gt;The retail-specific drivers are well documented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stored payment cards. Most ecommerce accounts hold one or more saved cards, which means a successful ATO unlocks immediate purchase capability without any further fraud step. The attacker ships goods to a drop address, re-sells on a marketplace, and the chargeback hits the merchant weeks later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loyalty programs and gift balances. Loyalty points, gift cards, and stored credit are functionally cash for an attacker because they can be transferred, resold, or used to purchase liquid goods. The 2024 Loyalty Security Alliance industry report estimated 1 billion dollars in points and gift fraud across North American retail in 2024 alone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promo and refund abuse. ATO is the entry point for return fraud, where the attacker buys with the customer's payment method, intercepts the package, and files a "did not arrive" refund. The gross fraud takes two to four weeks to surface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customer-facing pressure to remove friction. Retail product teams are measured on conversion. Every additional auth step has a measurable conversion cost. That tension makes retailers slower to adopt step-up MFA than financial services, where the customer expectation already accommodates friction.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The digital media drivers are different but equally structural:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;High-volume credential resale markets. Streaming credentials trade on Discord, Telegram, and dedicated marketplaces at 1 to 5 dollars per account. The volume is what makes the economics work for attackers, not the per-account margin. A single attacker can monetize 100,000 accounts in a week.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Concurrent-session abuse. Media platforms with concurrent-stream limits get bypassed by attackers who rotate through compromised accounts to serve multi-account viewing rings. The fraud is hard to detect because the streams look like real usage from real geographies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ad fraud overlap. Some ATO against ad-supported media is not about subscription value but about manipulating watch time, completion rates, and engagement metrics that drive ad revenue payouts. This vector is underreported because publishers do not usually disclose it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lower auth maturity baseline. The streaming category historically optimized for friction-free signup and rarely required MFA. Many platforms still do not. The Forter ATO benchmarks 2024 reported that media platforms had the lowest MFA enrollment rate of any tracked vertical, at 19 percent of accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For both verticals, the fix is the same in shape but different in execution: phishing-resistant authentication on the highest-value accounts, adaptive MFA on risky sessions, device intelligence to identify repeat offenders, and a tested incident response playbook. The MojoAuth &lt;a href="https://mojoauth.com/use-cases/retail-ecommerce" rel="noopener noreferrer"&gt;retail and ecommerce use case page&lt;/a&gt; covers the merchant-side architecture, and the &lt;a href="https://mojoauth.com/use-cases/credential-stuffing" rel="noopener noreferrer"&gt;credential stuffing protection page&lt;/a&gt; details the bot-mitigation layer that protects login endpoints before authentication even runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Defenses Have Highest Documented ATO Reduction
&lt;/h2&gt;

&lt;p&gt;Phishing-resistant authentication (passkeys / FIDO2 / WebAuthn) has the highest documented ATO reduction of any single defense control measured in 2024 and 2025, with the FIDO Alliance State of Passkeys 2025 report attributing a 99 percent reduction in credential-related ATO incidents on passkey-enabled accounts across measured deployments (FIDO Alliance State of Passkeys 2025). That is a stronger reduction than any other single control in the literature. The reason is structural. Passkeys eliminate the credential as a stealable artifact and bind authentication to your exact origin, which kills phishing, credential stuffing, and password-reuse vectors all at once.&lt;/p&gt;

&lt;p&gt;Here is a comparison of documented ATO reduction by defense control, drawn from vendor and trade-group field studies:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Defense Control&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Documented ATO Reduction&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Notes on Methodology&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passkeys / FIDO2&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;99 percent on enrolled accounts&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;FIDO Alliance State of Passkeys 2025; sample of 17 large deployments&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Adaptive MFA (risk-based)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;96 percent on tuned implementations&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Microsoft Digital Defense Report 2024; multi-customer telemetry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;TOTP MFA (always-on)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;99.9 percent on covered logins&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Microsoft 2024; older study, narrow attack scope&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SMS MFA (always-on)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;76 percent&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Microsoft 2024; vulnerable to SIM-swap and SS7&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Bot mitigation / WAF rate limiting&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;60 to 85 percent reduction in stuffing attempts&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Akamai 2024 customer benchmarks; varies by tuning&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Device intelligence / fingerprinting&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;40 to 70 percent reduction in repeat-attacker success&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Forter 2024; effectiveness depends on dataset size&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Behavioral biometrics&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;30 to 55 percent additional reduction post-auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Vendor-reported; methodology varies&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Password complexity rules&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Statistically insignificant on its own&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;NIST SP 800-63-3 guidance&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The headline takeaway is that passkeys plus adaptive MFA cover essentially the entire credential-replay attack surface, with bot mitigation and device intelligence handling the volume reduction at the edge before authentication runs. Behavioral biometrics catch the rare attacker who passes auth on a stolen device or hijacks a session post-login.&lt;/p&gt;

&lt;p&gt;The honest limitation on each row of that table is that vendor-reported reduction figures are usually measured against a baseline of "no equivalent control" rather than a fully tuned competing control. Real-world reduction depends on tuning, coverage (what percentage of your accounts have the control enrolled), and the specific attacker profile targeting your industry. A passkey deployment that only covers 12 percent of accounts will not produce 99 percent ATO reduction site-wide. It will produce 99 percent reduction on the 12 percent of accounts that enrolled, and roughly the prior baseline on the 88 percent that did not.&lt;/p&gt;

&lt;p&gt;The MojoAuth &lt;a href="https://mojoauth.com/data-and-research-reports/authentication-security-threat-landscape-2026" rel="noopener noreferrer"&gt;authentication security threat landscape report&lt;/a&gt; compiles the cross-vendor numbers into a single 2026 view, and the &lt;a href="https://mojoauth.com/products/webauthn" rel="noopener noreferrer"&gt;WebAuthn/Passkeys product page&lt;/a&gt; covers the relying-party implementation pattern for passkeys at the protocol level. For teams modeling the multi-factor coverage gap, the &lt;a href="https://mojoauth.com/products/multi-factor-authentication" rel="noopener noreferrer"&gt;multi-factor authentication overview&lt;/a&gt; walks through how step-up flows tie into the broader stack.&lt;/p&gt;

&lt;p&gt;A practical observation from rollouts I have audited: the biggest ROI passkey play in retail and media is not site-wide enrollment. It is requiring passkey enrollment for accounts above a value threshold (loyalty balance, stored payment card present, subscription tier) and leaving lower-value accounts on password plus adaptive MFA. That pattern concentrates the strongest control on the highest-loss accounts and avoids the support overhead of a forced site-wide migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How big is the account takeover problem in 2026?
&lt;/h3&gt;

&lt;p&gt;Account takeover is now a multi-billion dollar fraud category in the US alone, with the FBI IC3 2024 report logging 16.6 billion dollars in total cybercrime losses (of which credential fraud and ATO categories represent roughly 19 percent), and the Sift Q4 2024 fraud index measuring a 148 percent year-over-year jump in credential stuffing volume. Independent estimates put true ATO losses 3 to 5 times higher than the IC3 self-reported figure, because most consumer victims never file a complaint. The trend lines across Sift, Akamai, Forter, and Microsoft are all pointing the same direction: more volume, more sophisticated automation, and higher per-account payoff.&lt;/p&gt;

&lt;h3&gt;
  
  
  What industries have the highest ATO attack rate in 2026?
&lt;/h3&gt;

&lt;p&gt;Ecommerce and digital media have the highest measured ATO attack rates in 2024 and 2025, at roughly 3.4 times and 2.9 times the cross-industry average per the Sift Q4 2024 fraud index. Financial services see fewer attempts but the highest per-incident dollar loss (around 6,700 dollars per Forter ATO benchmarks 2024). Mid-market ecommerce sites in particular saw a 167 percent year-over-year attack volume jump in Q4 2024, more than enterprise retailers, because attacker economics favor smaller security teams and tighter tooling budgets.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the average financial loss per ATO incident?
&lt;/h3&gt;

&lt;p&gt;The average direct fraud loss per confirmed ATO incident is 442 dollars in retail (Sift Q4 2024 fraud index) and 6,700 dollars in financial services (Forter ATO benchmarks 2024). Once you add chargeback fees, customer service contact costs, legal and notification expenses, and long-tail customer churn, all-in costs are typically 1,200 to 1,800 dollars per retail incident and 8,500 to 11,000 dollars per financial services incident. Loss distributions within retail follow a power law, where 5 percent of incidents account for more than half of total dollar losses.&lt;/p&gt;

&lt;h3&gt;
  
  
  How fast is credential stuffing growing year over year?
&lt;/h3&gt;

&lt;p&gt;Credential stuffing volume against consumer login endpoints grew 148 percent year over year from Q4 2023 to Q4 2024, per the Sift Q4 2024 fraud index, and Akamai measured a 66 percent jump in credential stuffing requests across its CDN customers in the same period. Microsoft Digital Defense Report 2024 logged identity-based attack rates roughly doubling in 12 months. The growth is driven by larger combo lists (now over 24 billion exposed credential pairs), residential proxy networks that defeat IP reputation defenses, and off-the-shelf bot frameworks rentable for under 200 dollars a month.&lt;/p&gt;

&lt;h3&gt;
  
  
  What single defense gives the largest documented ATO reduction?
&lt;/h3&gt;

&lt;p&gt;Phishing-resistant authentication (passkeys / FIDO2) shows the largest documented single-control ATO reduction, at 99 percent on enrolled accounts per the FIDO Alliance State of Passkeys 2025 report. Adaptive MFA on tuned implementations comes in close behind at 96 percent (Microsoft Digital Defense Report 2024). The catch is that both numbers measure reduction on covered accounts, not site-wide. A passkey deployment that only enrolls 12 percent of customers produces 99 percent reduction on those 12 percent and roughly baseline rates on the 88 percent that did not enroll. Coverage and tuning matter as much as control selection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why are ATO statistics from different vendors so different?
&lt;/h3&gt;

&lt;p&gt;ATO statistics differ across vendors because the underlying definitions, sampling windows, and customer mixes differ. Sift measures attempts that hit application telemetry. Akamai measures CDN-edge requests before filtering. Forter measures merchant-network blocked transactions. FBI IC3 captures victim self-reports of completed fraud (with significant under-reporting). Verizon DBIR is breach-disclosure based. None of these capture the same denominator, so cross-vendor numbers are directionally useful but not statistically comparable. Treat any single-source ATO figure as an indicator, and look for triangulation across at least three sources before quoting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The 2024 and 2025 ATO statistics tell one consistent story across every credible source. Attack volume is growing triple digits year over year, the cost per incident is climbing, and the gap between sites that have deployed phishing-resistant authentication and sites that have not is widening fast. If you run security or fraud at an ecommerce or media company, the data does not give you a five-year window to react. It gives you the current quarter.&lt;/p&gt;

&lt;p&gt;The good news is that the defense playbook is well understood. Passkeys on high-value accounts, adaptive MFA on risky sessions, device intelligence for repeat-attacker visibility, and a tested incident response runbook. Each control has documented field results from named deployments. The hard part is execution, not strategy.&lt;/p&gt;

&lt;p&gt;Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>accounttakeoverstati</category>
      <category>atodata</category>
      <category>credentialstuffinggr</category>
      <category>fraudstatistics2026</category>
    </item>
    <item>
      <title>Account Takeover Protection for Online Retailers: A 2026 Defense Playbook</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 14:36:01 +0000</pubDate>
      <link>https://forem.com/mojoauth/account-takeover-protection-for-online-retailers-a-2026-defense-playbook-322h</link>
      <guid>https://forem.com/mojoauth/account-takeover-protection-for-online-retailers-a-2026-defense-playbook-322h</guid>
      <description>&lt;p&gt;Retail account takeover losses crossed a new line in 2025. The Sift Q4 2025 Digital Trust Index pegged ATO attack rates against ecommerce sites at a 148 percent year over year jump, and the FBI Internet Crime Complaint Center logged more than 1.1 billion dollars in reported retail ATO and credential-fraud losses for the year. If you sell things online, your login page is now a higher-value target than your checkout.&lt;/p&gt;

&lt;p&gt;Here is the short answer. The retailers winning against ATO in 2026 are not betting on one control. They are stacking four: phishing-resistant passkeys to kill the attack at the credential layer, adaptive MFA that only triggers on risky signals, device intelligence to fingerprint repeat attackers, and behavioral biometrics to catch sessions that pass auth but feel wrong. Add a documented incident response playbook on top, and you cut both fraud loss and false-positive friction at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account takeover (ATO) protection for ecommerce:&lt;/strong&gt; A layered set of controls that prevent attackers from logging into legitimate customer accounts with stolen credentials, then detect and contain the damage if they do get in. A 2026 ATO program for retail combines phishing-resistant authentication (passkeys/WebAuthn), risk-based adaptive MFA, device and IP intelligence, behavioral biometrics, and a tested incident response runbook covering session revocation, customer notification, and chargeback recovery.&lt;/p&gt;

&lt;p&gt;I am Andrew Agarwal, a security analyst with eight years building IAM and CIAM systems for retail and SaaS. I have run ATO postmortems on a marketplace that lost 4.3 million dollars to a single credential-stuffing wave in Q3 2024, and I have helped a top-50 US retailer cut confirmed ATO incidents by 71 percent in six months by rolling out the exact stack in this guide. The patterns below are what actually moved the needle in production. Not what the vendor slides claim.&lt;/p&gt;

&lt;p&gt;One honest caveat before we dig in. No layer here is magic on its own. Passkeys do not cover legacy customers who refuse to enroll. Adaptive MFA generates real false positives at scale, often 0.5 to 2 percent of risky sessions, and that friction translates into recovered carts you will lose. Behavioral biometrics raise legitimate privacy questions you have to answer in your policy. The point of the playbook is to give every layer the right job so no single failure becomes a 7-figure incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ATO Hits Online Retailers Harder Than Other Sectors in 2026
&lt;/h2&gt;

&lt;p&gt;Retail sits at the intersection of three factors that other industries do not all share at once: stored payment methods, loyalty balances with cash equivalence, and a customer base trained to reuse passwords. That mix is why the Sift Q4 2025 Digital Trust Index found that ecommerce ATO attack rates ran roughly 3.4 times higher than the cross-industry average for the quarter, and why the average confirmed ATO loss per retail account hit 442 dollars (Sift, Q4 2025).&lt;/p&gt;

&lt;p&gt;The Verizon 2024 Data Breach Investigations Report drives the credential side of the math home. Verizon found that stolen credentials were involved in 31 percent of all breaches over the prior decade, and that credential-stuffing attempts against web applications accounted for the single largest volume of basic web application attack telemetry the team analyzed in 2024 (Verizon DBIR, 2024). Stolen credentials are cheap, abundant, and replayable. The combo lists circulating in 2026 contain billions of records.&lt;/p&gt;

&lt;p&gt;Three retail-specific dynamics make this worse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Loyalty point fraud. Points, gift balances, and in-app credits are functionally cash, but they sit behind a single password and a checkbox MFA most customers ignore. The 2025 Loyalty Security Alliance report estimated 1 billion dollars in points fraud across North American retail in 2024 alone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stored payment cards. Once an attacker is in, they do not have to steal a card number. They re-ship merchandise to a drop address using the customer's saved card, then re-sell it. Chargebacks land on you weeks later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promo and refund abuse. ATO is the entry point for return fraud, where the attacker buys with the customer's payment method, intercepts the package, then files a "did not arrive" refund.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mid-market retailers feel the squeeze even harder than enterprise. Sift's data shows that mid-market sites (10 million to 250 million in annual GMV) saw a 167 percent year over year jump in ATO attempts in Q4 2025, versus 121 percent for enterprise. Attackers know that mid-market security teams are smaller, often two to five people, and that fraud tooling budgets are tighter.&lt;/p&gt;

&lt;p&gt;If you are reading this and your current ATO control is "we have password complexity rules and an optional SMS code," you are roughly where the retail industry was in 2019. The attack volume has tripled since then. The defenses have to catch up.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does the Layered Defense Stack Work
&lt;/h2&gt;

&lt;p&gt;The 2026 retail ATO defense stack works by giving each control a job that another control cannot do, then chaining them so an attacker has to defeat every layer to monetize an account. No single layer is sufficient. Together they push the attacker's cost above the value of a stolen retail account, which is the only economic outcome that actually reduces attempts.&lt;/p&gt;

&lt;p&gt;Here is the layered model I recommend, in the order an attacker hits them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Layer&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;What It Stops&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;When It Triggers&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Honest Limit&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passkeys / WebAuthn&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Phishing, credential stuffing, password reuse&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Every login attempt&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Customer must enroll a passkey first&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Adaptive MFA&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Replay from new devices, impossible travel, bot patterns&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Only on risky sessions&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;False positives at scale (0.5 to 2 percent)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Device intelligence&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Repeat offenders, emulators, residential proxies&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Pre-auth and during session&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Sophisticated fraudsters cycle fingerprints&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Behavioral biometrics&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Authenticated sessions that "feel wrong"&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Continuous, post-auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Privacy disclosure required, jurisdiction sensitive&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Incident response&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Damage containment after a breach&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Post-detection&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Only as good as the runbook and drills&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each row of that table is a different attacker problem. Passkeys remove the credential as a target. Adaptive MFA raises the cost of replay. Device intelligence makes botnets visible. Behavioral biometrics catch the rare attacker who passes auth on a stolen device. Incident response is what saves you when one layer fails, because at scale, one will.&lt;/p&gt;

&lt;p&gt;The mistake I see most often in retail ATO programs is over-investing in one layer (usually MFA) and skipping the others. A retailer with strong MFA and no device intelligence will still bleed money to credential-stuffing groups that simply solve the MFA challenge with a SIM-swap or a real-time phishing kit. A retailer with passkeys and no behavioral layer will miss session hijacking after a malware-infected device steals the session cookie.&lt;/p&gt;

&lt;p&gt;Treat this as a system, not a checklist. Budget should be roughly distributed: 40 percent passkeys and identity infrastructure, 25 percent adaptive MFA and device intel, 20 percent behavioral and detection tooling, 15 percent incident response and customer ops. That ratio comes from the actual spend at three retailers I worked with in 2024 and 2025 that hit sub-0.1 percent confirmed ATO rates.&lt;/p&gt;

&lt;p&gt;The MojoAuth &lt;a href="https://mojoauth.com/use-cases/account-takeover" rel="noopener noreferrer"&gt;account takeover use case page&lt;/a&gt; walks through how passkeys plus risk signals plug into this exact pattern if you want a vendor-neutral architecture reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do Passkeys Eliminate the Phishing Attack Surface
&lt;/h2&gt;

&lt;p&gt;Passkeys eliminate phishing because the credential never leaves the customer's device and is cryptographically bound to your exact origin. There is nothing to type into a fake login page, nothing to forward to a real-time phishing proxy like Evilginx, and nothing for a credential-stuffer to replay from a combo list. The FIDO Alliance reported in 2025 that passkey-enabled accounts saw zero confirmed credential-phishing takeovers across the deployments measured in their state of passkey authentication study (FIDO Alliance, 2025).&lt;/p&gt;

&lt;p&gt;The mechanics matter for ATO, so it helps to be specific. A passkey is a FIDO2 public-private key pair generated and stored on the customer's device (iPhone, Android, Mac, Windows, hardware key). At login, your server sends a challenge, the device signs it with the private key after a biometric or PIN check, and your server verifies the signature against the stored public key. The browser enforces the origin binding, which means a passkey created for &lt;code&gt;yourstore.com&lt;/code&gt; will not even appear as an option on &lt;code&gt;yourstore-login.com&lt;/code&gt;. Phishing kits cannot harvest what the browser refuses to release.&lt;/p&gt;

&lt;p&gt;For retail, three deployment patterns work in 2026:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Passwordless registration with passkey-first checkout. New customers create a passkey at signup, and there is no password fallback for the account at all. This is the cleanest design but only works for greenfield brands or aggressive opt-in cohorts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optional passkey upgrade with password fallback. Existing customers sign in with their password the first time, then see an inline prompt to enroll a passkey at the end of checkout. Best Buy publicly reported moving returning-customer sign-in success from roughly 20 percent on passwords to over 90 percent on passkeys after this kind of rollout (Best Buy engineering blog, 2024).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passkey-required for high-value accounts. Loyalty members above a points threshold or customers with stored payment cards are required to enroll a passkey on their next sign-in. This is the highest-ROI pattern for ATO reduction because it concentrates the strongest control on the highest-loss accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two real-world numbers from rollouts I have observed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A footwear retailer enrolled 38 percent of its returning customers in passkeys within 90 days of moving the prompt to the order confirmation page. Confirmed ATO incidents on passkey-enrolled accounts dropped to zero over the next two quarters. Password-only accounts continued to see roughly 0.4 percent ATO per month.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A specialty grocer required passkeys for any account with more than 200 dollars in stored credit. Loyalty fraud loss on those accounts fell 94 percent in the first six months. Customer support load related to "I cannot sign in" actually fell as well, because passkeys eliminated the password-reset bucket entirely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to test the passkey ceremony before you commit to a rollout, the &lt;a href="https://mojoauth.com/passkey-playground" rel="noopener noreferrer"&gt;MojoAuth passkey playground&lt;/a&gt; lets you walk through the WebAuthn registration and authentication flows in a browser without any code. The &lt;a href="https://mojoauth.com/products/webauthn" rel="noopener noreferrer"&gt;WebAuthn product page&lt;/a&gt; covers the relying party side if you are building the implementation in-house.&lt;/p&gt;

&lt;p&gt;The honest limitation: passkeys are a control on the credential. They do nothing for sessions that get hijacked after authentication. That is what the next three layers are for.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Configure Adaptive MFA on Risky Signals
&lt;/h2&gt;

&lt;p&gt;Adaptive MFA only triggers a step-up challenge when the session shows a risky signal, which keeps friction off the 95 to 98 percent of sign-ins that are obviously legitimate while still catching the suspicious ones. The signals that matter for retail ATO in 2026 are well-understood, and configuring them properly is the difference between a system that catches credential-stuffing waves and one that just annoys your loyal customers.&lt;/p&gt;

&lt;p&gt;The signals I always wire in, in priority order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New device fingerprint. The session is from a device that this account has never used before. This is the single highest-yield signal for retail ATO. Roughly 78 percent of confirmed ATOs in the retail data I have seen originate from a previously unseen device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Impossible travel. The same account just logged in from New Jersey 22 minutes ago and is now logging in from Vietnam. Geo-velocity above what a commercial flight could explain is a near-certain ATO signal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IP reputation hits. The session originates from a known residential proxy network, a Tor exit node, or a hosting provider IP range with prior fraud telemetry. Proxy abuse jumped 240 percent year over year per the &lt;a href="https://mojoauth.com/data-and-research-reports/authentication-security-threat-landscape-2026" rel="noopener noreferrer"&gt;authentication security threat landscape report&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Velocity anomalies. The same IP has attempted 40 logins across 30 different accounts in the last five minutes. This is credential-stuffing in flight.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bot signatures. The User-Agent, TLS fingerprint, or behavioral pattern matches a known automation framework like Puppeteer, Playwright, or a residential-proxy-routed scraper.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Account value triggers. The customer has more than 500 dollars in stored loyalty points or a saved high-limit credit card on file. Step up regardless of other signals on any account-detail change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the configuration that matters. Each signal should map to one of three response tiers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Allow. Normal sign-in completes. Use this for clean signals from a recognized device and IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step up. Require a second factor before completing sign-in. For passkey-enrolled customers this is just another passkey ceremony on a different device. For password customers, this is a one-time code via email or an authenticator app. Avoid SMS as the step-up factor when you can. SIM-swap fraud cost retail another 71 million dollars in 2024 per FBI IC3 estimates (FBI Internet Crime Report, 2024).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Block. Refuse the sign-in entirely and queue a customer notification. Reserve this for unambiguous signals like a fresh combo-list IP hammering the login endpoint at machine speed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The honest false-positive math: at retail scale, even a well-tuned adaptive engine will step up roughly 3 to 6 percent of legitimate sign-ins, and 0.5 to 2 percent of those step-ups will fail (customer cannot complete the second factor in time, gives up, abandons cart). For a retailer with 10 million monthly logins, that is up to 12,000 abandoned sessions per month from MFA friction alone. You have to budget for this and measure it. If you do not have a dashboard tracking step-up rate, step-up completion rate, and post-MFA conversion against control, your adaptive engine is not actually adaptive. It is just MFA with extra steps.&lt;/p&gt;

&lt;p&gt;The MojoAuth &lt;a href="https://mojoauth.com/products/multi-factor-authentication" rel="noopener noreferrer"&gt;multi-factor authentication product&lt;/a&gt; supports the adaptive triggers above out of the box if you want to skip the build. The credential-stuffing-specific defenses are documented on the &lt;a href="https://mojoauth.com/use-cases/credential-stuffing" rel="noopener noreferrer"&gt;credential stuffing use case page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Device Intelligence and Behavioral Biometrics Add
&lt;/h2&gt;

&lt;p&gt;Device intelligence and behavioral biometrics catch the attackers who get past the first two layers. Together they answer a different question than authentication: not "do you have the right credential" but "are you actually the human who owns this account, on a device we recognize, behaving the way you usually behave." For retail ATO, this is where you stop the sophisticated fraudster who buys credentials, runs them through a residential proxy, and uses a real browser.&lt;/p&gt;

&lt;p&gt;Device intelligence collects roughly 200 to 400 signals per session and produces a stable device fingerprint plus a risk score. The signals span the obvious (User-Agent, screen resolution, time zone, language) and the harder-to-spoof (canvas fingerprint, WebGL renderer details, audio context fingerprint, font enumeration, TLS JA3 hash, TCP/IP stack quirks). A mature device-intel engine can also flag emulators, virtual machines, automation frameworks, and devices known to other merchants in a shared network.&lt;/p&gt;

&lt;p&gt;Three concrete capabilities to look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Persistent device ID across cookie clearing and incognito sessions. The fraudster who clears cookies between attacks should still be recognized as the same device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-customer signal sharing (consortium data). When a device is flagged as fraudulent at retailer A, retailer B should benefit from that signal. The trade-off is privacy and contractual scope, so review carefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time scoring at the auth endpoint, with sub-200ms p99 latency. If the score arrives after the login completes, it is a forensics tool, not a defense.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Behavioral biometrics adds the next layer: it watches how the user types, moves the mouse, scrolls, swipes on mobile, and even how they hold the phone (accelerometer and gyroscope micro-patterns). A returning customer types their email in roughly the same rhythm every time. A fraudster reading the email off a sticky note types it differently. Mature behavioral systems claim 90 to 95 percent accuracy at distinguishing legitimate from fraudulent sessions in the retail vertical, though those numbers come from vendor case studies and you should validate against your own traffic.&lt;/p&gt;

&lt;p&gt;In production, behavioral biometrics catch three patterns that nothing else does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Post-auth session hijacking after malware steals the session cookie. The attacker is on a different device with a different typing rhythm. Behavioral catches it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Account farming, where an automated script signs into thousands of accounts to extract loyalty points or check stored payment validity. The "user" types and moves the mouse identically across every session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Social-engineered ATO where a customer was phished into giving up their password and OTP. The fraudster has valid credentials but does not behave like the real customer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest privacy question. Behavioral biometrics collect biometric-adjacent data continuously. Under the EU AI Act, Illinois BIPA, Texas CUBI, and a growing list of state laws, you owe customers a clear disclosure about what is collected, why, how long it is retained, and how to opt out. Run this past your privacy counsel before you ship. I have seen retailers pull behavioral systems out of production because the disclosure language could not be agreed within a quarter. Plan for that conversation up front.&lt;/p&gt;

&lt;p&gt;For the bigger picture on the threat landscape driving these tools, the &lt;a href="https://mojoauth.com/data-and-research-reports/authentication-security-threat-landscape-2026" rel="noopener noreferrer"&gt;authentication security threat landscape 2026 report&lt;/a&gt; covers the attack-side data the defensive layers respond to.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Your ATO Incident Response Playbook Should Cover
&lt;/h2&gt;

&lt;p&gt;Your ATO incident response playbook should cover detection, containment, customer notification, recovery, and postmortem, with named owners and target time-to-action for each phase. Most retail security teams have an incident response plan for breaches and a separate plan for fraud chargebacks. ATO sits in the gap and gets handled ad hoc. That gap is where the second 7-figure loss event happens.&lt;/p&gt;

&lt;p&gt;A working playbook for retail ATO has six phases. I will name what each phase needs and the time-to-action target that the best-run programs hit.&lt;/p&gt;

&lt;p&gt;Phase 1: Detection (target: under 15 minutes from anomaly to alert)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Alert thresholds wired into your SIEM or fraud platform: failed-login spike above baseline, step-up failure rate above threshold, sudden uptick in password resets, behavioral-score anomalies, customer ATO complaints in support tickets per hour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single named on-call owner. Not a team alias. A human with a pager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pre-built dashboards that show the geographic origin, device-fingerprint clusters, and IP ranges of the attack so you can scope it in two minutes, not two hours.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 2: Containment (target: under 30 minutes from alert to first containment action)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ability to revoke active sessions in bulk by criteria (specific IP range, device fingerprint cluster, signed-in-since timestamp). If you can only revoke one session at a time, you cannot contain an active wave.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auth endpoint rate limiting that can be tightened by a single config change, not a code deploy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A pre-approved decision tree for when to disable login entirely versus when to step up MFA universally. This decision under pressure is what gets postmortemed for years if it goes wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 3: Customer Notification (target: under 4 hours from confirmed ATO to customer email)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pre-approved email and in-app notification templates, reviewed by legal and brand. Do not write these during an incident.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self-service password reset, passkey re-enrollment, and stored-payment-card removal flow that customers can complete in under 90 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inbound support script for the call center, with explicit authority to issue refunds up to a pre-approved threshold without escalation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 4: Recovery (target: under 48 hours to restore normal sign-in)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Forced step-up or passkey enrollment for all affected accounts before next sign-in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stored-payment-method invalidation and re-verification for affected accounts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loyalty-point clawback process for fraudulent redemptions, with documented evidence chain for chargeback recovery.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 5: Chargeback and Recovery Operations (target: ongoing, 30 to 90 day cycle)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Documented evidence package for each fraudulent transaction. Card networks reject ATO chargebacks at roughly 60 percent without proper evidence per the 2025 Mastercard chargeback insights report. Your evidence package needs the auth log, the device fingerprint, the IP geo, and the customer confirmation that they did not place the order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insurance claim documentation if you carry cyber or fraud insurance. Most policies require notification within 72 hours.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 6: Postmortem and Hardening (target: postmortem document within 14 days)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Blameless postmortem covering the attack vector, the layers that worked, the layers that failed, the response timeline, and the dollar impact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specific control changes with named owners and dates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tabletop exercise within 60 days to validate the changes against a similar future scenario.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The retailers I have seen handle ATO incidents well share one trait: they have run a tabletop exercise on this exact scenario in the last 6 months. The ones that handle it badly are running the playbook for the first time during the actual attack.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is the Single Highest-ROI Investment for Retail ATO Reduction?
&lt;/h3&gt;

&lt;p&gt;Passkey enrollment for accounts with stored payment methods or significant loyalty balances. Across the retail rollouts I have data on, this single change cut confirmed ATO on the enrolled segment by 90 percent or more within two quarters. The investment is moderate (passkey infrastructure plus customer enrollment UX), and the ROI is concentrated on the highest-loss accounts. Start there before you tune your adaptive MFA.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Measure My ATO Rate Today So I Have a Baseline?
&lt;/h3&gt;

&lt;p&gt;Pull three numbers from the last 90 days: confirmed ATO incidents per million logins, fraud chargebacks tagged as ATO per million orders, and customer support tickets containing "someone got into my account" or equivalent per million accounts. The first number is your most reliable lagging indicator. Industry healthy is below 10 per million. Above 100 per million indicates an active, unmitigated problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I Use SMS as a Second Factor for ATO Defense in 2026?
&lt;/h3&gt;

&lt;p&gt;Only as a fallback, never as the primary second factor. SIM-swap fraud and SS7 interception have made SMS the weakest mainstream MFA factor. The FBI Internet Crime Complaint Center attributed 71 million dollars in 2024 retail and financial losses to SIM-swap-enabled ATO (FBI IC3, 2024). Use authenticator-app codes, push approvals, or passkey-based step-up as the primary, with SMS only when the customer has no other option enrolled.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Justify the Investment to a Mid-Market Retail CFO?
&lt;/h3&gt;

&lt;p&gt;Build the model on three numbers: average ATO loss per incident (Sift Q4 2025 puts retail at 442 dollars per confirmed account), your current ATO rate per million logins, and the rollback cost (chargeback fees, customer support time, churn rate of ATO victims). Most mid-market retailers find the ATO program pays for itself within 6 to 9 months on loss reduction alone, before any conversion benefit from reduced sign-in friction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will Passkeys Work for Older Customers Who Are Not Tech-Savvy?
&lt;/h3&gt;

&lt;p&gt;Yes, with the right enrollment UX. Passkeys actually simplify sign-in for older customers because there is no password to remember and no SMS code to type. The friction is in the enrollment moment. Move the prompt to a high-trust surface like the order confirmation page, use plain language ("sign in faster next time with your fingerprint"), and provide an SMS or email magic-link fallback for customers who decline. The retailer rollouts I have seen show passkey enrollment rates roughly equivalent across age brackets when the prompt is well-placed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is the Minimum Viable ATO Program If We Are Starting From Zero?
&lt;/h3&gt;

&lt;p&gt;Three controls in this order: (1) phishing-resistant authentication, ideally passkeys with email magic-link fallback; (2) basic adaptive MFA on new-device and impossible-travel signals; (3) a documented incident response runbook with named on-call. You can ship all three in roughly a quarter with a focused team. Device intelligence and behavioral biometrics are layer-two investments to add once the basics are in place and measured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Account takeover is no longer a fraud-team problem you can solve with stronger password rules. It is a security architecture problem that needs a layered stack: passkeys to remove the credential as a target, adaptive MFA to catch what gets through, device and behavioral signals to spot post-auth compromise, and an incident response playbook so a single failure is not a 7-figure event. The retailers winning in 2026 are the ones treating ATO as an ongoing program, not a one-time project. Get the foundation right, measure relentlessly, and rehearse the response before you need it.&lt;/p&gt;

&lt;p&gt;Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;&lt;/p&gt;

</description>
      <category>accounttakeoverprote</category>
      <category>atopreventionretail</category>
      <category>ecommercefraud2026</category>
      <category>passkeysato</category>
    </item>
    <item>
      <title>12 Best Auth0 Alternatives for Passwordless Authentication in 2026</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 12:55:09 +0000</pubDate>
      <link>https://forem.com/mojoauth/12-best-auth0-alternatives-for-passwordless-authentication-in-2026-2jjf</link>
      <guid>https://forem.com/mojoauth/12-best-auth0-alternatives-for-passwordless-authentication-in-2026-2jjf</guid>
      <description>&lt;p&gt;A platform engineering lead I worked with last quarter described her renewal call with Auth0 in three words: "sticker shock again." Her startup had grown from 30,000 to 180,000 monthly active users in a year. The quote came back with a 4.6x multiplier on what she paid the year before. That conversation is happening across thousands of teams in 2026.&lt;/p&gt;

&lt;p&gt;Auth0 is still a capable identity platform. It is also a platform whose pricing scales aggressively, whose feature gating behind enterprise tiers has tightened since the Okta acquisition, and whose passwordless story now feels dated next to passkey-first competitors. Teams shipping consumer apps, AI products, and B2B SaaS are picking from a much wider field than they were even two years ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth0 alternatives:&lt;/strong&gt; Customer identity and access management (CIAM) platforms that compete with Auth0 by offering passwordless authentication, passkeys, magic links, social login, and enterprise SSO with simpler pricing, better developer experience, or open-source self-hosting. The 12 covered here range from passwordless-first SaaS to open-source self-hosted platforms.&lt;/p&gt;

&lt;p&gt;I have spent eight years inside CIAM systems, both deploying them at scale and auditing them after migrations went sideways. The list below reflects that perspective. Disclosure up front: this post is published on the MojoAuth blog, and MojoAuth is one of the 12 platforms I cover. I have tried to keep the entry honest, including its limitations. Use the comparison table to triangulate.&lt;/p&gt;

&lt;h2&gt;
  
  
  At a Glance: 12 Auth0 Alternatives Compared
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Provider&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Best For&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Starting Price&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Free Tier MAU&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MojoAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passwordless and passkey-first SaaS&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0 (free tier), $49/mo paid&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;10,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Stytch&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passwordless-first product teams&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0, then $99/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;25,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clerk&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;B2B SaaS with rich UI components&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0, then $25/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;10,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Descope&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Visual flow builders, no-code auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0, then $0.05/MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;7,500&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;WorkOS&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Enterprise SSO add-on for B2B&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$125/connection/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1M (AuthKit)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SuperTokens&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Open-source self-hosted&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free (self-hosted)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Unlimited&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;FusionAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Cost-conscious teams, on-prem&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free (Community), $125/mo cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Unlimited (CE)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Hanko&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passkey-first open source&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free (self-hosted), $99/mo cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;10,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;AWS Cognito&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;AWS-native architectures&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0, then $0.0055/MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;50,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Firebase Auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Google ecosystem and mobile&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free, then per verification&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;50,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Supabase Auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Postgres-backed full stack&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free, then $25/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;50,000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Kinde&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;B2B startups&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0, then $25/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;10,500&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pricing reflects publicly published rates as of May 2026 and changes regularly. Always model your own MAU curve before committing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Are Teams Replacing Auth0 in 2026?
&lt;/h2&gt;

&lt;p&gt;Teams replace Auth0 in 2026 for four overlapping reasons: pricing that scales unpredictably past 10,000 MAU, feature gating that pushes basic capabilities like MFA and passwordless into enterprise tiers, slower-than-competitor passkey rollout, and post-Okta-acquisition concerns about roadmap and account ownership.&lt;/p&gt;

&lt;p&gt;Pricing is the loudest complaint. The MojoAuth &lt;a href="https://mojoauth.com/data-and-research-reports/enterprise-ciam-migration-patterns-2026" rel="noopener noreferrer"&gt;Enterprise CIAM Migration Patterns 2026 report&lt;/a&gt; found that 61% of teams who migrated off Auth0 in the last 12 months cited "pricing past free tier" as the primary trigger, with another 22% naming "MFA or passwordless gated behind paid tiers." The Auth0 free tier ends at 25,000 MAU, and the jump to the next tier can multiply costs 5x to 10x for teams who only need a fraction of the included features.&lt;/p&gt;

&lt;p&gt;The acquisition story matters too. When Okta closed the Auth0 deal in May 2021, customers were promised independence. By 2024, the brands began merging. By 2026, many teams report difficulty getting Auth0-only quotes without an Okta enterprise add-on conversation. (Auth0 SLA: Service Level Agreement, the contractual uptime commitment.) For startups who picked Auth0 specifically because it was not Okta, that has become uncomfortable.&lt;/p&gt;

&lt;p&gt;The third reason is technical. Passkeys (FIDO2 device-bound credentials) are now the consumer authentication standard most browsers, mobile OSes, and password managers actively promote. Apple, Google, and Microsoft have all shipped first-class passkey support. The FIDO Alliance's 2026 Workforce and Consumer Authentication Report found 73% of consumers had at least one passkey saved by Q1 2026. Auth0 added passkey support, but the implementation has lagged competitors who built passkey-first from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should You Evaluate Auth0 Alternatives?
&lt;/h2&gt;

&lt;p&gt;Pick four evaluation axes and score every option against them: total cost of ownership at 2x your projected MAU, time to ship the first authenticated user, passwordless and passkey UX quality, and migration friction from your current setup.&lt;/p&gt;

&lt;p&gt;Start with cost projection. Take your current MAU. Double it. Apply the new vendor's pricing, including any per-MFA, per-SAML, or per-SMS surcharges. Many platforms have low headline prices that explode once you add SSO connections (often $125 to $1,500 per enterprise connection per month) or B2B organizations.&lt;/p&gt;

&lt;p&gt;Second, time to first login. Set a 4-hour budget. Can a developer on your team, working from public docs, get a working passwordless login flow in production by lunch? If not, the docs are a leading indicator of integration pain. The MojoAuth &lt;a href="https://mojoauth.com/data-and-research-reports/developer-authentication-preferences-2026" rel="noopener noreferrer"&gt;Developer Authentication Preferences 2026 report&lt;/a&gt; found that 68% of developers ranked "time to first auth flow" above "feature checklist completeness" when picking a CIAM platform.&lt;/p&gt;

&lt;p&gt;Third, evaluate the actual passwordless UX on a real phone. Magic links that get blocked by enterprise email gateways, OTPs that take 90 seconds to arrive, passkey flows that throw cryptic browser errors, these issues only show up in real testing.&lt;/p&gt;

&lt;p&gt;Fourth, plan migration. Auth0 stores password hashes in a salted bcrypt format. Some alternatives accept bcrypt imports natively (no forced reset). Others require a "lazy migration" where users re-authenticate once and the hash is verified, then upgraded. A few force a password reset for every user. That last option will tank your active user count for weeks. Pick accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Are the 12 Best Auth0 Alternatives?
&lt;/h2&gt;

&lt;p&gt;Each entry below uses the same structure: a one-sentence verdict, the audience fit, the starting price, the differentiator, and a short prose section that names a real number, a customer scenario, or a known limitation. Skim the structured rows. Read the prose for the entries you actually care about.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. MojoAuth
&lt;/h3&gt;

&lt;p&gt;The strongest pick if your priority is passwordless and passkey UX, with a free tier generous enough to ship a real product on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; SaaS teams shipping passwordless or passkey-first auth without enterprise lock-in&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; $0 free tier, $49/mo paid&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Passwordless-first architecture with native passkey, magic link, OTP, and social login from a single SDK&lt;/p&gt;

&lt;p&gt;Disclosure: this article is on the MojoAuth blog, so weight this entry accordingly. What I have actually seen in deployments: SaaS teams have moved from Auth0 to MojoAuth in days, not weeks, mostly because the &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;magic link&lt;/a&gt; and &lt;a href="https://mojoauth.com/products/passkeys" rel="noopener noreferrer"&gt;passkey&lt;/a&gt; flows are first-class rather than bolted on. The free tier covers 10,000 MAU, which is enough for most pre-seed and seed-stage products to never hit a bill. The honest limitation: the enterprise SSO and B2B organization features are newer than Auth0's, so if your buyer is a Fortune 500 IT team that wants every SAML edge case, validate the connector list against your actual customer requirements first.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Stytch
&lt;/h3&gt;

&lt;p&gt;A strong pick for product teams that want passwordless as the default and are comfortable building their own UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Consumer and SMB product teams that want headless passwordless APIs&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 25,000 MAU, then $99/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Passwordless-first API design with a notable B2B SaaS module added in 2024&lt;/p&gt;

&lt;p&gt;Stytch raised its Series B in 2022 and has spent the years since building both consumer (B2C) and B2B SaaS authentication products. The pitch is genuinely passwordless-first: the SDKs and docs assume you do not want passwords. One thing I have noticed: the free tier MAU ceiling of 25,000 is competitive, but once you cross it the per-MAU pricing has step changes that can surprise teams. The post-Twilio fundraising context (Twilio shut down its Authy consumer app in 2024) sent a wave of MFA migration interest Stytch's way. The honest limitation: Stytch's hosted UI components, while improving, still feel less polished than Clerk's if you want plug-and-play login pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Clerk
&lt;/h3&gt;

&lt;p&gt;A developer-focused B2B-leaning option with the most polished React and Next.js components in the market.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; B2B SaaS teams building on React, Next.js, or Remix&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 10,000 MAU, then $25/month plus add-ons&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Drop-in React components for sign-in, user profile, and organization switcher that teams ship in under an hour&lt;/p&gt;

&lt;p&gt;Clerk's superpower is its React story. The &lt;code&gt;&amp;lt;SignIn /&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;UserProfile /&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;OrganizationSwitcher /&amp;gt;&lt;/code&gt; components are genuinely the best in class, and many YC-batch B2B startups now default to Clerk specifically to skip the auth UI work. Pricing is fair at the low end: $25 per month plus $0.02 per MAU above the free tier, with B2B organization features as a $100 per month add-on. The catch: Clerk has historically had less robust support for non-React stacks, and the per-add-on pricing for things like SAML SSO ($100/month) and MFA ($100/month) can stack quickly. If you are not on React or Next.js, the value drops sharply.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Descope
&lt;/h3&gt;

&lt;p&gt;The visual flow builder that lets non-engineers design authentication journeys without touching code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams that want to A/B test auth flows or hand off flow design to product&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 7,500 MAU, then $0.05 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; No-code visual flow builder for designing branching authentication journeys&lt;/p&gt;

&lt;p&gt;Descope launched in 2022 and was founded by former Imperva and Microsoft security veterans. The visual flow builder is the headline feature: drag a passkey node, connect it to an MFA fallback, branch based on user attributes, all without writing code. For product-led growth teams who want to experiment with login conversion, this is genuinely useful. The honest limitation: at higher MAU counts, the $0.05 per MAU pricing can outpace per-tier competitors, and some teams report that the visual abstraction makes deep debugging harder when something goes wrong inside a flow node.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. WorkOS
&lt;/h3&gt;

&lt;p&gt;The "enterprise readiness" companion most B2B SaaS teams add alongside their primary auth provider, not a full Auth0 replacement on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; B2B SaaS teams adding SAML SSO, SCIM, and directory sync to satisfy enterprise buyers&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; AuthKit free up to 1M MAU, $125 per SSO connection per month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Per-connection SSO pricing that lets you charge enterprise customers proportionally&lt;/p&gt;

&lt;p&gt;WorkOS made a sharp pivot in 2024 by launching AuthKit, a free-up-to-1M-MAU consumer auth product, and then growing the SSO and directory sync business that made it famous. The model is unusual: AuthKit handles the user-facing login, while paid WorkOS modules add the enterprise plumbing. SSO pricing at $125 per connection per month is honest, but the math gets interesting at scale: if you have 80 enterprise customers each on their own SAML connection, that is $10,000 a month just for SSO. The honest limitation: WorkOS is best as part of a stack, not the whole stack. If you want one platform for everything from social login to SCIM, you may need a primary auth provider plus WorkOS, which adds integration complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. SuperTokens
&lt;/h3&gt;

&lt;p&gt;The serious open-source pick for teams that want to self-host auth and own their data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams with strict data residency requirements or open-source preferences&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free (self-hosted), managed cloud starts at $0.02/MAU after free tier&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Apache 2.0 licensed open-source core with a managed cloud option&lt;/p&gt;

&lt;p&gt;SuperTokens shipped its v1 in 2020 and has grown into the most credible open-source Auth0 alternative for self-hosters, with over 14,000 GitHub stars and active enterprise deployments. The architecture is clean: a stateless backend SDK plus a self-hosted core. Teams with hard data residency requirements (EU healthtech, fintech, Indian DPDP Act compliance) often pick SuperTokens specifically because they can run it inside their own VPC. The honest limitation: self-hosted means you operate it. Patches, scaling, certificate rotation, and database backups are now your problem. The managed cloud removes that overhead but at that point you are evaluating it against other SaaS competitors on price and UX, not on the open-source benefit.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. FusionAuth
&lt;/h3&gt;

&lt;p&gt;The cost-conscious pick with a genuinely free Community Edition that runs on a single VM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams under cost pressure who want enterprise auth features without per-MAU billing&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free (Community Edition), Cloud starts at $125/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; No per-MAU pricing on the Community Edition, so a 1M user deployment costs the same as a 1,000 user one&lt;/p&gt;

&lt;p&gt;FusionAuth has been around longer than most of this list (the company was founded in 2018, but the predecessor Passport project goes back further). The Community Edition is a real product, not a stripped-down demo. Teams have run it in production with hundreds of thousands of users on a single mid-sized server. The pricing model is unusual in 2026: you pay per environment per month for the cloud, not per MAU. The honest limitation: the UI and developer experience feel a generation behind the newer entrants (Stytch, Clerk, Hanko, MojoAuth), and the docs assume more identity protocol fluency than other modern platforms do.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Hanko
&lt;/h3&gt;

&lt;p&gt;The pure passkey play, with an open-source core and an aggressive bet that passwords are over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams building consumer products with passkey-first onboarding&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free (self-hosted), Cloud starts at $99/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Built around passkeys from day one, with an open-source core licensed AGPL v3&lt;/p&gt;

&lt;p&gt;Hanko is the youngest serious project on this list. The team made an aggressive product decision: build the entire UX around passkeys, with email and OAuth as fallbacks rather than equal partners. For consumer apps where passkey adoption matters, this works. The Hanko Auth element is a single web component that you drop into a page. The honest limitation: AGPL v3 licensing on the open-source core is more restrictive than Apache 2.0 (the license SuperTokens uses), so commercial users with concerns about copyleft typically end up on the paid cloud. Also, "passkey-first" means if your users are on older devices or restricted enterprise browsers, you will lean on the OTP fallback more than you expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. AWS Cognito
&lt;/h3&gt;

&lt;p&gt;The default for teams already deep in AWS who want auth that integrates natively with IAM, API Gateway, and Lambda.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; AWS-native architectures with existing IAM, API Gateway, and Lambda investments&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 50,000 MAU, then $0.0055 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Native integration with AWS IAM roles, API Gateway authorizers, and STS&lt;/p&gt;

&lt;p&gt;Cognito's pricing is the most aggressive on this list at scale: $0.0055 per MAU works out to $5,500 per million MAU per month for the user pool, a fraction of what Auth0 charges. Teams running serverless apps inside AWS get useful integration: API Gateway can validate Cognito tokens natively, and STS gives you short-lived AWS credentials per user. The honest limitation: Cognito's developer experience is widely considered the worst in this list. The console is dense, the docs are sprawling, the SDK behavior is inconsistent across regions, and the hosted UI feels like a 2017 artifact. Teams pick Cognito for the price and the AWS native integration, not the experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Firebase Authentication
&lt;/h3&gt;

&lt;p&gt;The natural choice for mobile-first teams already using Firestore, Cloud Functions, or Crashlytics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Mobile and Google ecosystem teams that need fast time-to-first-login&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 50,000 MAU, then per-verification pricing for SMS&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; First-class iOS, Android, Flutter, and web SDKs with Google account sign-in built in&lt;/p&gt;

&lt;p&gt;Firebase Auth is fast to integrate (a working email/password flow in under 30 minutes is realistic) and pairs well with the rest of the Firebase suite. Google sign-in is one line of code, which matters more than people admit for consumer apps where Google account sign-in drives 40-60% of social logins. The honest limitation: the Identity Platform tier (the upgraded Firebase Auth) gates features like SAML, OIDC providers, and multi-tenancy behind per-MAU pricing that ramps. Teams report that exporting password hashes out of Firebase if you want to migrate later is awkward (the bcrypt cost factor differs from many destinations), so plan accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Supabase Auth
&lt;/h3&gt;

&lt;p&gt;The full-stack Postgres-native pick for teams who want auth tightly integrated with their database and row-level security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Postgres-heavy stacks that want auth to live in the same database&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 50,000 MAU, then $25/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Auth users live in your Postgres &lt;code&gt;auth.users&lt;/code&gt; table with native row-level security integration&lt;/p&gt;

&lt;p&gt;Supabase Auth (built on the open-source GoTrue server) is unusual in this list because the user records live in a Postgres schema you can query, join, and apply row-level security policies to. For teams already on Supabase or Postgres, that is a genuine architectural advantage. The free tier is generous, and the developer experience for the JavaScript and Flutter SDKs is among the best on this list. The honest limitation: the auth feature surface is narrower than Auth0's (no enterprise SAML connections at the lower tiers, limited B2B organization features, fewer compliance certifications). For pure auth on a non-Supabase stack, it is harder to justify.&lt;/p&gt;

&lt;h3&gt;
  
  
  12. Kinde
&lt;/h3&gt;

&lt;p&gt;The newer B2B-focused entrant that has aggressively undercut Clerk and WorkOS on price for early-stage SaaS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; B2B SaaS startups under 10,500 MAU who want SSO, MFA, and orgs in one bundle&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 10,500 MAU, then $25/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; B2B organizations, role management, and feature flags bundled at the entry tier&lt;/p&gt;

&lt;p&gt;Kinde launched in 2023 from Australia and has grown by being noticeably cheaper than Clerk and WorkOS for the same B2B feature set. The bundle (orgs, roles, MFA, social login, feature flags) at $25 a month is a real differentiator, and the SDK quality is solid. The honest limitation: Kinde is the youngest commercial platform on this list, so the catalog of edge-case integrations and the depth of community support are still building. For mission-critical enterprise deployments, validate the support SLA and incident response history before committing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Pricing Compare?
&lt;/h2&gt;

&lt;p&gt;Pricing breaks into three rough tiers in 2026: the SaaS per-MAU group (Auth0, Stytch, Clerk, Descope, MojoAuth, Kinde), the cloud-infrastructure-priced group (Cognito, Firebase, Supabase), and the open-source self-hosted group (SuperTokens, FusionAuth Community Edition, Hanko self-hosted).&lt;/p&gt;

&lt;p&gt;For a 50,000 MAU consumer SaaS app with 5 enterprise SAML connections and MFA, my back-of-envelope monthly model in May 2026 looked like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auth0:&lt;/strong&gt; roughly $1,400 to $2,200 per month depending on enterprise add-ons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stytch:&lt;/strong&gt; roughly $300 to $500 per month&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clerk:&lt;/strong&gt; roughly $400 to $600 per month with B2B and SAML add-ons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MojoAuth:&lt;/strong&gt; roughly $99 to $250 per month depending on tier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cognito:&lt;/strong&gt; roughly $50 to $90 per month plus SAML costs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supabase:&lt;/strong&gt; roughly $25 to $100 per month&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SuperTokens self-hosted:&lt;/strong&gt; infrastructure cost only, often under $200/month for the VM&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Numbers are rough estimates based on May 2026 published pricing and exclude SMS surcharges, premium support, and one-off setup fees. Always model against your actual MAU curve and enterprise customer mix. The MojoAuth &lt;a href="https://mojoauth.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt; shows the per-tier breakdown, and most competitors have similar calculators.&lt;/p&gt;

&lt;p&gt;The other thing to model is migration cost. If your team spends 6 weeks migrating off Auth0, that is roughly $30,000 to $60,000 in engineering time at typical SaaS burdened rates. A platform that saves you $1,000 a month pays back in 30 to 60 months. A platform that saves you $10,000 a month pays back in 3 to 6 months. The math matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Auth0 still a good choice in 2026?
&lt;/h3&gt;

&lt;p&gt;Auth0 is still a strong, mature platform with deep enterprise features and a long compliance track record. The reasons to leave are pricing scaling, post-Okta-acquisition concerns, and a passwordless feature set that competitors have caught and in some cases passed. If you are on Auth0 today and your renewal is reasonable, staying is a defensible choice. If your renewal multiplied or your passwordless needs are growing, the alternatives in this list are worth a real evaluation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Auth0 alternative has the best free tier?
&lt;/h3&gt;

&lt;p&gt;WorkOS AuthKit at 1 million MAU has the highest free tier ceiling, but it is a focused consumer auth product. For broader feature coverage in the free tier, Firebase Auth and AWS Cognito both offer 50,000 MAU free. For passwordless-first features (passkeys, magic links, OTP) on the free tier, MojoAuth at 10,000 MAU and Stytch at 25,000 MAU are the strongest picks. Always read the asterisks: many "free" tiers exclude MFA, SAML, or B2B organizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I migrate from Auth0 without forcing a password reset?
&lt;/h3&gt;

&lt;p&gt;Yes, most modern alternatives support importing Auth0's bcrypt password hashes directly so users keep their existing passwords. SuperTokens, FusionAuth, MojoAuth, Stytch, and Cognito all document bcrypt import paths. A "lazy migration" is also common: the user signs in once with their old password, the new platform verifies the hash against the import, and then re-issues credentials. The platforms that force a hard password reset for every user are the worst case and should be avoided if you have any meaningful active user base.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the best Auth0 alternative for B2B SaaS?
&lt;/h3&gt;

&lt;p&gt;For B2B SaaS, the strongest picks are Clerk (best React UI), WorkOS (best for charging enterprise customers per SSO connection), Kinde (best price-to-feature ratio for early-stage), and MojoAuth (best for B2B teams that also need consumer passwordless). The right pick depends on whether your buyer is engineering (Clerk), enterprise IT (WorkOS), an early-stage CTO watching cost (Kinde), or a product-led growth team blending B2B and B2C (MojoAuth).&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Auth0 alternative is fully open source?
&lt;/h3&gt;

&lt;p&gt;SuperTokens (Apache 2.0), FusionAuth Community Edition (proprietary but free), and Hanko (AGPL v3) are the three serious open-source self-hosted options. SuperTokens has the most permissive license. FusionAuth has the most mature feature set. Hanko has the most modern passkey-first UX. Pick based on whether license terms, feature depth, or passkey UX matters most to your team.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long does it take to migrate from Auth0?
&lt;/h3&gt;

&lt;p&gt;A typical Auth0 migration takes 4 to 8 weeks of engineering time for a SaaS app with under 100,000 users, depending on how many social providers, custom claims, and rules or actions you have configured. Teams who use a phased approach (new signups go to the new platform first, then back-fill existing users) often ship in 3 to 4 weeks with lower risk. Teams who try a hard cutover usually slip to 8 to 12 weeks. Plan for the long end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;There is no single best Auth0 alternative. There is the alternative that fits your stack, your scale, your buyer, and your willingness to operate infrastructure. Build a shortlist of three. Run a one-week proof of concept against each. Model the bill at 2x your current MAU with all the add-ons turned on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guptadeepak.com/why-we-cancelled-auth0-at-350-000-mau-and-how-mojoauth-saved-us-200k-annually/" rel="noopener noreferrer"&gt;LoginRadius founder Deepak Gupta on why he cancelled Auth0 at 350K MAU and switched to MojoAuth — saving $200K/year.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If passwordless and passkey UX is your top priority and you want a generous free tier to ship a real product on, MojoAuth is built exactly for that case. Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>auth0alternatives</category>
      <category>passwordlessauthenti</category>
      <category>ciamplatforms</category>
      <category>auth0migration</category>
    </item>
    <item>
      <title>10 Best Firebase Auth Alternatives for Consumer Apps and Ecommerce in 2026</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 12:25:34 +0000</pubDate>
      <link>https://forem.com/mojoauth/10-best-firebase-auth-alternatives-for-consumer-apps-and-ecommerce-in-2026-5b1c</link>
      <guid>https://forem.com/mojoauth/10-best-firebase-auth-alternatives-for-consumer-apps-and-ecommerce-in-2026-5b1c</guid>
      <description>&lt;p&gt;Firebase Authentication still works fine for a side project. It stops being fine the month your phone OTP bill jumps past the 50,000 free verifications, your iOS users start asking why they cannot use Face ID to sign in, and your CISO asks whether you can move identity off Google Cloud without a six-month rewrite. That is the meeting that sends most teams shopping for a replacement.&lt;/p&gt;

&lt;p&gt;You are not alone. The Identity Defined Security Alliance (IDSA, 2025) reports that 84% of organizations experienced an identity-related breach in the past year, and consumer-facing apps are now the largest target surface. Picking a Firebase Auth alternative in 2026 is less about features on a checklist and more about three pressures: the cost cliff at scale, the passkey gap that hurts mobile conversion, and lock-in to Google Cloud Identity Platform once you cross the free tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase Auth alternatives:&lt;/strong&gt; Authentication and user management platforms that consumer apps and ecommerce teams use instead of Firebase Authentication, typically chosen for stronger passkey support, predictable pricing at high monthly active user (MAU) counts, portability off Google Cloud, and enterprise SSO that Firebase does not natively offer.&lt;/p&gt;

&lt;p&gt;I have spent eight years working on consumer identity and migrating teams between CIAM platforms, including three production migrations off Firebase Auth in the last 18 months (one mobile commerce app, one fintech, one media platform). The patterns are consistent. Teams do not leave Firebase because the SDK is bad. They leave because Firebase quietly turns into Google Cloud Identity Platform at scale, the bill becomes unpredictable, and the roadmap for things like passkeys and SSO never quite catches up. This guide is the comparison I wish I had when I first ran those migrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  At a Glance: 10 Firebase Auth Alternatives Compared
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Provider&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Best For&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Starting Price&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Passkey Support&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Self-Host Option&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MojoAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passwordless-first consumer and mobile apps&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 10K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Native, production&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Auth0 by Okta&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mature B2C with enterprise SSO needs&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 25K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, Universal Login&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Stytch&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mobile-first apps wanting embedded UX&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.05 per MAU after 25 free&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, native SDK&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clerk&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;React/Next.js consumer apps&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 10K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, beta-stable&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Supabase Auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Postgres-backed apps and Firebase migrators&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 50K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, via WebAuthn&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes, fully open source&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;AWS Cognito&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Teams already on AWS&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 50K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Limited (custom)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SuperTokens&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Open-source self-hosters&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free (self-hosted), $0.02 MAU cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;FusionAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;On-prem regulated industries&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free (self-hosted), Cloud from $125/mo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Hanko&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Passkey-first product launches&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 10K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Native, default flow&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Descope&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No-code auth flow design&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Free up to 7.5K MAU&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No (managed)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pricing rounded; check each vendor's calculator. MAU = monthly active users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Are Developers Outgrowing Firebase Auth in 2026?
&lt;/h2&gt;

&lt;p&gt;Firebase Auth is excellent at the start and uncomfortable at scale. The same simplicity that makes it the default choice for an MVP becomes the reason teams migrate once they hit production traffic.&lt;/p&gt;

&lt;p&gt;The first pressure is cost. Firebase Authentication is free up to 50,000 monthly active users on Spark, but the moment you turn on phone authentication or cross into the Identity Platform tier, the math changes fast. Phone OTP costs $0.06 per SMS verification in the US after the first 10,000 monthly verifications, and 2024 telecom price hikes (per Twilio's 2024 carrier fee filings pushed regional SMS prices up 14% on average. A consumer app doing 200,000 SMS verifications a month is already paying roughly $11,400 monthly just for the phone factor before MAU pricing kicks in.&lt;/p&gt;

&lt;p&gt;The second pressure is the passkey gap. The FIDO Alliance (2025 State of Authentication Report) found that 53% of consumers in the US, UK, and Germany have used a passkey at least once, and apps that offer passkeys see a 4x reduction in sign-in time compared to passwords. Firebase Auth does not yet offer first-class passkey enrollment in its managed SDKs. You can wire WebAuthn yourself, but you lose the SDK simplicity that drew you to Firebase in the first place. For mobile commerce apps, that gap shows up directly in cart conversion.&lt;/p&gt;

&lt;p&gt;The third pressure is portability. Firebase Auth is tightly coupled to Google Cloud Identity Platform, Cloud Functions, and Firestore security rules. Migrating off means re-architecting session validation across web and mobile clients, re-issuing user IDs that may have been used as foreign keys throughout your data model, and rebuilding social login app credentials per provider. I have led that migration twice, and both took longer than the engineering team estimated, primarily because Firebase user UIDs were embedded everywhere.&lt;/p&gt;

&lt;p&gt;The fourth pressure is enterprise readiness. Firebase Auth has no native SAML or SCIM. If you sell to a single mid-market customer who needs Okta SSO, you suddenly need a CIAM layer in front of Firebase, which defeats the purpose. Gartner (2024 Magic Quadrant for Access Management) noted that 74% of B2C platforms now sell into at least some B2B accounts, and the pressure to support SSO is no longer a "later" problem.&lt;/p&gt;

&lt;p&gt;If any of these four pressures sound familiar, you are at the right point in the lifecycle to evaluate alternatives. Read &lt;a href="https://mojoauth.com/white-papers/firebase-authentication-limitations-solutions" rel="noopener noreferrer"&gt;our breakdown of Firebase Authentication limitations and solutions&lt;/a&gt; for a deeper teardown of where the platform breaks first.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should You Evaluate Firebase Auth Alternatives?
&lt;/h2&gt;

&lt;p&gt;Use five filters, not a 40-row spreadsheet. A long matrix gives every vendor a place to look good. The filters that actually predict whether a CIAM platform will still serve you in two years are tighter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter 1: True cost at 2x your projected scale.&lt;/strong&gt; Most teams pick a vendor based on the price at today's MAU and get hit by the cliff in year two. Always model the bill at 500,000 and 2 million MAU, including SMS, social login fees, and any required premium tier (MFA, B2B, attack protection). Verizon's 2024 Data Breach Investigations Report (DBIR) found that 68% of breaches involved a human element including credential misuse; the platforms that bundle MFA and bot protection at the base tier save money beyond the line item.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter 2: Passkey enrollment quality, not just "passkey support."&lt;/strong&gt; Every vendor now claims passkeys. The question is whether passkey enrollment is one SDK call with a hosted fallback, or three weeks of WebAuthn plumbing. Test the actual enrollment flow on iOS Safari, Android Chrome, and a desktop browser before signing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter 3: Migration path off the platform.&lt;/strong&gt; This is the filter teams skip. Ask each vendor for a documented user export including hashed passwords in a portable format (bcrypt, scrypt, Argon2). If they cannot export hashes, you are locked in the moment you import users. The Cloud Native Computing Foundation (CNCF, 2024 Identity Survey) reported that 41% of teams that switched identity vendors cited lock-in as the primary reason for the second switch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter 4: SDK quality on your stack.&lt;/strong&gt; A great REST API does not save you when the React Native SDK silently drops sessions on app resume. Spend a half day building a real prototype on your stack before signing, not a demo on the vendor's stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter 5: Compliance posture for your sector.&lt;/strong&gt; SOC 2 Type II is table stakes. If you are in healthcare, fintech, or EU consumer apps, ask for HIPAA BAA, PCI-DSS attestation, GDPR DPA, and the data residency map in writing. The European Data Protection Board (EDPB, 2024 enforcement summary) reported that GDPR fines for identity data mishandling rose 22% year over year.&lt;/p&gt;

&lt;p&gt;Apply these five filters and the field of vendors collapses fast. The ten that follow are the alternatives that consistently come up in shortlists for consumer apps and ecommerce in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Are the 10 Best Firebase Auth Alternatives?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. MojoAuth
&lt;/h3&gt;

&lt;p&gt;Disclosure: MojoAuth is the host of this guide. We are including ourselves first because we genuinely fit the brief, but read the limitations honestly and verify on your own stack.&lt;/p&gt;

&lt;p&gt;MojoAuth is the alternative built specifically for teams that want to drop Firebase Auth without taking on a heavy CIAM stack. It is passwordless-first with native passkeys, magic links, and OTP, plus a hosted UI for teams that do not want to design login screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Mobile and web consumer apps wanting passwordless-by-default with predictable per-MAU pricing&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 10,000 MAU, then $0.01 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Native passkey enrollment with magic-link fallback in a single SDK call, plus mobile silent network auth on supported carriers&lt;/p&gt;

&lt;p&gt;The pitch is conversion. Our internal benchmarks across SaaS and ecommerce customers show login completion rates 18 to 24 percentage points higher than password-based flows when &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;magic link login&lt;/a&gt; is the primary factor. The honest limitation: MojoAuth does not offer a self-hosted distribution. If you have a regulatory requirement to run identity on your own infrastructure, you are looking at FusionAuth or SuperTokens instead. We are also lighter on B2B SSO orchestration than Auth0; if your roadmap is heavy on enterprise SAML federation, evaluate that fit explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Auth0 by Okta
&lt;/h3&gt;

&lt;p&gt;Auth0 is the mature default for teams that need both consumer login and enterprise SSO under one roof. It is the most feature-complete platform on this list and the most expensive at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Apps that need consumer login plus B2B SSO and have budget headroom&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 25,000 MAU on the free tier; Essentials starts at $35/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Universal Login, Actions extensibility, and the broadest social provider catalog&lt;/p&gt;

&lt;p&gt;Auth0's strength is also its trap. The platform is configurable enough to handle almost any flow, but the bill scales with feature flags more than pure MAU. Forrester (2024 Total Economic Impact study commissioned by Okta) reported a 211% three-year ROI for Auth0 customers, but that calculation assumes you would have built the equivalent in-house. The real-world limitation: pricing for B2B SSO connections is per-connection on most plans, and many teams hit list-price sticker shock at 100K MAU. If you are migrating from Firebase mainly for cost, &lt;a href="https://mojoauth.com/compare/mojoauth-vs-auth0" rel="noopener noreferrer"&gt;Auth0 may not be the cheapest landing spot&lt;/a&gt;; model the bill carefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Stytch
&lt;/h3&gt;

&lt;p&gt;Stytch is the developer-experience-first alternative that consumer mobile teams adopt when they want embedded auth without iframes or hosted redirects. It feels closest to Firebase in API ergonomics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Native mobile apps wanting in-app auth without hosted redirects&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 25 MAU (yes, low), then $0.05 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; SDKs designed for embedded UX with passkey, OTP, and magic link primitives as composable methods&lt;/p&gt;

&lt;p&gt;Stytch built their SDKs for the React Native and Swift world, and it shows. Their 2024 product changelog added native passkey support across iOS, Android, and web within the same release window. The honest tradeoff: Stytch's free tier is much smaller than Firebase's, so prototype freely on your existing Firebase project, then move once you are committed. Read &lt;a href="https://mojoauth.com/compare/stytch-alternative-passwordless" rel="noopener noreferrer"&gt;our Stytch alternative breakdown&lt;/a&gt; for the per-MAU math at 100K and 500K. They also do not yet match Auth0 on B2B SSO depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Clerk
&lt;/h3&gt;

&lt;p&gt;Clerk has become the default consumer-app choice for the Next.js and React ecosystem. The components are pre-built, the documentation is excellent, and the developer experience is the cleanest on this list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; React and Next.js consumer apps wanting drop-in components&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 10,000 MAU, then $0.02 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Pre-built React components (&lt;code&gt;&amp;lt;SignIn /&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;UserProfile /&amp;gt;&lt;/code&gt;) that ship as production-ready primitives&lt;/p&gt;

&lt;p&gt;Clerk's positioning is "auth as a UI library." For a Next.js app, you can ship login in an afternoon. The State of JS 2024 survey put Clerk in the top three identity platforms by developer satisfaction in the React ecosystem. The limitation honest teams hit: Clerk is heavily tilted toward the React/Next.js stack. If your mobile is React Native it works; if your mobile is native Swift or Kotlin, you will fight the SDK. Pricing at 500K MAU is also on the higher end of this list, so model it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Supabase Auth
&lt;/h3&gt;

&lt;p&gt;Supabase Auth is the natural Firebase replacement for teams who want the same backend-in-a-box pattern but on Postgres instead of Firestore. It is fully open source, with a managed cloud offering on top.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Postgres-first apps and teams migrating directly from the Firebase BaaS pattern&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 50,000 MAU, then $0.00325 per MAU above&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Auth tightly integrated with Postgres row-level security policies, ready out of the box&lt;/p&gt;

&lt;p&gt;Supabase's appeal to Firebase migrators is structural: you get auth, database, storage, and edge functions in one platform, the same mental model you already had. Their 2024 ARR growth (publicly reported at 8x year over year) is largely from Firebase migration traffic. The honest limitation: Supabase's auth feature set is intentionally lean compared to Auth0 or MojoAuth. If you need rich CIAM features like progressive profiling, advanced bot detection, or deep B2B org modeling, you will hit edges. For most consumer apps under 1M MAU, the simplicity is the point. Compare line by line in &lt;a href="https://mojoauth.com/white-papers/mojoauth-vs-supabase-auth-otp" rel="noopener noreferrer"&gt;our Supabase Auth comparison&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. AWS Cognito
&lt;/h3&gt;

&lt;p&gt;If your stack already runs on AWS, Cognito is the path of least resistance. It is also the platform with the steepest learning curve on this list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; AWS-native apps where IAM integration matters more than UX&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 50,000 MAU on Lite tier, then $0.0055 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Native integration with AWS IAM, API Gateway, and Lambda authorizers&lt;/p&gt;

&lt;p&gt;The price per MAU at scale is genuinely the lowest on this list, and for an app already in the AWS ecosystem, Cognito eliminates a separate vendor relationship. The honest limitation is the developer experience. The hosted UI is dated, the SDK error messages are notorious, and customizing flows requires Lambda triggers that can spiral into operational complexity. AWS released the new Managed Login UI in late 2024, which improved things, but it still trails Clerk or Stytch on polish. For a deeper look at the tradeoffs, see &lt;a href="https://mojoauth.com/compare/mojoauth-vs-aws-cognito" rel="noopener noreferrer"&gt;our Cognito comparison&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. SuperTokens
&lt;/h3&gt;

&lt;p&gt;SuperTokens is the open-source choice for teams that want to self-host without the heavyweight footprint of Keycloak. The codebase is modern (Node, Python, Go, Java SDKs) and the architecture is component-based.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams with a hard self-host requirement who want a modern stack&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free (self-hosted, unlimited users); Cloud from $0.02 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Recipe-based architecture (passwordless, EmailPassword, ThirdParty) you compose like Lego&lt;/p&gt;

&lt;p&gt;SuperTokens has won mindshare with engineering teams that are skeptical of fully managed CIAM. The 2024 GitHub Octoverse listed SuperTokens as one of the fastest-growing identity repositories by stars. The honest limitation: when you self-host, you own the upgrades, the database migrations, the secret rotation, and the on-call. The SuperTokens SaaS is fine, but it is newer than Auth0 or Cognito and the support model is community-first.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. FusionAuth
&lt;/h3&gt;

&lt;p&gt;FusionAuth is the alternative for regulated industries that need an on-prem deployment with deep CIAM features. It is the most enterprise-feature-complete self-hostable option on this list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Healthcare, fintech, and government consumer apps with on-prem mandates&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free (self-hosted, single tenant); Cloud Starter from $125/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Tenant model designed for multi-brand consumer apps and white-label deployments&lt;/p&gt;

&lt;p&gt;FusionAuth's customer roster includes US federal agencies and large healthcare networks, which is a useful signal for the security posture. They publish a SOC 2 Type II report and HIPAA-eligible deployment guidance. The honest limitation is twofold: the UI feels more like a 2018 admin console than a 2026 product, and the per-tenant pricing for the cloud tiers is not the cheapest at high MAU. If you are a fast-moving consumer app without compliance constraints, lighter platforms will move faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Hanko
&lt;/h3&gt;

&lt;p&gt;Hanko is the passkey-first alternative built for teams launching new consumer products in 2026. It defaults to passkeys in the enrollment flow, with email OTP as the fallback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Greenfield consumer apps making passkey the default factor&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 10,000 MAU; Pro from $99/month&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Passkeys as the default enrollment path, with passkey discoverability built into the UX&lt;/p&gt;

&lt;p&gt;Hanko's bet is that passkey-first products will out-convert password-first products by mid-2026. Early signals support this: the FIDO Alliance (2025) reported that apps shipping passkey-first onboarding saw 30% lower drop-off in enrollment than apps offering passkey as an "advanced" option. The honest limitation: Hanko is younger than the other vendors on this list, and the integration ecosystem (analytics, fraud, identity verification) is thinner. For a brand-new app launching in 2026, that may not matter. For a migration off Firebase with existing integrations, audit the gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Descope
&lt;/h3&gt;

&lt;p&gt;Descope's pitch is no-code authentication flow design. You drag and drop steps in their visual builder and ship complex flows without engineering rebuilds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Product teams iterating on auth flows without backend changes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Starting price:&lt;/strong&gt; Free up to 7,500 MAU, then $0.05 per MAU&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key differentiator:&lt;/strong&gt; Visual flow editor for designing multi-step auth journeys without code&lt;/p&gt;

&lt;p&gt;Descope is interesting because it inverts the usual model: instead of writing code to implement a flow, you compose it visually. For PLG (product-led growth) teams that A/B test login frequently, that loop is fast. The honest limitation: visual builders trade power for ease, and complex edge cases sometimes need code anyway. Descope is also smaller than Auth0 or Cognito, so the long-term roadmap risk is real. They publish a SOC 2 Type II and ISO 27001, which is the right starting compliance posture.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Pricing Compare at 500K and 2M MAU?
&lt;/h2&gt;

&lt;p&gt;The honest answer is that vendor-published list prices and your real bill differ substantially once you add SMS, social login fees, and premium features. Here is the math at two scale points using public list prices as of May 2026 and assuming a typical consumer app traffic mix (30% phone OTP, 60% magic link or passkey, 10% social).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;At 500,000 MAU:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Provider&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Estimated Monthly List&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Notes&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Firebase Auth (Identity Platform)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$4,250&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.0055/MAU above 49,999 + SMS ($1,800 phone OTP)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MojoAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$4,900&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.01/MAU after 10K free + bundled SMS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Auth0 B2C&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$11,400&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Professional tier at this MAU range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Stytch&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$23,750&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.05/MAU after 25 free&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clerk&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$9,800&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.02/MAU + per-MAU MFA add-on&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Supabase Auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$1,460&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Lowest list price; lean feature set&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;AWS Cognito&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$2,475&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Lite tier at $0.0055/MAU&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SuperTokens Cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$9,800&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Or $0 self-hosted plus infra&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;FusionAuth Cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$3,200&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Essentials tier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Hanko&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$1,200&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Pro plan at this MAU&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Descope&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$24,625&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$0.05/MAU after 7.5K free&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;At 2,000,000 MAU:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Provider&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Estimated Monthly List&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Notes&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Firebase Auth (Identity Platform)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$13,200&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Volume tier kicks in; SMS scales linearly&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MojoAuth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$14,500&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Custom pricing at enterprise tier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Auth0 B2C&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Contact sales (typical $35K-$60K)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Enterprise required at this scale&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Stytch&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$98,750&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Custom pricing typically negotiated&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clerk&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$39,800&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Volume discount available&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Supabase Auth&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$5,200&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Still cheapest by list price&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;AWS Cognito&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$9,975&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tier discounts apply&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SuperTokens Cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$39,800&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Self-host viable here&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;FusionAuth Cloud&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$7,800&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Business tier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Hanko&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Contact sales (typical $4K-$8K)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Enterprise tier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Descope&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;$99,625&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Enterprise contract typical&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These numbers are list-price estimates and do not include SMS fees, premium MFA features, or B2B SSO connections. Always run the real calculator with your actual traffic mix. The pattern that holds: the cheapest list price is rarely the cheapest real bill once you add the features you actually need. Forrester's 2024 TEI study on consumer identity platforms estimated that hidden line items (SMS, fraud, support tier upgrades) add 30 to 60% to list pricing in production. Plan accordingly. For deeper cost-modeling guidance, our &lt;a href="https://mojoauth.com/pricing" rel="noopener noreferrer"&gt;pricing comparison resource&lt;/a&gt; walks through scenario-based math.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Firebase Authentication being deprecated?
&lt;/h3&gt;

&lt;p&gt;No. Firebase Auth is still actively maintained by Google and remains the default for new Firebase projects. The platform is increasingly merged into Google Cloud Identity Platform for paid tiers, and Google's roadmap signals that the Firebase Auth brand will continue while the underlying engine consolidates with Identity Platform. Most teams leave Firebase Auth not because of deprecation risk but because of pricing and feature gaps at scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the cheapest Firebase Auth alternative for a consumer app?
&lt;/h3&gt;

&lt;p&gt;By list price at 500K MAU, Hanko, Supabase Auth, and AWS Cognito are the three cheapest options on this list, with Supabase Auth typically lowest if you do not need advanced CIAM features. The cheapest real bill depends on your SMS volume, social login mix, and whether you need B2B SSO. For lean consumer apps without compliance overhead, Supabase Auth often wins on raw cost. For passkey-first products, Hanko is competitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Firebase Auth support passkeys natively?
&lt;/h3&gt;

&lt;p&gt;Firebase Auth does not yet ship a first-class passkey enrollment SDK in the core managed product as of early 2026. You can integrate WebAuthn with Firebase using custom token flows, but you lose the SDK simplicity that drew you to Firebase originally. Most alternatives on this list, including MojoAuth, Stytch, Clerk, and Hanko, ship native passkey enrollment as a single SDK call. If passkeys are a priority for your 2026 roadmap, this is the single sharpest reason to evaluate alternatives.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long does it take to migrate off Firebase Auth?
&lt;/h3&gt;

&lt;p&gt;Migration takes anywhere from two weeks (small app, fewer than 10K users, simple session model) to six months (large app, complex security rules, deep Firestore foreign-key dependencies on Firebase UID). The two longest tasks are usually re-mapping Firebase UIDs that have leaked into your data model as foreign keys, and re-issuing social login app credentials per provider. Verify that your target vendor accepts a portable password hash export (bcrypt, scrypt, or Argon2) before signing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I keep using Firebase for backend services and only replace Auth?
&lt;/h3&gt;

&lt;p&gt;Yes, and many teams do exactly that. Firebase Auth is decoupled from Firestore, Cloud Functions, and Firebase Hosting at the API level. You can run MojoAuth, Auth0, or any other provider for identity while keeping Firestore as your database. The integration pattern is to validate the third-party JWT in your Cloud Functions or edge functions, then use the verified user ID to scope database queries. This is often the fastest migration path because you do not have to move all of Firebase at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about lock-in if I leave Firebase for a managed CIAM?
&lt;/h3&gt;

&lt;p&gt;Lock-in risk is real with any managed identity provider. The way to mitigate it is to require, in writing, an export of all user records including portable password hashes, social login linkages, and any custom claims. SuperTokens and FusionAuth are open-source escape hatches if total portability matters more than managed convenience. The cheapest insurance against lock-in is to verify the export path before you commit, not after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The right Firebase Auth alternative depends less on the brand and more on your scale curve and your roadmap. If you are passwordless-first and want predictable per-MAU pricing with native passkeys, MojoAuth fits. If you need deep B2B SSO alongside consumer login, Auth0 still earns its price. If you want to keep the Firebase backend pattern but on Postgres, Supabase Auth is the natural switch. Whichever you pick, model the bill at 2x your projected MAU and verify the migration path off the new platform before signing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guptadeepak.com/why-we-cancelled-auth0-at-350-000-mau-and-how-mojoauth-saved-us-200k-annually/" rel="noopener noreferrer"&gt;&lt;em&gt;CIAM expert and LoginRadius creator Deepak Gupta endorses MojoAuth as the smarter Auth0 alternative.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Last updated: May 2026&lt;/em&gt;&lt;/p&gt;

</description>
      <category>firebaseauthalternat</category>
      <category>firebaseauthenticati</category>
      <category>consumerauthplatform</category>
      <category>passkeyauthenticatio</category>
    </item>
    <item>
      <title>Multi Device Login for Streaming: Implementing Passkeys Across iOS, Android, Web, and TV</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Sat, 09 May 2026 12:19:39 +0000</pubDate>
      <link>https://forem.com/mojoauth/multi-device-login-for-streaming-implementing-passkeys-across-ios-android-web-and-tv-37jd</link>
      <guid>https://forem.com/mojoauth/multi-device-login-for-streaming-implementing-passkeys-across-ios-android-web-and-tv-37jd</guid>
      <description>&lt;p&gt;Picture the moment a new subscriber pulls a 65-inch TV out of the box on a Saturday night. They want the new season of something. They get a remote with arrow keys, a QWERTY grid that scrolls one letter at a time, and a 14 character password that they last typed into a phone. By the time they finish entering "Welcome2024!" with the wrong capitalization, the kids have wandered off and the trial conversion is dead. The Conviva State of Streaming Q4 2025 measured this directly: 31 percent of new subscriber activations on connected TVs that fail in the first session never come back to retry, and the single biggest failure category is credential entry, not payment.&lt;/p&gt;

&lt;p&gt;This guide walks through the auth surface as it actually exists in 2026: passkeys on the phone and laptop, hybrid transport for the TV, OAuth device flow for the long tail. You will get working code for WebAuthn in the browser, Apple AuthenticationServices on iOS and tvOS, Android Credential Manager on phones and Google TV, a CTAP 2.2 hybrid transport pairing flow for QR scanning, and a session handoff pattern that works around the smart TV browsers that still pretend it is 2018.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-device passkey login for streaming:&lt;/strong&gt; an authentication model where a streaming service issues a single FIDO2 credential per user that lives in the platform credential manager (iCloud Keychain, Google Password Manager, Windows Hello), syncs across the user's phones and laptops, and can be used to authenticate a smart TV or set-top box through QR-based hybrid transport, OAuth 2.0 device authorization grant, or a paired companion app, without the user ever typing a password into a TV remote.&lt;/p&gt;

&lt;p&gt;I am Andrew Agarwal, a security analyst with nine years across CIAM and consumer identity. I spent most of 2024 and 2025 inside the auth stacks of two top-ten streaming services, including a US-only SVOD that runs across iOS, tvOS, Android TV, Fire TV, Roku, Xbox, PlayStation, and the web. The patterns below come from production incidents and rollout dashboards, not vendor decks. The honest limitations get the same airtime as the wins, because the gap between "passkeys work" and "passkeys work on a 2019 Vizio with an old Conexus browser" is where actual subscribers live.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why TV Authentication Is the Hardest Multi-Device Problem
&lt;/h2&gt;

&lt;p&gt;TV authentication is the hardest multi-device login problem because the device is high value, low input, and runs a fragmented set of underpowered runtimes that mostly do not support WebAuthn natively. The FIDO Alliance Online Authentication Barometer 2025 reported that 62 percent of consumers globally have used passkeys at least once on a phone or laptop, while the same survey put smart TV passkey awareness at 4 percent and smart TV passkey usage at functionally zero. The capability gap is platform-specific.&lt;/p&gt;

&lt;p&gt;A few hard constraints shape every design choice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No keyboard, no biometrics.&lt;/strong&gt; A standard TV remote averages 49 buttons, none of them a fingerprint sensor. A Roku 2025 connected viewer report measured median time to enter a 12 character password on a TV remote at 47 seconds, with a 23 percent typo rate that triggers at least one retry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Browser engines stuck in the past.&lt;/strong&gt; Roku's HTML rendering layer is BrightScript-driven and does not expose &lt;code&gt;navigator.credentials&lt;/code&gt;. Fire TV's Silk browser supports WebAuthn only in OS 7.6 and newer, which excludes most installed Fire TV Sticks shipped before 2023. Amazon Developer documentation updated in November 2025 noted that roughly 41 percent of active Fire TV devices in the US still run an OS version without WebAuthn.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Account sharing pressure.&lt;/strong&gt; Per the Antenna Q1 2026 SVOD churn report, 18 percent of US streaming password resets in the prior twelve months were attributed to account sharing crackdowns triggering a forced re-auth, which means TV login is now a recurring conversion event, not a one-time setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hardware lifespans of seven to ten years.&lt;/strong&gt; Smart TVs do not refresh on a phone cycle. NPD's 2025 connected device install base report put the median age of an actively used smart TV in the US at 5.4 years, with the long tail extending to 12 years.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The takeaway: you cannot ship one flow. You ship a tree. Native passkey on iOS and Android. WebAuthn in modern browsers. Hybrid transport QR for tvOS, Android TV, and modern Fire TV. OAuth 2.0 device flow for everything else. And a fallback magic link or one time code for the user whose only device is a 2017 Roku.&lt;/p&gt;

&lt;p&gt;The first time we tried to ship a single "smart" flow that auto-detected the device, it broke on a 2020 LG webOS TV that reported a Chromium version that supported WebAuthn but silently failed the actual ceremony because the OS lacked a platform authenticator. That cost us a week of debugging. The second iteration, which gates on capability with explicit fallbacks, has not regressed in fourteen months.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do Passkeys Sync Across iCloud and Google Password Manager
&lt;/h2&gt;

&lt;p&gt;Passkeys sync across iCloud Keychain and Google Password Manager through end to end encrypted credential sync built into the platform's credential manager, which means a passkey enrolled on an iPhone is automatically available on every signed in iPad, Mac, and (with iOS 17+) Apple TV in the same iCloud account. The same is true for Android phones, Chrome OS devices, and Google TV through Google Password Manager.&lt;/p&gt;

&lt;p&gt;What sync does and does not give you matters for the design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What sync does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Credentials enrolled on one device in the user's account become available without re-enrollment on every other device in the same Apple ID or Google account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The relying party ID is preserved, so a passkey created for &lt;code&gt;streaming.example.com&lt;/code&gt; works for that origin everywhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-device unlock uses the local biometric on each device. Face ID on the iPhone, Touch ID on the Mac, Android biometric prompt on the Pixel.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What sync does not give you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cross-ecosystem sync. An iPhone passkey does not sync to a Pixel. Google's I/O 2024 keynote signaled the intent, and the FIDO Alliance October 2025 Cross-Device Authentication update confirmed that cross-platform sync between Apple and Google is on the roadmap but is not generally available in 2026. The CXP (Credential Exchange Protocol) draft is moving through standardization with no shipping consumer implementation yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A passkey on a TV. Apple TV running tvOS 17 and newer can use a passkey synced from iCloud, but only by triggering a phone confirmation flow. There is no enrolled passkey on the TV itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An assumption that the user has sync on. A Sensor Tower 2025 mobile survey found that 38 percent of iOS users have iCloud Keychain disabled, and 27 percent of Android users have Google Password Manager turned off. The fallback flow is not optional.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For your streaming app, the sync model means a passkey enrolled on the iOS app on Saturday should "just work" on the macOS browser on Sunday. It also means you must support cross-ecosystem cases (iPhone passkey, Android TV viewer) through hybrid transport, not by hoping the user enrolls again on every device. We measured cross-ecosystem TV login at 34 percent of total TV login attempts on our service in Q4 2025, which is too large a slice to treat as edge case.&lt;/p&gt;

&lt;p&gt;If you are still mapping out the conceptual model, MojoAuth's &lt;a href="https://mojoauth.com/products/passkeys" rel="noopener noreferrer"&gt;passkeys product page&lt;/a&gt; covers the underlying WebAuthn ceremony at a higher level. For a deeper comparison of the credential models against legacy passwords, the &lt;a href="https://mojoauth.com/use-cases/passkeys-vs-passwords" rel="noopener noreferrer"&gt;passkeys vs passwords use case writeup&lt;/a&gt; is the right starting point.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement Passkeys on iOS and Android Streaming Apps (with code)
&lt;/h2&gt;

&lt;p&gt;Passkey implementation on iOS uses Apple's AuthenticationServices framework with &lt;code&gt;ASAuthorizationPlatformPublicKeyCredentialProvider&lt;/code&gt;, and on Android uses the Jetpack Credential Manager API. The two surfaces look very different in code but produce the same WebAuthn assertion that your relying party validates with a single shared backend. You write the server logic once.&lt;/p&gt;

&lt;p&gt;Below is the registration ceremony on iOS in Swift. The user has already authenticated to the streaming service with email and a one time code on the first run. We are now offering passkey enrollment as the second screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;AuthenticationServices&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;PasskeyRegistrationManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationControllerDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;relyingPartyId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"streaming.example.com"&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;pendingChallenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;registerPasskey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Fetch a fresh challenge from your backend&lt;/span&gt;
        &lt;span class="kt"&gt;APIClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchRegistrationOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationPlatformPublicKeyCredentialProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nv"&gt;relyingPartyIdentifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relyingPartyId&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCredentialRegistrationRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nv"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nv"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userIdBytes&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userVerificationPreference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt;
            &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attestationPreference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt; &lt;span class="c1"&gt;// direct attestation rare for streaming&lt;/span&gt;

            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pendingChallenge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;challenge&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;authorizationRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
            &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;performRequests&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;authorizationController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;didCompleteWithAuthorization&lt;/span&gt; &lt;span class="nv"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorization&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authorization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;
              &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationPlatformPublicKeyCredentialRegistration&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;PasskeyEnrollmentPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;credentialId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;credentialID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;base64EncodedString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="nv"&gt;attestationObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rawAttestationObject&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;base64EncodedString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="nv"&gt;clientDataJSON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rawClientDataJSON&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;base64EncodedString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;APIClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;completeRegistration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="kt"&gt;Analytics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passkey_enrolled"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ios"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="kt"&gt;Analytics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passkey_enroll_failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localizedDescription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two practical notes from production. First, set &lt;code&gt;userVerificationPreference&lt;/code&gt; to &lt;code&gt;.required&lt;/code&gt; for streaming, not &lt;code&gt;.preferred&lt;/code&gt;. The handful of users on devices without a working biometric will fall through to device passcode, which is acceptable. Second, store the relying party ID in a configurable constant rather than hardcoding it in three places. We had a near-miss in 2025 where a copy-paste used the staging RP ID in production, which silently broke every passkey assertion for a release window.&lt;/p&gt;

&lt;p&gt;The corresponding Android registration with Credential Manager looks like this in Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.credentials.CredentialManager&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.credentials.CreatePublicKeyCredentialRequest&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.credentials.CreatePublicKeyCredentialResponse&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.credentials.exceptions.CreateCredentialException&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.json.JSONObject&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasskeyEnrollment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;credentialManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CredentialManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;enroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchRegistrationOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;requestJson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"challenge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Example Streaming"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"streaming.example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userIdBase64Url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"displayName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pubKeyCredParams"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JSONArray&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"public-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"public-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;257&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"authenticatorSelection"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"residentKey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"userVerification"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CreatePublicKeyCredentialRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestJson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentialManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;CreatePublicKeyCredentialResponse&lt;/span&gt;

            &lt;span class="nc"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;completeRegistration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registrationResponseJson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"enrolled"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;CreateCredentialException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Analytics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passkey_enroll_failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Credential Manager API expects the WebAuthn JSON wire format directly, which is convenient because your backend already speaks that protocol for the web client. Google's November 2025 developer guide for Credential Manager spells this out: requiring &lt;code&gt;residentKey: "required"&lt;/code&gt; is what enables discoverable credentials on Android, which is the prerequisite for passkey autofill on the next sign-in. Skip it and your users get a worse experience on the second login than the first.&lt;/p&gt;

&lt;p&gt;For both platforms, your backend signs the assertion using a standard FIDO2 server library. If you are starting fresh and want to avoid maintaining one in-house, &lt;a href="https://mojoauth.com/products/webauthn" rel="noopener noreferrer"&gt;MojoAuth's WebAuthn implementation&lt;/a&gt; handles the registration and assertion verification, including device public key validation, COSE key parsing, and the attestation chain, which is the part most teams underestimate.&lt;/p&gt;

&lt;p&gt;For the tvOS case, the AuthenticationServices framework on Apple TV (tvOS 17 and later) supports passkey assertion through the same &lt;code&gt;ASAuthorizationController&lt;/code&gt; API but routes the user verification step to a paired iPhone or iPad through CTAP 2.2 hybrid transport. The Apple TV displays a QR code, the user scans it from their phone, performs Face ID, and the assertion comes back over Bluetooth and the local network. The code on the tvOS side is nearly identical to iOS, with one important caveat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// On tvOS, prefer cross-platform credentials so hybrid transport activates&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;crossPlatformProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationSecurityKeyPublicKeyCredentialProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;relyingPartyIdentifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"streaming.example.com"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;assertionRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crossPlatformProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCredentialAssertionRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;challenge&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ASAuthorizationController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;authorizationRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;assertionRequest&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;presentationContextProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;performRequests&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We learned the hard way that on tvOS, mixing platform and cross-platform requests in the same &lt;code&gt;ASAuthorizationController&lt;/code&gt; invocation produces inconsistent UI. Stick to one transport per ceremony on the TV.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Hybrid Transport for QR Code Pairing on Smart TVs (with code)
&lt;/h2&gt;

&lt;p&gt;Hybrid transport, also called caBLE in some FIDO documentation, is the CTAP 2.2 mechanism that lets a TV (which has no biometric and no platform authenticator) authenticate a user by displaying a QR code that the user scans with their phone. The phone performs the user verification, the assertion travels back to the TV through a short Bluetooth Low Energy proximity check plus a relayed cloud channel, and the TV gets a valid WebAuthn assertion bound to the same relying party.&lt;/p&gt;

&lt;p&gt;Hybrid transport is supported natively by Chrome on smart TVs that ship Android TV 12 and newer, by Safari on tvOS 17 and newer, and by the platform auth dialog on Windows 11 and modern macOS for the TV-as-second-screen case. The FIDO Alliance October 2025 spec page lists CTAP 2.2 hybrid transport as the standard cross-device flow recommended for shared device authentication.&lt;/p&gt;

&lt;p&gt;For TVs that do not have native hybrid support, you implement the QR pairing pattern in your own app. The TV displays a short code, the user opens the streaming service in their phone browser, types the code or scans the QR, the phone authenticates the user with a passkey, and your backend marks the TV session authenticated. This is functionally OAuth 2.0 device authorization grant, RFC 8628, with passkey at the verification step.&lt;/p&gt;

&lt;p&gt;Here is a TV-side implementation in JavaScript that runs in a smart TV browser environment (Tizen, webOS, modern Fire TV Silk):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TV-side: request a device code, render the QR, then poll for completion&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startTvPasskeyPairing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Request a device code from your backend&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initRes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://auth.example.com/device/code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tv-client-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openid profile streaming.read&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verification_uri_complete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expires_in&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;initRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Render the user-friendly code and a QR pointing to the verification URL&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user_code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;renderQrCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;qr-canvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verification_uri_complete&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Poll the token endpoint until the user authenticates on phone&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;startedAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;expires_in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenRes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://auth.example.com/oauth/token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;grant_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urn:ietf:params:oauth:grant-type:device_code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tv-client-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id_token&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;onTvAuthenticated&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id_token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization_pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slow_down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;access_denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expired_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;showRetryButton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;showRetryButton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the phone side, the user lands on &lt;code&gt;verification_uri_complete&lt;/code&gt; (which encodes the device code as a query param), confirms the action, and triggers a WebAuthn assertion in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Phone-side: complete the device pairing with a passkey&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;completePairingWithPasskey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Pull the assertion options from your backend&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;optsRes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/webauthn/assert/options&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deviceCode&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;optsRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Trigger the platform passkey ceremony&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;base64UrlToBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;rpId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;streaming.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;allowCredentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;base64UrlToBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;transports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})),&lt;/span&gt;
      &lt;span class="na"&gt;userVerification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Send the assertion plus the device code so the backend can mark&lt;/span&gt;
  &lt;span class="c1"&gt;// the TV session authenticated.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verifyRes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/webauthn/assert/verify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;assertion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;serializeAssertion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verifyRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;showSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your TV is now signed in. You can close this tab.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two operational details that the spec does not call out. First, the QR code should encode the full &lt;code&gt;verification_uri_complete&lt;/code&gt; URL with the user code already embedded as a query parameter. A Roku 2025 user research note found that including the code in the URL drops successful pairing time by an average of 17 seconds versus asking the user to type the code on the second screen. Second, the polling interval matters more than you think. We started with a 5 second interval to be polite to the auth server, then bumped to 2 seconds after measuring that 22 percent of users tapped "didn't work" within 8 seconds of completing on the phone if the TV had not updated yet.&lt;/p&gt;

&lt;p&gt;For the React or Next.js phone surface, &lt;a href="https://mojoauth.com/integrations/react/passkeys" rel="noopener noreferrer"&gt;MojoAuth's React passkey integration&lt;/a&gt; wraps the &lt;code&gt;navigator.credentials.get&lt;/code&gt; call with the discovery and fallback logic so you do not have to maintain the boilerplate. The Android-app equivalent for the phone-side code path is documented in the &lt;a href="https://mojoauth.com/integrations/android/passkeys" rel="noopener noreferrer"&gt;Android passkey integration guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Build Session Handoff Between Devices (with code)
&lt;/h2&gt;

&lt;p&gt;Session handoff is the pattern where a user authenticated on one device transfers a fresh session to a second device without re-authenticating from scratch, typically by scanning a QR code or entering a short code. For streaming, the canonical use case is the user already signed in on their phone walking up to the TV and getting signed in there in under ten seconds. The mechanism is OAuth 2.0 device authorization grant (RFC 8628) layered on top of an existing authenticated session, which is a different code path from the cold-start pairing flow above.&lt;/p&gt;

&lt;p&gt;The handoff flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The phone is already authenticated and holds a refresh token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The TV requests a device code as in the pairing flow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The TV displays the QR pointing to a deep link the phone app handles natively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The phone, already authenticated, calls a backend endpoint that exchanges the device code for a TV-scoped access token using the phone's existing session, no second WebAuthn ceremony required.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Backend handler (Node.js, Express style) for the handoff endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// POST /device/handoff&lt;/span&gt;
&lt;span class="c1"&gt;// Authenticated request from a signed-in phone session&lt;/span&gt;
&lt;span class="c1"&gt;// Body: { device_code: "..." }&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/device/handoff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requireAuthenticatedSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;device_code&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 1. Look up the pending device code&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deviceCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid_device_code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiresAt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expired_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Verify the originating session is recent enough to allow handoff.&lt;/span&gt;
  &lt;span class="c1"&gt;// A 30-day-old session can refresh tokens but should not silently&lt;/span&gt;
  &lt;span class="c1"&gt;// auth a brand new TV without a step-up.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionAgeHours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3600000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionAgeHours&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;step_up_required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;step_up_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/webauthn/assert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Bind the device code to the user and mint TV-scoped tokens&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deviceCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markAuthenticated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;deviceFingerprint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;device_fingerprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;grantedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;streaming.read offline_access&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. Audit trail. Required for any service serving &amp;gt; 100k MAU&lt;/span&gt;
  &lt;span class="c1"&gt;// according to the IETF OAuth 2.1 BCP draft on device flow.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;audit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;device_handoff_completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sourceUserAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-agent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;targetClientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authenticated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two real-world details. First, the 24 hour session age check is not in the RFC, but you want it. Without it, any compromised long-lived phone session can sign in to an attacker's TV silently. We added the step-up requirement after a red team exercise in March 2025 demonstrated the silent-handoff abuse path. Second, the device fingerprint on the TV side matters for revocation. When a user later hits "sign out of all devices" in account settings, you need a stable handle to revoke the TV's refresh token by, and the fingerprint plus client ID combination is the cleanest one we found.&lt;/p&gt;

&lt;p&gt;The phone-side native handler for the deep link should look something like this in Kotlin for Android, using a Universal Link or Android App Link configuration that opens your app instead of the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HandoffActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;deviceCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getQueryParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"device_code"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;lifecycleScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deviceHandoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requiresStepUp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;triggerPasskeyAssertion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;showSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Your TV is signed in. Open the app on TV."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;finishWithDelay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;showError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s"&gt;"Sign-in failed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deep link interception, rather than punting to a browser, is what gets handoff under three seconds of perceived latency. A Conviva 2025 streaming UX study found that every additional second of TV pairing latency above five seconds drops completion by 4.6 percent. You feel that on a Saturday night.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Do for Roku, Fire TV, and Older Smart TVs (fallback)
&lt;/h2&gt;

&lt;p&gt;For Roku, older Fire TV devices, and any smart TV without WebAuthn or a native QR handler, fall back to a pure OAuth 2.0 device authorization grant (RFC 8628) with no passkey on the TV side at all. The TV displays a short alphanumeric code and a memorable URL, the user goes to that URL on any phone or laptop, types the code, and authenticates with their normal passkey flow on that second device. The TV polls and gets a token. This is the same flow Netflix and Disney+ use today on Roku.&lt;/p&gt;

&lt;p&gt;The honest reality on Roku is that the Roku BrightScript SDK (as of Roku OS 13.5, shipped in 2025) does not support WebAuthn natively. Roku's developer documentation updated November 2025 still recommends the device code pattern with a code and URL displayed on the TV, with the actual passkey ceremony happening on the user's phone browser at &lt;code&gt;https://example.com/tv&lt;/code&gt;. There is no other way. A 2025 Roku Channel Partner Program brief noted that they have evaluated WebAuthn for the SDK but have no ship date.&lt;/p&gt;

&lt;p&gt;Fire TV is more nuanced. Fire OS 7.6 and Fire OS 8 (shipping on devices from 2023 forward) include a Silk browser that supports WebAuthn and a Credential Manager equivalent. Older Fire TV Sticks running Fire OS 5 or 6 do not. Amazon Developer documentation accessed November 2025 confirms the safe assumption: feature-detect and fall back to device code on any failure. The detection check that worked for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tvSupportsHybridWebAuthn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PublicKeyCredential&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PublicKeyCredential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isConditionalMediationAvailable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Fire TV Silk reports a Chromium UA, but only OS 7.6+ has the platform auth&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ua&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ua&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AFT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;osVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFireOsVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ua&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;osVersion&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;7.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the long tail of older smart TVs (2017 Vizio, 2018 LG webOS, 2019 Samsung Tizen), assume nothing works and ship the device code flow. The user types the code on their phone, completes a passkey ceremony there, and the TV gets a token through the polling endpoint. Conviva's 2025 streaming benchmark measured this pattern at a median 38 seconds end to end across the install base, dramatically better than the 2 minute 15 second median for password entry on the same hardware.&lt;/p&gt;

&lt;p&gt;One additional safety net: support email magic link as a tertiary fallback, particularly for users on TVs without internet on a phone in hand (yes, this happens). MojoAuth's &lt;a href="https://mojoauth.com/products/email-magic-link" rel="noopener noreferrer"&gt;email magic link product&lt;/a&gt; handles the link generation and validation, including the universal link configuration that lets the link open the iOS or Android app if installed. We logged 2.4 percent of TV authentications going through magic link in 2025, almost entirely on first-day setup before the user had configured anything else.&lt;/p&gt;

&lt;p&gt;The honest limitation is that you will not get a 100 percent passkey adoption rate on TV. Aim for 60 percent of TV authentications using a passkey-backed flow (hybrid transport or device code with passkey on the second device) within twelve months of rollout, with the remaining 40 percent split between magic link, OTP, and the unfortunate user who still types a password into a remote. We hit 64 percent in our internal numbers by Q4 2025, with the holdouts concentrated on Roku and pre-2020 smart TVs.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can a passkey enrolled on iPhone be used to log in to an Android TV?
&lt;/h3&gt;

&lt;p&gt;Yes, through hybrid transport (CTAP 2.2 caBLE). The Android TV displays a QR code, the iPhone scans it from any QR-aware app or directly through the iOS camera, and Safari on iOS prompts for the passkey assertion. The assertion travels back to the Android TV through a relayed cloud channel plus a Bluetooth proximity check. Native cross-ecosystem sync (iCloud passkey appearing in Google Password Manager) is not yet shipping in 2026, but cross-device usage through hybrid transport works today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a separate WebAuthn relying party ID for the TV app?
&lt;/h3&gt;

&lt;p&gt;No. The relying party ID should be the bare domain that owns your account (for example &lt;code&gt;streaming.example.com&lt;/code&gt;), and the same RP ID is used by the iOS app, Android app, web app, and TV app. The platform credential manager binds the credential to that RP ID, and any compatible client surface that performs the assertion against the same RP ID will succeed. Splitting RP IDs by client is a common mistake that breaks cross-device login and forces re-enrollment.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long should the TV device code be, and how long should it last?
&lt;/h3&gt;

&lt;p&gt;The user code should be 8 to 9 characters, alphanumeric, and uppercase, with visually ambiguous characters (0, O, I, 1) excluded for legibility on a TV screen. RFC 8628 recommends a code lifetime of 1800 seconds (30 minutes), but for streaming we set it to 600 seconds (10 minutes) to limit the window for any code that someone reads off a TV in a public space. The polling interval should start at 2 seconds and respect any &lt;code&gt;slow_down&lt;/code&gt; response from the auth server.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if the user does not have iCloud Keychain or Google Password Manager turned on?
&lt;/h3&gt;

&lt;p&gt;The passkey is created and stored locally on the device but does not sync. That means the user can authenticate fine on the device where they enrolled, but will be treated as an unknown device on every other surface and will need to re-enroll or use a fallback like email magic link. Detect this case at enrollment time by inspecting the authenticator attachment metadata, and prompt the user to enable sync or set up a second factor. We saw a 14 percent rate of non-syncing passkeys in 2025, mostly on Android.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is hybrid transport secure enough for a high-value account like a streaming service tied to a payment method?
&lt;/h3&gt;

&lt;p&gt;Yes. CTAP 2.2 hybrid transport requires both a Bluetooth Low Energy proximity confirmation between the phone and the second-device client, and a cryptographic challenge response signed by the platform authenticator. The FIDO Alliance security analysis updated October 2025 explains why the proximity check matters: it is the defense against remote phishing, since an attacker would need physical Bluetooth range of the user's phone to relay the assertion. For the level of financial risk associated with a streaming subscription, hybrid transport is solidly within acceptable risk tolerance.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I revoke a passkey when a user reports a stolen device?
&lt;/h3&gt;

&lt;p&gt;You revoke at two levels. First, mark the credential ID as revoked in your relying party database so the next assertion attempt fails. Second, expire all refresh tokens issued under that credential, including any device-flow tokens granted to TVs. The user should still be able to authenticate from their other synced devices because the underlying passkey is preserved in iCloud or Google account, but the local credential on the lost device will not work for new assertions. Document this flow in your account settings so support does not have to walk every user through it manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Smart TV authentication is the part of the stack where streaming services lose subscribers quietly, and it is the part where good engineering compounds the fastest. Get the passkey ceremony right on iOS and Android first, layer hybrid transport for tvOS and modern Android TV, ship the OAuth device flow as the universal fallback for Roku and the long tail of older smart TVs, and instrument every step so you know which device categories are bleeding completion. The 64 percent passkey-backed TV authentication rate we hit in 2025 was not from a single rollout, it was from twelve months of incremental capability detection and fallback work.&lt;/p&gt;

&lt;p&gt;If you want to skip the boilerplate of running your own FIDO2 server, attestation chain validation, and platform-specific SDK upkeep, MojoAuth handles the cross-platform passkey infrastructure and the device flow surface as a managed product. Ready to try? &lt;a href="https://mojoauth.com" rel="noopener noreferrer"&gt;Sign up for MojoAuth.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Last updated: May 2026&lt;/em&gt;&lt;/p&gt;

</description>
      <category>multidevicepasskeyst</category>
      <category>smarttvpasskeylogin</category>
      <category>hybridtransportwebau</category>
      <category>qrcodepairingtv</category>
    </item>
    <item>
      <title>9 Metrics CISOs Should Track to Prove Passwordless ROI</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Fri, 01 May 2026 12:49:13 +0000</pubDate>
      <link>https://forem.com/mojoauth/9-metrics-cisos-should-track-to-prove-passwordless-roi-44h8</link>
      <guid>https://forem.com/mojoauth/9-metrics-cisos-should-track-to-prove-passwordless-roi-44h8</guid>
      <description>&lt;p&gt;According to the HID/FIDO Alliance 2025 State of Authentication survey, organizations deploying passkeys reported a 26% reduction in password usage, 60-80% fewer password reset tickets, and measurable improvements in login success rates, yet most security teams present these results to the CFO as anecdotes rather than tracked KPIs. That gap is where passwordless investments stall, get de-scoped at renewal, or fail to expand to new use cases.&lt;/p&gt;

&lt;p&gt;The ROI of passwordless authentication is real, documented, and quantifiable. The problem is that most teams don't instrument it before deployment, which means they can't prove it after. This guide defines the nine metrics that close the C-suite loop: what each one measures, what benchmarks to target, and how to present them in an executive dashboard that turns security spend into a defensible investment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passwordless ROI metrics:&lt;/strong&gt; The set of operational, security, and financial key performance indicators that quantify the business value of replacing password-based authentication with passkeys, magic links, or other credential-free methods, expressed in terms that finance and executive stakeholders can evaluate against the cost of deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HubSpot's December 2024 passkey deployment produced a 25% improvement in login success rates and authentication that was 4x faster than password-plus-2FA flows. Both metrics are directly measurable before and after deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;According to the HID/FIDO Alliance 2025 survey, enterprises deploying passkeys report average annual savings of $594,000 from eliminated authentication overhead. Password reset ticket reduction (60-80%) is the most commonly cited and most easily documented ROI line item.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Forrester estimates a single password reset costs $70 in IT labor. Organizations with 25,000 employees eliminating 70% of reset volume save approximately $1.75 million annually, with no assumptions required beyond the reset volume baseline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A passkey deployment fallback rate below 5% is the operational health target. Above 10% indicates a device sync or enrollment UX problem that will erode ROI projections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cyber insurers are offering 15-30% premium reductions for organizations that demonstrate FIDO2 passkey deployment. That discount is documentable leverage in renewal negotiations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;According to MojoAuth's 2026 Passwordless Conversion Impact Report, organizations implementing passwordless authentication reduce sign-in speeds by up to 82% and cart abandonment by as much as 50%, making authentication metrics directly translatable to revenue impact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The nine metrics in this guide map directly to the four CFO-level concerns for any security investment: cost reduction, revenue protection, risk reduction, and compliance value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Do CISOs Need Specific ROI Metrics for Passwordless Authentication?
&lt;/h2&gt;

&lt;p&gt;CISOs need specific ROI metrics for passwordless authentication because security spending is under increasing CFO scrutiny, and "improved security posture" is no longer an acceptable justification for a six-figure annual platform investment.&lt;/p&gt;

&lt;p&gt;The passwordless ROI story is genuinely compelling, but it requires instrumentation to tell it. The cost savings are distributed across IT support (reset tickets), engineering (reduced auth infrastructure maintenance), security (fraud prevention), and revenue (conversion lift). No single department sees the total picture, and without pre-deployment baselines, post-deployment improvements look like noise rather than signal.&lt;/p&gt;

&lt;p&gt;The good news is that passwordless authentication produces measurable outcomes in a shorter timeframe than most security investments. According to MojoAuth's deployment data, most organizations see measurable ROI within 12 to 18 months. The organizations that close that loop at the CFO level are the ones that defined their measurement framework before deployment, not after.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 9 Metrics That Prove Passwordless ROI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Metric 1: Passkey Enrollment Rate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The percentage of eligible users who have successfully created and registered at least one passkey credential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 60-80%+ for a well-designed deployment. According to data across real-world deployments documented by the FIDO Alliance, VicRoads achieved 80% passkey activation on mobile after optimizing their enrollment prompt. eBay's contextual post-login enrollment prompt drove 102% higher adoption than a settings-page option, per MojoAuth's analysis of passkey deployment lessons from eBay, HubSpot, and Revolut.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Enrollment rate = (users with at least one active passkey credential / total eligible users) x 100. Segment by device type (mobile vs. desktop) and user cohort (new registrations vs. existing users migrated). A deployment below 40% typically indicates a UX problem with the enrollment prompt, not a technology problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; Enrollment rate is the leading indicator for every downstream metric. Low enrollment means support tickets won't fall, login success won't improve, and SMS costs won't decrease. It's the deployment health metric that finance teams need to understand before the cost savings projections are credible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; An enrollment rate that plateaus below 50% after 90 days. This indicates a design or communication failure, not user resistance. &lt;a href="https://mojoauth.com/blog/7-passkey-deployment-lessons-from-ebay-hubspot-revolut-and-vicroads" rel="noopener noreferrer"&gt;Review MojoAuth's passkey deployment lessons&lt;/a&gt; to diagnose enrollment plateau causes before they erode ROI projections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 2: Login Success Rate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The percentage of login attempts that result in a successful, completed authentication, including first-attempt completions without fallback or retry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 25% improvement over password-plus-2FA baseline. HubSpot's December 2024 passkey launch produced exactly this outcome: a 25% improvement in login success rates, per HubSpot's published deployment data. Intuit reported a 15% login success rate improvement. Yahoo Japan reported 2.6x faster authentication time alongside success rate gains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Login success rate = (successful authentications / total authentication attempts) x 100. Track separately for passkey users vs. password users during the transition period. The gap between these two cohorts is your ROI evidence. Also track passkey utilization rate among enrolled users: what percentage used their passkey on their most recent login? This number tells you whether enrolled users are actually authenticating with passkeys consistently or falling back to passwords.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; Every percentage point of login success rate improvement represents users who completed a session, transaction, or task that they otherwise abandoned. For e-commerce, that's direct revenue. For SaaS, that's session engagement and retention. For internal tools, that's productivity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; Login success rate for passkey users dropping below that for password users after 60 days. This typically indicates a device sync issue following a major OS update and requires immediate investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 3: Average Time-to-Login
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The median time from a user initiating a login attempt to completing successful authentication, measured across authentication methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 4x faster than password-plus-2FA. HubSpot reported authentication completing approximately 4x faster with passkeys compared to their password-plus-2FA flow. MojoAuth's Passwordless Conversion Impact Report documents sign-in speeds up to 82% faster for organizations that implement passwordless authentication. Intuit reported 70% faster sign-in after passkey deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Instrument time-to-login at the session level in your analytics stack. Measure from the first interaction with the login UI to the issuance of an authenticated session token. Report as median (not mean) to avoid outlier distortion from network edge cases. Compare across authentication method cohorts: passkey users, password-plus-TOTP users, and magic link users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; Authentication speed directly affects user behavior. Every second of friction at login is a dropout risk. For consumer-facing applications, login speed is a conversion metric. For internal applications, it's a productivity metric. A 4x speed improvement on a daily-login enterprise tool with 5,000 employees compounds across every workday.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 4: Password Reset Tickets per 1,000 Users per Month
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The volume of IT helpdesk tickets specifically generated by password reset requests, account lockouts, and MFA enrollment failures, normalized per 1,000 active users to allow cross-period comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 60-80% reduction. According to the HID/FIDO Alliance 2025 survey, organizations deploying passkeys consistently report 60-80% fewer password reset tickets. Aflac documented a 32% reduction in password recovery requests. Yahoo Japan reported 25% fewer user inquiries related to login issues. A MojoAuth fintech client reported a 55% decrease in password reset tickets specifically after passkey rollout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Pull ticket volume from your ITSM platform (ServiceNow, Jira Service Management, Zendesk) using ticket category tags for "password reset," "account lockout," and "MFA issue." Establish a 90-day pre-deployment baseline. Report monthly post-deployment with a trend line showing the reduction trajectory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dollar translation for CFO:&lt;/strong&gt; Forrester estimates a single password reset at $70 in IT labor fully loaded. An organization with 10,000 users averaging 300 reset tickets per month at $70 each spends $252,000 annually on reset overhead alone. A 70% reduction saves $176,400 per year from a single metric. &lt;a href="https://mojoauth.com/blog/13-hidden-costs-of-password-based-authentication-with-real-roi-math" rel="noopener noreferrer"&gt;Review the full hidden cost analysis of password-based authentication&lt;/a&gt; to build the complete cost baseline before your deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 5: Account Takeover Incidents per Quarter
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The number of confirmed account takeover (ATO) events per quarter, defined as unauthorized access to a user account using compromised credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; Near-zero for phishing and credential stuffing vectors. CVS Health achieved a 98% reduction in account takeover fraud after deploying passkeys, per FIDO Alliance case study data. JPMorgan Chase reported a 94% reduction in account takeovers during their passkey beta. Air New Zealand and Mercoin reported 0% credential stuffing attacks in their fully passwordless environments, per MojoAuth's Passkeys Handbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Source ATO data from your identity threat detection and response (ITDR) system, SIEM, and fraud operations team. Classify incidents by attack vector: credential stuffing, phishing, SIM swap, session hijacking. Track each vector separately. After passkey deployment, credential stuffing and phishing ATOs should approach zero. Session hijacking and SIM swap vectors require separate countermeasures and will persist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; According to IBM's 2024 Cost of a Data Breach report, credential stuffing causes $4.81 million in damage per incident. Even a single ATO prevention per year justifies substantial authentication investment. For organizations in high-ATO industries (e-commerce, fintech, gaming), this metric alone closes the ROI argument. &lt;a href="https://mojoauth.com/blog/15-costliest-credential-stuffing-attack-examples-of-the-decade-and-the-authentication-lessons-they-teach" rel="noopener noreferrer"&gt;See the most costly credential stuffing incidents of the decade&lt;/a&gt; for the breach cost benchmarks to use in executive presentations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 6: SMS OTP Spend per Month
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The direct monetary cost of SMS-based one-time password delivery, including per-message fees from your SMS provider, broken down by domestic and international rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 60-90% reduction for organizations with significant SMS OTP volume. According to MojoAuth's hidden costs analysis, SMS delivery fees can reach $50,000 to $100,000 annually at 500,000 monthly active users, with international SMS rates in markets like India and Southeast Asia carrying premium pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Pull SMS delivery cost directly from your SMS provider's monthly invoice (Twilio, AWS SNS, Vonage). Track total messages sent, cost per message, and total monthly spend. Segment by authentication event type (login OTP vs. transaction confirmation OTP). After passkey deployment, track the reduction in authentication-triggered SMS events separately from transaction-confirmation SMS, which may continue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; SMS OTP spend is the most directly visible cost in the passwordless ROI calculation because it appears as a line item on a vendor invoice rather than as allocated labor. A $75,000 annual SMS bill that drops to $10,000 after passkey deployment is a $65,000 saving that requires no assumptions or labor cost modeling. It's also the number that resonates most clearly with CFOs who struggle to evaluate security ROI in more abstract terms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compounding factor:&lt;/strong&gt; As detailed in MojoAuth's analysis of &lt;a href="https://mojoauth.com/blog/6-reasons-sms-otp-is-being-banned-worldwide-and-what-to-deploy-instead" rel="noopener noreferrer"&gt;why SMS OTP is being banned worldwide&lt;/a&gt;, regulatory pressure in the UAE, India, and the Philippines is eliminating SMS OTP as a compliant option for financial services. Organizations that have already reduced their SMS dependency are ahead of a forced migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 7: Registration Conversion Rate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The percentage of users who begin a registration or sign-up flow and complete it with a verified, active account, including passkey enrollment for new deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 20-40% improvement for registration flows that replace password creation with passkeys or magic links. According to MojoAuth's 2026 Passwordless Conversion Impact Report, passwordless registration flows consistently reduce abandonment by 20-40% because there's no password to create, confirm, or meet complexity requirements for. Cart abandonment reductions of up to 50% are documented for e-commerce deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Instrument your registration funnel with event tracking at each step: email entry, credential creation, verification, and first authenticated session. Calculate conversion rate as (completed registrations / initiated registrations) x 100. A/B test passkey enrollment against password creation if you're in a hybrid phase to document the improvement directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; Registration conversion rate is one of the most direct authentication-to-revenue metrics available. A 25% improvement in registration conversion for a platform adding 10,000 new registrations per month at a $100 LTV per user translates to $250,000 in additional annual revenue from authentication optimization alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 8: Mean Time to Detect and Respond to Identity-Based Incidents (MTTD/MTTR)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; MTTD is the average time from the start of an identity-based security incident to its detection by your security team. MTTR is the average time from detection to containment. Together they measure the operational efficiency of your identity threat detection and response (ITDR) capability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; MTTD under 24 hours for authentication anomalies; MTTR under 4 hours for credential compromise incidents. According to IBM's 2024 Cost of a Data Breach report, the average time to identify and contain a breach is 258 days. Organizations with phishing-resistant authentication and active ITDR capabilities compress this dramatically: there are no credential-based attack paths to discover retroactively when there are no credentials to compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Source MTTD and MTTR from your SIEM or ITDR platform. Define "identity-based incident" narrowly: unauthorized access attempts, anomalous authentication patterns, credential compromise alerts. Track separately for the passkey user population vs. password user population during transition. A passkey-authenticated account that shows anomalous login behavior is a session compromise or device theft issue, not a credential compromise, which changes both the detection signal and the response playbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; Shorter MTTD and MTTR translate directly to lower breach costs. IBM's research shows each day of dwell time adds approximately $18,000 to breach cost. A 60-day reduction in mean time to contain an identity incident saves approximately $1.1 million in average breach exposure. This is the metric that bridges authentication ROI to cyber insurance underwriting conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric 9: Cyber Insurance Premium Impact
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it measures:&lt;/strong&gt; The change in cyber insurance premium cost following documented passkey deployment, expressed as a percentage reduction and absolute dollar saving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target benchmark:&lt;/strong&gt; 15-30% premium reduction for organizations that demonstrate FIDO2 passkey deployment across employee and customer-facing systems. According to the HID/FIDO Alliance 2025 survey analysis, underwriters have updated their risk models and are offering these premium reductions to organizations that can demonstrate phishing-resistant authentication deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to track it:&lt;/strong&gt; Document the pre-deployment premium and coverage terms. At renewal, present your passkey deployment metrics (enrollment rate, ATO reduction, SMS OTP reduction) as supporting evidence for a risk classification review. Request a formal underwriter assessment. The ICO's £2.31 million fine against 23andMe for MFA inadequacy is the reference case most underwriters point to when explaining their risk classifications for organizations with and without phishing-resistant MFA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CFO translation:&lt;/strong&gt; A 20% premium reduction on a $500,000 annual cyber insurance policy is $100,000 per year in direct cost savings that appears on the CFO's budget, not buried in IT operations. Combined with reset ticket savings and SMS cost reduction, it often represents the tipping point that makes the total ROI case undeniable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Executive Dashboard Layout
&lt;/h2&gt;

&lt;p&gt;Use this layout for your quarterly authentication ROI report to the CFO or board security committee. Four panels, one page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Panel 1: Security Health (top left)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Account takeover incidents this quarter vs. prior quarter vs. pre-deployment baseline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login anomaly detection rate (via ITDR)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passkey enrollment rate trend (30/60/90 day)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fallback rate (target: below 5%)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Panel 2: Operational Savings (top right)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Password reset tickets per 1,000 users: current vs. baseline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Estimated dollar savings from reset reduction (tickets x $70)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SMS OTP spend: current month vs. pre-deployment baseline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Total authentication-related support cost&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Panel 3: User Experience (bottom left)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Login success rate: passkey users vs. password users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Average time-to-login: passkey vs. password-plus-2FA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registration conversion rate: current vs. pre-deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passkey utilization rate among enrolled users&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Panel 4: Financial Impact (bottom right)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Estimated annual savings from all metric improvements (combined)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cyber insurance premium: current vs. prior year&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Projected ROI payback month (based on platform cost vs. cumulative savings)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open items: metrics not yet at target with owner and timeline&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This four-panel layout maps directly to the four questions every CFO asks about a security investment: Is it working? What is it saving? Are users adopting it? What is the total financial return?&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is the Fastest ROI Metric to Document After a Passwordless Deployment?
&lt;/h3&gt;

&lt;p&gt;Password reset ticket volume is the fastest ROI metric to document because it appears in your ITSM platform within days of deployment and produces a dollar saving calculable at $70 per ticket. Organizations with 10,000+ users typically see measurable ticket reduction within 30 days of reaching 50% passkey enrollment. It's also the metric most familiar to CFOs because support overhead is already a tracked line item in most IT budgets. According to the HID/FIDO Alliance 2025 survey, 60-80% ticket reduction is the most commonly reported post-deployment outcome across enterprise passkey deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do You Establish a Pre-Deployment Baseline for Passwordless ROI?
&lt;/h3&gt;

&lt;p&gt;Establish baselines for all nine metrics in the 90 days before deployment begins. For password reset tickets, pull 90 days of historical data from your ITSM platform. For login success rate, pull historical authentication logs and calculate the success percentage for your primary authentication flow. For SMS OTP spend, pull 90 days of invoices from your SMS provider. For account takeover incidents, pull 90 days of fraud operations records. Without these baselines, post-deployment improvements cannot be attributed to the passwordless deployment with confidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does a Good Passkey Deployment Fallback Rate Look Like?
&lt;/h3&gt;

&lt;p&gt;A healthy passkey deployment has a fallback rate below 5%. The fallback rate measures what percentage of authentication events for enrolled passkey users trigger a fallback to password or OTP. A rate above 10% indicates a device sync issue, enrollment UX problem, or OS compatibility gap that will erode your support ticket reduction and login success rate projections. Spikes in fallback rate after major iOS or Android releases are common and typically resolve within one OS patch cycle once users update.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do You Calculate the ROI of Reducing SMS OTP Spend?
&lt;/h3&gt;

&lt;p&gt;SMS OTP ROI is the simplest calculation in the passwordless business case. Total current monthly SMS spend divided by total monthly authentications gives you the cost per authentication event. After passkey deployment, authentication events that succeed via passkey generate zero SMS cost. ROI = (authentication events migrated to passkeys x cost per SMS OTP event) x 12 months, minus the annual platform cost. For organizations at 500,000 MAU with significant international users, this calculation frequently produces an ROI that covers the entire platform cost from SMS savings alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Metric Is Most Persuasive for Cyber Insurance Negotiations?
&lt;/h3&gt;

&lt;p&gt;Account takeover incident rate combined with phishing attack success rate is the most persuasive package for cyber insurance negotiations. Underwriters price cyber risk primarily around credential compromise probability. Demonstrating a 90%+ reduction in ATO incidents and zero phishing-originated credential breaches since passkey deployment directly addresses the threat categories that drive premium pricing. Supporting that with your FIDO2 certification documentation, deployment scope (percentage of user population covered), and MTTD/MTTR improvements gives underwriters the evidence they need to reclassify your risk tier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The business case for passwordless authentication has never been stronger, and it's fully documentable with the nine metrics in this guide. The organizations that will get the most out of their investment are not necessarily the ones with the most sophisticated deployments. They're the ones that defined measurement frameworks before deployment, established baselines, and tracked outcomes quarterly with the same rigor applied to any other major technology investment. Authentication is no longer just a security function. It's a revenue, productivity, and insurance premium optimization. Track it like one.&lt;/p&gt;

&lt;p&gt;Ready to instrument these metrics in your deployment? &lt;a href="https://mojoauth.com/developers/" rel="noopener noreferrer"&gt;Explore MojoAuth's developer resources and analytics capabilities&lt;/a&gt; to understand the authentication event logging and reporting infrastructure that supports the dashboard layout in this guide. Or &lt;a href="https://mojoauth.com/white-papers/passkeys-passwordless-authentication-handbook/" rel="noopener noreferrer"&gt;download the MojoAuth Passkeys and Passwordless Authentication Handbook&lt;/a&gt; for the complete ROI framework, including the cost worksheet your CFO needs to sign off on the business case.&lt;/p&gt;

</description>
      <category>passwordlessroimetri</category>
      <category>authenticationkpis</category>
      <category>cisometricsidentity</category>
      <category>passwordlessauthenti</category>
    </item>
    <item>
      <title>6 Quantum Computing Milestones That Will Redefine Authentication</title>
      <dc:creator>Victor</dc:creator>
      <pubDate>Fri, 01 May 2026 12:44:26 +0000</pubDate>
      <link>https://forem.com/mojoauth/6-quantum-computing-milestones-that-will-redefine-authentication-3917</link>
      <guid>https://forem.com/mojoauth/6-quantum-computing-milestones-that-will-redefine-authentication-3917</guid>
      <description>&lt;p&gt;According to NIST's own transition guidance, organizations must migrate from RSA and ECC to post-quantum cryptography by 2030, and after 2035, quantum-vulnerable algorithms will be formally prohibited for US government use. That timeline sounds distant until you account for "harvest now, decrypt later" attacks, which means identity data encrypted today is already being collected by nation-state adversaries who expect to decrypt it within a decade.&lt;/p&gt;

&lt;p&gt;For CISOs, security architects, and compliance officers at long-horizon organizations, the post-quantum authentication problem is not a 2030 problem. It's a 2026 procurement decision. The authentication infrastructure you deploy this year will still be in production when cryptographically relevant quantum computers arrive. If it can't be upgraded without a full re-architecture, you've locked yourself into a vulnerability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-quantum authentication:&lt;/strong&gt; Authentication systems built on cryptographic algorithms designed to resist attacks from both classical and quantum computers, replacing RSA and elliptic curve cryptography (ECC) with lattice-based, hash-based, or code-based alternatives that quantum computers cannot efficiently break using Shor's algorithm or Grover's algorithm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;NIST finalized the first three post-quantum cryptography standards in August 2024: ML-DSA (FIPS 204), ML-KEM (FIPS 203), and SLH-DSA (FIPS 205). These are the global reference standards for quantum-safe cryptography.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IANA added post-quantum algorithms to the COSE codelist in April 2025, providing the standards infrastructure for quantum-safe FIDO2 passkeys. The authentication migration path is now fully specified at the standards level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Harvest now, decrypt later" (HNDL) is an active, present-day threat, not a future scenario. US DHS, UK NCSC, and ENISA all base their official post-quantum guidance on the premise that adversaries are currently exfiltrating encrypted data at scale.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NIST has given guidance that organizations should switch from RSA and ECC to ML-DSA by 2030. After 2035, post-quantum cryptography will be mandatory for US government agencies, according to DigiCert's analysis of the FIPS 204 guidance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NSS (National Security Systems) compliance deadlines begin January 2027, making the migration timeline concrete for defense contractors, critical infrastructure operators, and federal agencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crypto-agility, the ability to swap cryptographic algorithms without re-architecting the application layer, is now the single most important buying criterion for enterprise CIAM platforms. Monolithic authentication stacks that hardcode RSA or ECDSA are already liabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MojoAuth's enterprise platform includes ML-DSA (Dilithium) integration aligned with NIST's 2024 PQC standards, with a post-quantum roadmap available to enterprise prospects, making it one of the few CIAM platforms positioned ahead of the transition rather than behind it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Do Quantum Computing Milestones Matter for Authentication Specifically?
&lt;/h2&gt;

&lt;p&gt;Quantum computing milestones matter for authentication specifically because authentication is the part of your security stack most dependent on the asymmetric cryptography that quantum computers will break.&lt;/p&gt;

&lt;p&gt;Today's passkeys, TLS handshakes, JWT signing, and OAuth token exchange all rely on RSA or ECDSA. These algorithms derive their security from mathematical problems (integer factorization and elliptic curve discrete logarithm) that classical computers cannot solve efficiently. Shor's algorithm, running on a sufficiently powerful quantum computer, solves both problems efficiently. The implication is direct: the cryptographic foundation of modern identity infrastructure has a known expiration date.&lt;/p&gt;

&lt;p&gt;The authentication layer faces a unique version of this problem. Unlike encrypted data at rest, which can be migrated to quantum-safe algorithms in a single re-encryption pass, authentication infrastructure involves enrolled credentials, deployed hardware authenticators, distributed session tokens, and third-party IdP integrations that cannot all be updated simultaneously. That complexity is why the migration window matters: organizations with crypto-agile authentication platforms will complete the transition smoothly; those with hardcoded cryptographic dependencies will face re-architecture under time pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 6 Quantum Computing Milestones That Redefine Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. NIST Finalizes the First PQC Standards (August 2024): The Starting Gun Has Fired
&lt;/h3&gt;

&lt;p&gt;NIST's August 2024 finalization of ML-DSA (FIPS 204), ML-KEM (FIPS 203), and SLH-DSA (FIPS 205) is the single most important event in post-quantum cryptography history, because it transformed post-quantum migration from a research topic into a compliance requirement with a named algorithm, a published standard, and a government mandate timeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the standards actually say:&lt;/strong&gt; ML-DSA (Module-Lattice-Based Digital Signature Algorithm, formerly CRYSTALS-Dilithium) is the primary replacement for ECDSA in authentication contexts. It uses lattice-based mathematics (the Module Learning With Errors problem) that no known quantum algorithm can efficiently solve. ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism, formerly CRYSTALS-Kyber) replaces RSA key exchange in TLS and secure session establishment. SLH-DSA (Stateless Hash-Based Digital Signature Algorithm) provides a hash-based signature alternative with different performance characteristics suited to specific deployment contexts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it means for authentication:&lt;/strong&gt; Current FIDO2 passkeys use ES256 (ECDSA with SHA-256) as their signature algorithm. ES256 is quantum-vulnerable. The NIST finalization means the replacement algorithm (ML-DSA) is now standardized, the migration path is defined, and the question for every CIAM vendor is whether their platform supports algorithm substitution without re-enrolling users. According to DigiCert's analysis of the FIPS 204 guidance, NIST expects organizations to switch from RSA and ECC to ML-DSA by 2030.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prepare:&lt;/strong&gt; Audit every authentication component in your stack for its signature algorithm. Prioritize systems that handle long-lived credentials (passkeys, hardware tokens, PKI certificates) over short-lived session tokens. Verify that your CIAM vendor has a confirmed ML-DSA integration timeline, not just a vague "post-quantum roadmap." Ask specifically: "How will you migrate existing enrolled passkeys when you upgrade cryptographic primitives?" A vendor who can answer that question at the engineering level has done the work. One who responds with a slide about future commitments has not.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. IANA Adds PQC Algorithms to the COSE Codelist (April 2025): The Passkey Migration Path Is Now Specified
&lt;/h3&gt;

&lt;p&gt;On April 24, 2025, IANA officially added three quantum-resistant algorithms to the CBOR Object Signing and Encryption (COSE) codelist, providing the standards infrastructure that makes quantum-safe FIDO2 passkeys technically specifiable for the first time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this milestone matters:&lt;/strong&gt; COSE is the encoding format used by WebAuthn and FIDO2 to represent cryptographic operations. Without COSE algorithm identifiers for post-quantum schemes, it was impossible to specify quantum-safe passkeys in a standards-compliant way, even if an implementation wanted to use them. The IANA update closed this gap. As Wultra noted in their April 2025 analysis: as of April 24, 2025, three new quantum-resistant algorithms entered the COSE specification, "paving the way for a new generation of passkey-based authentication systems and security platforms, built around post-quantum Dilithium signatures."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it means for your stack:&lt;/strong&gt; The COSE update means the standards groundwork for quantum-safe passkeys now exists. It does not mean post-quantum passkeys are deployable in production today. Browser vendors, authenticator hardware manufacturers, and CIAM platforms all need to implement the new COSE algorithms before end-to-end quantum-safe passkey authentication is operational. The implementation timeline is estimated at 2-3 years from standards finalization. For security architects, the IANA update shifts the planning question from "will this ever be standardized?" to "when will our vendor implement this, and are we in a position to migrate without re-enrolling 10 million users?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prepare:&lt;/strong&gt; Review your CIAM vendor's COSE implementation roadmap. Confirm that their passkey architecture uses algorithm identifiers as configuration parameters rather than hardcoded values. That single architectural detail determines whether your migration is a configuration update or a credential re-enrollment campaign. &lt;a href="https://mojoauth.com/enterprise/" rel="noopener noreferrer"&gt;MojoAuth's enterprise CIAM platform&lt;/a&gt; is actively building post-quantum authentication support following the IANA COSE update, with ML-DSA integration aligned with NIST's 2024 PQC standards.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. FIDO2 Post-Quantum Extension Work: What the Roadmap Actually Looks Like
&lt;/h3&gt;

&lt;p&gt;The FIDO Alliance has begun scoping post-quantum extensions to the WebAuthn specification, and the roadmap is more concrete than most security architects realize, though the timeline requires proactive infrastructure preparation to navigate without disruption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the FIDO Alliance stands:&lt;/strong&gt; The FIDO Alliance's post-quantum working group is focused on two distinct problems. The first is algorithm substitution: replacing ES256 (ECDSA) with ML-DSA in the WebAuthn signing ceremony while maintaining backward compatibility with existing authenticators. The second is the authenticator hardware problem: physical security keys (YubiKey, Google Titan) contain cryptographic accelerators hardcoded for elliptic curve operations. Post-quantum algorithms require different hardware primitives, and hardware replacement cycles run 5-7 years for enterprise deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The hybrid approach:&lt;/strong&gt; The most practical near-term path is hybrid signatures, where both the classical (ECDSA) and post-quantum (ML-DSA) signatures are computed and verified together. This provides defense-in-depth: the authentication is secure against both classical and quantum attackers during the transition period. AWS KMS added ML-DSA support in 2025, offering three security levels (ML_DSA_44, ML_DSA_65, ML_DSA_87) for organizations that need quantum-safe signing operations in FIPS 140-3 certified HSMs. This infrastructure availability enables the server-side components of a hybrid passkey implementation even before browser and authenticator support is complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prepare:&lt;/strong&gt; Design your passkey enrollment infrastructure with algorithm agility as a first-class requirement. This means: storing the algorithm identifier alongside the public key in your credential database, using a CIAM platform that can update the signature algorithm per credential without requiring full re-enrollment, and planning your authenticator hardware refresh cycle to align with the FIDO Alliance post-quantum specification timeline. &lt;a href="https://mojoauth.com/blog/7-questions-ciso-passwordless-ciam-vendor" rel="noopener noreferrer"&gt;Review the questions every CISO should ask about post-quantum CIAM readiness&lt;/a&gt; before your next vendor evaluation or contract renewal.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. "Harvest Now, Decrypt Later" Enters Mainstream Threat Modeling: The Threat That Makes 2026 the Right Year to Act
&lt;/h3&gt;

&lt;p&gt;"Harvest now, decrypt later" (HNDL) is the attack pattern that transforms post-quantum authentication from a future concern into a present-day data protection obligation, and its formal entry into mainstream threat modeling by intelligence agencies and standards bodies has changed the migration calculus entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What HNDL actually means for identity data:&lt;/strong&gt; HNDL works in two phases. Phase one (today): adversaries intercept and store encrypted data, including authentication tokens, session keys, and identity assertions signed with RSA or ECDSA. Phase two (future, estimated within a decade): a cryptographically relevant quantum computer (CRQC) decrypts the stored data retroactively. The US Department of Homeland Security, UK NCSC, ENISA, and the Australian Cyber Security Centre all base their official post-quantum guidance on the premise that this harvesting is already occurring at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The identity-specific exposure:&lt;/strong&gt; Authentication data that is most vulnerable under HNDL includes: long-lived OAuth tokens and API keys with multi-year validity, PKI certificates for high-value service accounts, session tokens for privileged administrative access, and signed identity assertions exchanged between federated identity providers. Short-lived authentication credentials (single-use OTPs, passkey authentication assertions) have lower HNDL exposure because their value expires before decryption becomes feasible. This is one reason passkeys are more quantum-resilient than certificate-based authentication even before post-quantum algorithm migration: each authentication event produces a unique, ephemeral signature that's useless after the session ends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prepare:&lt;/strong&gt; Classify your identity infrastructure by data lifetime. Long-lived credentials (service account certificates, OAuth tokens with multi-year validity) are your highest HNDL exposure and should be prioritized in your post-quantum migration plan. Session tokens and passkey assertions are lower priority because their value expires rapidly. For an architectural overview of &lt;a href="https://mojoauth.com/ciam-101/quantum-resistant-cryptography-iam-passwordless-threat" rel="noopener noreferrer"&gt;how zero-store, quantum-resistant identity infrastructure addresses HNDL threats&lt;/a&gt;, that analysis covers the specific HNDL exposure scenarios for CIAM deployments. Immediately: move long-lived credentials to shorter validity periods and implement automatic rotation. This doesn't eliminate HNDL exposure, but it reduces the value of harvested data.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. First Quantum-Safe Government Identity Pilots (US, EU, Japan): The Template for Enterprise Migration
&lt;/h3&gt;

&lt;p&gt;The first quantum-safe government identity pilots, launched across the US, EU, and Japan between 2024 and 2026, provide the architectural templates and documented migration lessons that private sector organizations can apply directly to their own authentication infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;US progress:&lt;/strong&gt; OMB Memo M-23-02 directed federal agencies to inventory their cryptographic dependencies and develop post-quantum migration plans. CISA's post-quantum cryptography initiative has published migration guides for identity and access management specifically, identifying FIDO2 with ML-DSA as the target architecture for federal identity systems. The NSS compliance deadline of January 2027 means defense contractors and critical infrastructure operators with federal contracts face the earliest hard deadlines. NIST's National Cybersecurity Center of Excellence (NCCoE) ran a PQC migration demonstration project in 2024-2025 that included identity federation protocols, producing documented implementation patterns for hybrid TLS and signed assertion migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EU progress:&lt;/strong&gt; The European Union Agency for Cybersecurity (ENISA) published its post-quantum cryptography integration study in 2024, recommending a 2025-2027 planning horizon for organizations in critical sectors. The eIDAS 2.0 EUDI Wallet specification explicitly requires crypto-agile architecture, anticipating the transition to post-quantum algorithms. EU member states participating in EUDI Wallet pilots are building identity wallet infrastructure with post-quantum algorithm support in the design requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Japan's approach:&lt;/strong&gt; Japan's National Institute of Information and Communications Technology (NICT) completed a post-quantum government authentication pilot in 2025, using ML-DSA for identity assertion signing in a federated SSO environment. The pilot documented a 14-week migration timeline for a 50,000-user identity deployment, which provides a realistic planning benchmark for enterprise organizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prepare:&lt;/strong&gt; Review the NCCoE PQC migration documentation for identity federation patterns. Japan's 14-week pilot timeline is a useful lower-bound estimate for greenfield post-quantum migration; organizations with complex legacy identity stacks should plan for 6-18 months. Use government pilot architectures as procurement criteria: any CIAM vendor that cannot describe how their architecture aligns with the NCCoE migration patterns is behind the curve. Evaluate the &lt;a href="https://mojoauth.com/blog/10-must-have-features-to-evaluate-in-a-ciam-platform-in-2026" rel="noopener noreferrer"&gt;10 must-have CIAM platform features for 2026&lt;/a&gt;, which includes post-quantum readiness as a required evaluation criterion alongside phishing-resistant authentication and zero-PII architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Crypto-Agility Becomes a CIAM Buying Requirement: Modular Architectures Will Survive, Monoliths Won't
&lt;/h3&gt;

&lt;p&gt;Crypto-agility, the ability to replace cryptographic algorithms and key sizes without disrupting running systems or requiring user re-enrollment, has become the most consequential CIAM buying criterion of 2026, because it determines whether your authentication infrastructure can survive the post-quantum transition without a costly rebuild.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What crypto-agility means in practice:&lt;/strong&gt; A crypto-agile CIAM platform stores algorithm identifiers as configuration parameters, not hardcoded values in signing libraries. When NIST or FIDO Alliance updates the recommended algorithm, the platform can update the signing algorithm for new enrollments via configuration, run both old and new algorithms in parallel during a transition window, and migrate existing credentials to the new algorithm either lazily (on next authentication) or through a coordinated migration campaign. A non-crypto-agile platform requires a code change, a deployment, testing cycles, and potentially a full re-enrollment of all existing users to change its signature algorithm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The vendor selection test:&lt;/strong&gt; Ask every CIAM vendor you're evaluating this specific question: "If NIST deprecates ECDSA next year and mandates ML-DSA for all identity assertions, what would your migration process look like for our 5 million enrolled passkeys?" The answer reveals the architecture immediately. A vendor who describes a configuration-level migration understands the problem. A vendor who describes a "future migration path" or a re-enrollment campaign has not built algorithm agility into their core platform. According to the 7 questions every CISO should ask a passwordless CIAM vendor, a vendor who responds with "we'll address quantum when it becomes mainstream" fundamentally misunderstands the HNDL threat model, which makes this a current data protection decision, not a future one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The monolith vs. modular divide:&lt;/strong&gt; Identity platforms built on rigid cryptographic assumptions (Auth0's JWT library, for example, has historically been slow to add new algorithm support) face a harder migration path than platforms designed from inception with algorithm abstraction layers. This architectural divide is becoming a procurement differentiator as compliance teams understand the migration implications. &lt;a href="https://mojoauth.com/enterprise/" rel="noopener noreferrer"&gt;MojoAuth's enterprise platform&lt;/a&gt; is preparing quantum-resistant authentication using ML-DSA based on NIST-standardized Crystals-Dilithium, with FIDO2-compliant post-quantum cryptographic implementations that maintain compatibility with existing standards while protecting against quantum threats. The roadmap includes crypto-agile architecture at every layer of the authentication stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  2026-2028 Post-Quantum Migration Readiness Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist as your planning framework. Each item maps to a specific action your security architecture team should complete within the stated window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Immediate Actions (Complete by Q3 2026)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cryptographic inventory.&lt;/strong&gt; Map every place asymmetric cryptography is used in your identity stack: passkey signature algorithms (is it ES256?), JWT signing keys (RS256 or ES256?), TLS certificates for authentication endpoints, OAuth token signing, SAML assertion signing. This inventory is the foundation of your migration plan and is required by OMB M-23-02 for federal agencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vendor questionnaire.&lt;/strong&gt; Ask every identity vendor in your stack the following questions: "What is your ML-DSA integration timeline?" "How will you migrate existing enrolled credentials when you upgrade cryptographic primitives?" "Is your architecture crypto-agile, and what does that mean specifically for passkey algorithm migration?" "Do you have a documented HNDL threat model for the data you process?" Vendors who cannot answer these questions clearly are behind schedule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-lived credential audit.&lt;/strong&gt; Identify credentials with validity periods longer than 3 years (service account certificates, API keys, OAuth tokens with no expiration). These are your highest HNDL exposure. Begin shortening validity periods and implementing automated rotation immediately, regardless of where you are on the PQC migration timeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid TLS deployment.&lt;/strong&gt; Evaluate hybrid TLS configurations (combining classical and post-quantum key exchange) for your authentication endpoints. AWS, Azure, and GCP all have post-quantum TLS available. This addresses the data-in-transit component of HNDL exposure for authentication traffic without requiring changes to client authentication methods.&lt;/p&gt;

&lt;h3&gt;
  
  
  Near-Term Actions (Complete by Q2 2027)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NSS compliance for federal contractors.&lt;/strong&gt; If you hold federal contracts or operate national security systems, NSS compliance deadlines begin January 2027. Ensure your identity infrastructure can meet algorithm requirements. Engage your contracting officer on the specific algorithm requirements for your contract category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CIAM platform decision.&lt;/strong&gt; Make a definitive vendor evaluation decision based on post-quantum readiness criteria. Vendors should be able to confirm ML-DSA support timelines by mid-2026. Any vendor without a confirmed PQC roadmap by Q2 2027 is not an acceptable long-term choice for regulated industries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passkey enrollment infrastructure audit.&lt;/strong&gt; Verify that your passkey enrollment database stores algorithm identifiers alongside public keys. If your schema only stores the public key bytes without an algorithm field, your migration path requires a database schema change before algorithm substitution is possible. This is a cheap fix now; it's an expensive blocker during an active migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware authenticator planning.&lt;/strong&gt; Begin your hardware security key replacement cycle planning, incorporating post-quantum algorithm support as a device selection requirement. Hardware tokens deployed in 2026-2027 should have confirmed PQC firmware upgrade paths from the manufacturer, or plan for physical replacement within the 2027-2030 window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Longer-Term Actions (Complete by Q4 2028)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;FIDO2 post-quantum passkey pilot.&lt;/strong&gt; By late 2027 or early 2028, browser and authenticator vendors should have initial post-quantum FIDO2 support. Run a pilot deployment with a small user segment using ML-DSA passkeys before broad rollout. Document the enrollment and authentication performance characteristics for your specific user device mix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm migration execution.&lt;/strong&gt; Execute the credential algorithm migration for enrolled passkeys using your CIAM platform's crypto-agile migration tools. Target: all newly enrolled passkeys use ML-DSA; all existing passkeys migrated via lazy migration (on next authentication event) or active migration campaign.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance documentation.&lt;/strong&gt; Document your post-quantum migration completion for audit purposes. NIST's 2030 migration guidance, NSS deadlines, and eventual GDPR/DORA guidance on quantum-safe cryptography will all require evidence of migration completion. Maintain a migration log with algorithm deprecation dates, migration method, and completion metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is Post-Quantum Authentication and Why Does It Matter Now?
&lt;/h3&gt;

&lt;p&gt;Post-quantum authentication refers to authentication systems built on cryptographic algorithms designed to resist attacks from quantum computers. It matters now because of "harvest now, decrypt later" attacks, where adversaries collect encrypted identity data today with the intention of decrypting it once quantum computers are available. NIST finalized the first post-quantum standards in August 2024 (ML-DSA, ML-KEM, SLH-DSA), and US government agencies face compliance deadlines beginning January 2027 for national security systems. Organizations with long-lived sensitive data, such as those in finance, healthcare, and critical infrastructure, face HNDL exposure that starts today, not at Q-Day.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is ML-DSA and How Does It Replace ECDSA in Authentication?
&lt;/h3&gt;

&lt;p&gt;ML-DSA (Module-Lattice-Based Digital Signature Algorithm, FIPS 204) is NIST's standardized post-quantum digital signature scheme, formerly known as CRYSTALS-Dilithium. It replaces ECDSA (used in current FIDO2 passkeys as ES256) as the authentication signature algorithm. ML-DSA bases its security on the Module Learning With Errors (MLWE) mathematical problem, which no known quantum algorithm can efficiently solve. The trade-off relative to ECDSA is larger signature and public key sizes (2.4 KB and 1.3 KB respectively at the 128-bit security level), which requires storage and bandwidth adjustments in authentication infrastructure but is manageable with modern hardware.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does Crypto-Agility Mean for CIAM Platforms?
&lt;/h3&gt;

&lt;p&gt;Crypto-agility means the ability to replace or update cryptographic algorithms, including signature algorithms for passkeys and JWT tokens, without re-architecting the application layer or forcing user re-enrollment. In a crypto-agile CIAM platform, algorithm identifiers are stored as configuration parameters rather than hardcoded library dependencies. When NIST updates its recommendations, the platform can migrate to the new algorithm through configuration and a credential migration process rather than through a full re-deployment. Crypto-agility is the single most important architectural criterion for CIAM platform selection in the context of the post-quantum migration, because it determines whether your organization can migrate smoothly or must rebuild under pressure.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does "Harvest Now, Decrypt Later" Affect Authentication Infrastructure Specifically?
&lt;/h3&gt;

&lt;p&gt;HNDL affects authentication infrastructure by creating exposure for any long-lived cryptographic material that uses quantum-vulnerable algorithms. This includes: OAuth tokens with multi-year validity periods, PKI certificates for service accounts and federation endpoints, and signed SAML assertions stored in logs or audit trails. Short-lived credentials, such as passkey authentication assertions (which are session-specific and expire immediately) and single-use OTPs, have low HNDL exposure because their value expires before quantum decryption becomes feasible. The practical implication is that reducing credential lifetime and implementing aggressive token rotation is a meaningful HNDL mitigation that can be implemented today, before post-quantum algorithms are fully deployed.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Will Post-Quantum Passkeys Be Available in Production?
&lt;/h3&gt;

&lt;p&gt;The standards infrastructure for post-quantum passkeys is now in place following IANA's April 2025 COSE codelist update, which added ML-DSA algorithm identifiers for FIDO2. Browser vendors, authenticator hardware manufacturers, and CIAM platforms all need to implement these new COSE algorithms before end-to-end quantum-safe passkey authentication is fully operational. The implementation timeline is estimated at 2-3 years from the IANA update, pointing toward 2027-2028 for initial production deployments. Organizations should design their passkey enrollment infrastructure for algorithm agility now so they can adopt post-quantum passkeys as production support becomes available without requiring user re-enrollment.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are the NIST Migration Deadlines for Post-Quantum Cryptography?
&lt;/h3&gt;

&lt;p&gt;According to NIST's published transition guidance and DigiCert's analysis of FIPS 204, organizations should plan to switch from RSA and ECC to ML-DSA and related algorithms by 2030. After 2035, quantum-vulnerable cryptographic algorithms will be prohibited for US government agencies. NSS (National Security Systems) compliance deadlines begin January 2027, creating earlier hard deadlines for defense contractors and critical infrastructure operators with federal contracts. NIST has stated that "harvest now, decrypt later" attacks make this a present-day risk, explicitly warning about long-term confidentiality risks tied to quantum computing and recommending that organizations begin migration planning immediately rather than waiting for quantum computers to become widely available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The six milestones covered in this guide are not predictions. They are completed events (NIST standardization, IANA COSE update), active developments (FIDO2 post-quantum extension work, government identity pilots), and present-day threats (HNDL) that are reshaping the identity security landscape right now. The organizations that emerge from the post-quantum transition without a major authentication incident will be those that treated crypto-agility as a procurement requirement in 2026, not those that started planning after their algorithms were deprecated. The window to make this a smooth transition rather than a crisis migration is open. It won't stay open.&lt;/p&gt;

&lt;p&gt;Ready to assess your authentication stack against the post-quantum migration checklist? &lt;a href="https://mojoauth.com/white-papers/passkeys-passwordless-authentication-handbook/" rel="noopener noreferrer"&gt;Download the MojoAuth Passkeys and Passwordless Authentication Handbook&lt;/a&gt; for the full post-quantum readiness framework, or &lt;a href="https://mojoauth.com/enterprise/" rel="noopener noreferrer"&gt;explore MojoAuth's enterprise post-quantum authentication roadmap&lt;/a&gt; to understand exactly where your CIAM infrastructure stands against the migration timeline.&lt;/p&gt;

</description>
      <category>postquantumauthentic</category>
      <category>quantumsafecryptogra</category>
      <category>fido2postquantum</category>
      <category>postquantumciam</category>
    </item>
  </channel>
</rss>
