How userVerification works in WebAuthn

userVerification is an optional WebAuthn parameter that lets a relying party (RP) express how strongly it wants to confirm a user's identity during passkey creation or authentication. The response to a request contains a UV flag in the authenticator data that reports whether user verification was actually performed.

User presence vs. user verification

Passkeys rely on public key cryptography. When a passkey is created, a public-private key pair is generated: the private key stays with the passkey provider, and the public key goes to the RP's server. Authentication succeeds when the server verifies a signature from the passkey using the stored public key.

Two flags in the authenticator data describe what happened on the device:

  • UP (user presence): proves someone interacted with the device during authentication.
  • UV (user verification): asserts that the correct person was present, not just any person. On smartphones, this typically uses the screen-lock mechanism — a biometric, PIN, or password.

Both flags travel to the server in the authenticator data field. During authentication, the server validates this field by checking the signature against the stored public key; a valid signature means the flags can be trusted.

The three userVerification values

Per the WebAuthn specification, the RP can pass a userVerification parameter on both credential creation and assertion. It accepts one of three values:

  • 'preferred' (default): user verification is preferred but can be skipped if unavailable. The UV flag in the response is true if verification was performed, false if not.
  • 'required': a user verification method must be invoked. If none is available, the request fails locally, so the response credential always carries a UV flag of true.
  • 'discouraged': user verification should be avoided when possible. Depending on the device, it may still happen, and the UV flag can contain either true or false.

Sample code for passkey creation:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

Sample code for passkey authentication:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

Choosing a value for your application

When to use 'preferred'

Choose userVerification='preferred' when user experience outweighs protection. In environments where a verification method isn't available, the friction of an alternative can drive users away. On macOS without Touch ID — because the hardware doesn't support it, it's disabled, or the device is in clamshell mode — the browser may ask for a system password instead, which is cumbersome. With 'preferred', the user can skip verification entirely in that case.

The resulting UV flag becomes a useful signal for risk analysis. When the sign-in attempt appears risky for other reasons and the UV flag is false, the RP can choose to escalate with additional challenges.

When to use 'required'

Use userVerification='required' when you need certainty that both UP and UV occurred. The trade-off is added friction for the user. On the same macOS example, a user without Touch ID must enter their system password to complete the request. The server should verify the UV flag is true, which is guaranteed by this option.

Server-side validation

On passkey registration and authentication, the server checks the UP and UV flags according to its requirements. Because the authenticator data is signature-validated, a true value for either flag is a genuine signal from the authenticator, not something an attacker can forge without the private key.

User verification helps passkey-relying parties assess whether the device owner is truly present during a sign-in. Whether to require it or keep it optional depends on how much friction the fallback mechanism adds to the user flow — but the server must always inspect both the UP and UV flags before treating an authentication as successful.