All releases
Feature

Passkeys — Face ID, Touch ID and security keys in your app

Auth now supports WebAuthn passkeys: your end-users can sign in with Face ID, Touch ID, Windows Hello or a hardware key — either as a second factor or on their own, with no password at all. Turn it on per app under App settings → Passkeys.

A passkey is a key pair the user's device creates and keeps. The private half never leaves the authenticator, there is nothing to phish, and nothing for you to store beyond a public key. Auth verifies the ceremony itself, so your app never handles the cryptography.

Your end-users can now:

  • Add a passkey as a second factor alongside a password, from /:app/v1/me/mfa — the same place TOTP and email codes live.
  • Sign in with a passkey alone. POST /:app/v1/auth/passkey/options then /verify mints a session with no password step. The options endpoint takes no email address on purpose: an endpoint that answered differently for a registered and an unregistered address would tell an anonymous caller whether an account exists. Discoverable credentials mean the authenticator finds its own passkey, so it never needs to be told.
  • Step up into a sensitive action with a passkey they already registered.

Passwordless sign-in always requires the user to be verified by the authenticator — a biometric or a PIN, not just a tap. When a passkey is the only credential, “someone is holding this key” is not an authentication. For second-factor ceremonies that requirement is yours to set.

Turning it on

Open your app in the console, go to Settings → Passkeys, and set the relying-party id: the bare domain your users sign in on (example.com, which also covers app.example.com). It must cover one of the app's allowed redirect origins — the page shows you which origins a ceremony would be accepted from, and warns you when the answer is “none”, which is the one misconfiguration that otherwise only shows up as a failed sign-in.

One thing worth knowing before you pick that domain: the relying-party id is part of every passkey. It is hashed into each credential at registration. Changing it later does not turn those passkeys off — it makes all of them fail verification, which looks to your users like their passkey stopped being trusted. Auth refuses the change while any passkey exists, and the console says so before you try.