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 istrueif verification was performed,falseif 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 oftrue.'discouraged': user verification should be avoided when possible. Depending on the device, it may still happen, and the UV flag can contain eithertrueorfalse.
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.



