Building a working passkey prototype on a local development machine takes less than an afternoon. You import a WebAuth helper library, wire up a biometric prompt on your MacBook, watch Touch ID log you in within three hundred milliseconds, and immediately feel ready to delete passwords from your database forever. That engineering euphoria evaporates the moment you prepare to roll out that exact flow to fifty thousand real production users who access your platform from aging Android phones, locked-down corporate Windows laptops, and in-app social media browsers. When we migrated our core authentication engine to support passkeys, we quickly discovered that the cryptographic math is the easy part, while preserving a frictionless login user experience across fragmented device ecosystems is where most production migrations fail.
Why Dedicated Passkey Buttons Confuse Real Users
Our first staging prototype followed the naive pattern you see in most technical tutorials by placing a prominent new button labeled Sign in with a Passkey right below the traditional email and password form. When we ran usability tests with a small cohort of non-technical customers, the results were sobering. Users who had never created a passkey clicked the shiny new button out of curiosity, got hit with a confusing operating system modal complaining that no credentials were found on their device, and assumed our login page was broken. Even worse, users who had previously registered a passkey on their mobile phone tried clicking that same button on their desktop computer, triggering awkward cross-device QR code prompts they did not understand how to complete.
Saving our conversion rate meant abandoning the separate button paradigm entirely and embracing WebAuth Conditional Mediation, commonly known as passkey autofill. Instead of forcing the user to remember how they previously configured their account security, we unified the entry point into a single, familiar identifier input field decorated with the webauthn autocomplete attribute.
Wiring conditional mediation into the mount lifecycle of the login input completely eliminated user hesitation. The moment a returning user taps the email field, the browser quietly checks if a matching passkey exists in the local device enclave or synced keychain. If a credential is present, the native biometric prompt appears right inside the keyboard autofill suggestion bar alongside their saved usernames, allowing them to authenticate with a single fingerprint tap. If the current device has no passkey available, nothing blocks the screen and the user simply continues typing their email address to proceed with their normal authentication method.
Modeling Multi-Device Credentials and Replay Protection in PostgreSQL
Supporting fifty thousand users in production also required rethinking how we modeled identity credentials in our database schema. A common mistake during early WebAuthn adoption is treating a passkey like a one-to-one replacement for a password column on the users table. In reality, a single user often accumulates multiple cryptographic key pairs across different ecosystems, such as one synced passkey inside iCloud Keychain for their Apple devices and a separate hardware-bound passkey on a Windows workstation.
To prevent users from getting locked out when switching machines, we designed a dedicated one-to-many passkey credentials table using Drizzle ORM that stores the raw public key alongside device transport hints and a strictly incrementing signature counter. Tracking the transports array is critical for user experience because returning those exact transport hints during authentication tells the browser whether it can immediately invoke an internal platform sensor like Face ID or whether it needs to offer a hybrid Bluetooth cross-device bridge.
Separating the cryptographic state into its own indexed table also allowed us to enforce strict replay protection inside our verification Server Actions. Every time a user signs a challenge, our backend verifies the cryptographic assertion against the stored publicKey and compares the incoming signature counter against the value stored in PostgreSQL. If a hardware authenticator reports a counter lower than or equal to the previous login, our system immediately flags a potential cloned key anomaly and revokes that specific credential without disrupting the rest of the user's registered devices.
Post-Login Progressive Nudges Over Forced Enrollment
The final piece of the migration puzzle was figuring out how to get fifty thousand existing users to actually register a passkey without annoying them. Early in our rollout, we tested an interstitial modal that interrupted users immediately when they opened the login page, asking them to set up a passkey before signing in. Nearly eighty percent of users dismissed the prompt immediately because they were in a hurry to check an order or complete a transaction, and asking someone to perform a secondary verification step before they have even logged in creates unnecessary cognitive friction.
We flipped that sequence on its head by moving enrollment exclusively to the post-authentication phase. After a user successfully signs in using their existing password or one-time verification code, we know two vital facts with certainty. First, their session is already freshly authenticated, so we do not need to challenge them again. Second, we can inspect their browser capabilities in the background to verify that their current device actually supports local biometric hardware before showing a single pixel of UI. By presenting a non-intrusive bottom sheet right after a successful login that offers one-tap biometric upgrades for future visits, our opt-in enrollment rate jumped past sixty-five percent within the first month.
Treating Authentication as an Evolving Spectrum
Migrating fifty thousand accounts to WebAuthn taught us that passwordless authentication is not a binary switch you flip overnight. Even with high passkey adoption, users will still lose their phones, borrow a friend's laptop, or open links inside restricted webviews that block native credential managers. By combining conditional autofill inputs, multi-credential database schemas, and silent fallbacks to instant verification codes, we delivered the speed and phishing resistance of hardware cryptography without leaving a single user stranded at the login screen.