Skip to content

WebAuthn and passkeys

WebAuthn (Web Authentication) is the W3C standard for phishing-resistant credentials in browsers. Passkeys are the consumer-friendly name for the same technology, with some additional sync behaviour. From your code's perspective, the two are the same — WebAuthn is the protocol, passkey is the marketing term.

Why it matters: WebAuthn is the strongest authentication factor the platform supports. The credential cryptographically binds to the domain it was registered against; an attacker who phishes the user to cymmetri-spoofed.com can't get the credential to sign for them — the browser refuses. This defeats most credential-theft attacks at the protocol level, not by guessing the password but by removing the password entirely.

When a user enrolls a WebAuthn credential:

  1. Your tenant tells the user's browser "I'd like to register a new credential."
  2. The browser asks the user to confirm — Touch ID, Face ID, Windows Hello, or by tapping a hardware key.
  3. The user's authenticator generates a new key pair specific to your tenant + user.
  4. The public key is sent to the platform; the private key stays on the user's device.
  5. The platform records the credential alongside the user's identity.

When the user signs in with that credential:

  1. The platform sends a random challenge to the browser.
  2. The browser asks the user to confirm — same Touch ID, Face ID, etc.
  3. The user's authenticator signs the challenge with the private key.
  4. The signature is sent to the platform, which verifies it against the stored public key.

The private key never leaves the device. There's no shared secret to leak; phishing sites can't extract the credential.

Both terms describe the same protocol. The differences are about how the private key is stored:

  • Non-discoverable WebAuthn (older usage). The private key lives only on the device where it was created. Lose the device, lose the credential.
  • Passkeys (newer term). The private key is synced across the user's devices via their platform's cloud (iCloud Keychain, Google Password Manager, 1Password, etc.). A passkey enrolled on the user's iPhone is automatically available on their iPad and Mac.

The protocol bits IntelliAuth handles are identical for both. The user-experience difference is that passkeys feel "lighter" — the user doesn't need to re-enroll on every device, because the credential follows them.

The SDK + platform handle:

  • The WebAuthn ceremony (challenge generation, response verification, replay protection).
  • Platform compatibility shims (older browser quirks, iOS Safari WebKit nuances).
  • Authenticator metadata (knowing that a YubiKey 5 is a hardware key, that Touch ID is a platform authenticator).
  • Credential storage on the IntelliAuth side.

You write:

  • The button or UI that triggers enrollment ("Set up Touch ID" → useIntelliAuth().startMfaEnrolment('webauthn')).
  • The button or UI that triggers a challenge if you're using WebAuthn as primary auth ("Sign in with passkey" → useIntelliAuth().loginWithPasskey()).
  • Error handling for the few cases where the ceremony fails (user denied, no authenticator available, etc.).

Two common deployment patterns:

  • As a secondary factor (alongside password). Users sign up with email+password; once signed in, they can add WebAuthn for stronger sign-in next time. This is the gradual-adoption path; most apps start here.
  • As a primary factor (passwordless). Users sign up by registering a passkey directly. No password is ever set. Stronger, simpler — but requires the user to have a compatible device.

The second pattern is the future direction of the web. If you're building a new app today and your users are likely on modern devices, prefer passwordless-with-passkeys. Fall back to email+password for users whose devices don't yet support passkeys.

As of 2026, WebAuthn is in every modern browser. Passkey sync (the cross-device experience) is in:

  • iOS 16+ / macOS Ventura+ (iCloud Keychain).
  • Chrome on Android (Google Password Manager).
  • Chrome / Edge on desktop with a synced Google account.
  • 1Password, Dashlane, Bitwarden as third-party syncers.

Hardware keys (YubiKey, Titan) work on every browser that supports WebAuthn — no sync needed; the credential lives on the key itself.

For users on older browsers or unusual configurations, your app should keep a fallback (email + password, magic link, SMS) so they don't get locked out.

Every WebAuthn sign-in lands in the tenant audit log with amr: ['webauthn']. Useful for compliance reports — "what fraction of our sign-ins this month used phishing-resistant authentication?" is a single query against the audit feed.