The userHandle read-only property of the AuthenticatorAssertionResponse interface is an ArrayBuffer object which is an opaque identifier for the given user. Such an identifier can be used by the relying party's server to link the user account with its corresponding credentials and other data.
The same value may be found on the id property of the options.user object (used for the creation of the PublicKeyCredential instance).
User Handle
The user handle is specified by a Relying Party, as the value of user.id, and used to map a specific public key credential to a specific user account with the Relying Party. Authenticators in turn map RP IDs and user handle pairs to public key credential sources.
A user handle is an opaque byte sequence with a maximum size of 64 bytes. User handles are not meant to be displayed to users. The user handle SHOULD NOT contain personally identifying information about the user, such as a username or e-mail address; see §14.9 User Handle Contents for details.
Which makes userHandle the opaque user_id, not the username.
This is also evidenced by the userHandle response I receive from navigator.credentials.get() exactly matching the opaque userID I passed into navigator.credentials.create().
In the
WebAuthnAssertionResponse
.verify()
function, theassertion_response.userHandle
attribute is incorrectly compared against thewebauthn_user.username
instead ofwebauthn_user.user_id
: https://github.com/duo-labs/py_webauthn/blob/4a0f8cd1db3b7635a1951a933d5a690beedf7c50/webauthn/webauthn.py#L890Per https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAssertionResponse
.userHandle
is:Also confirmed by https://www.w3.org/TR/webauthn/#user-handle:
Which makes userHandle the opaque user_id, not the username.
This is also evidenced by the
userHandle
response I receive fromnavigator.credentials.get()
exactly matching the opaque userID I passed intonavigator.credentials.create()
.