Skip to main content

2FA FIDO2 & U2F (WebAuthn)

The Web Authentication Browser API (also known as WebAuthn) is a specification written by the W3C and FIDO. The WebAuthn API allows servers to register and authenticate users using public key cryptography instead of a password. WebAuthn is commonly used with

  • a USB, NFC, or Bluetooth low energy device (e.g. YubiKey) to authenticate;
  • using an Operating System "platform module" (e.g. TouchID, FaceID, Windows Hello Face, Android Biometric Authentication, ...);

Once the end-user triggers the WebAuthn process, the browser will show a WebAuthn prompt which looks different per browser:

WebAuthn Prompt

Ory's WebAuthN implementation can be used for both multi-factor authentication and passwordless authentication. You need to configure whether WebAuthn is used for passwordless, or for multi-factor authentication.


WebAuthn needs to be configured and is disabled per default.


Once passwordless is set to either true or false, avoid changing it. Doing so may lock some users out of their accounts.

ory patch identity-config <your-project-id> \
--add '/selfservice/methods/webauthn/enabled=true' \
--add '/selfservice/methods/webauthn/config/passwordless=false' \
--add '/selfservice/methods/webauthn/config/rp/display_name="My Display Name"'

(Custom) Identity Schema

All Ory presets have the correct settings for WebAuthn enabled.

If you want to use a custom identity schema, you need to define what field of the identity schema is the primary identifier for WebAuthn. This is used for both multi-factor authentication as well as passwordless:

$schema: '',
type: 'object',
properties: {
traits: {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
title: 'Your E-Mail',
minLength: 3,
'': {
credentials: {
// ...
webauthn: {
identifier: true
// ...
// ...
// ...

Identity Credentials

The webauthn method would generate a credentials block as follows:

id: webauthn
- # The name shown in the UI for the eky
display_name: my-key
# When the keay was added
added_at: '2022-03-06T09:45:18Z'
# If true, is a credential used for passwordless flows.
is_passwordless: false
# WebAuth2-specific values.
id: P/psShpG+SOCxBqslynuxMors6oexs7RS09bSA/F9EI=
public_key: pQECAyYgASFYIJ0RRsaHJ2IQ6Eh11BPpHkdOl2DkICXg3rJVxSHQAsklIlgga0Tt2PqLlg/baAl20Y64JCllE71jDG+XzHfN6FT/S9I=
attestation_type: none
sign_count: 1
clone_warning: false

# The user handle will be used in the exchange with the FIDO2 device
# to ensure that the user handles from the key and from Ory match.
user_handle: NDVP4/1nTj2CTFaItp/zXg==