Skip to content

Passkey Authentication

The authentication section of the quickstart guide covers the basics, so we’ll focus on some more advanced aspects of passkey authentication here.

Similar to the registration flow, you probably want to test for passkey support during authentication, or at least handle the potential error.

User verification is especially useful during authentication:

// discouraged, preferred (default) or required
const userVerification = "required" as const;
const result = await authenticatePasskey({ tenancyId, userVerification });

You should also check the passkey.userVerified property of the resulting Principal in your backend code:

const principal = await exchangeCodeUnsafe({ ... })
if (principal.passkey?.userVerified !== true) {
throw new Error("Try again")
}

For more information see the dedicated user verification guide.

To preselect the passkey(s) presented to the user, pass the ids via the allowCredentials option:

const allowCredentials = [existingPasskeyId]
const result = await authenticatePasskey({ allowCredentials, ... })

This is conceptually similar to the exludeCredentials registration option.

If the user is already logged into their account, or they have presented a username/email in a two step login flow, you can help them out by preselecting the passkey they should use to authenticate.

Given that you already know their local user id (or claimed user id), you can lookup the passkeys associated with the account and pass them to authenticatePasskey.

This avoids the scenario in which a user is signed into your system using one account, then tries to re-authenticate using a passkey associated with a different acccount.

Imagine you’re signed into GitHub using your work account, and you want to perform some operation. GitHub asks for your passkey and you accidentally select your personal key. You’ll get a weird error and wonder what’s happened.