---
url: 'https://www.corbado.com/blog/webauthn-user-id-userhandle'
title: 'WebAuthn User ID, User Handle, User Name & Credential ID'
description: 'Understand WebAuthn User ID, User Name, User Display Name, User Handle and Credential ID in Passkey applications and get advice for implementation.'
lang: 'en'
author: 'Vincent'
date: '2023-12-14T00:00:00.000Z'
lastModified: '2026-03-27T07:00:37.694Z'
keywords: 'user id, user handle, webauthn user name, credential id, user handle'
category: 'WebAuthn Know-How'
---

# WebAuthn User ID, User Handle, User Name & Credential ID

## Key Facts

- **User ID (user.id)** must never be an email address or phone number since these can
  change or be reassigned, causing broken authentication for affected users.
- The **User Handle (response.userHandle)** returned during authentication equals the User
  ID set at registration, enabling the server to identify the user account.
- **User Name (user.name)** is the unique login identifier shown in browser prompts and
  password managers; User Display Name is cosmetic and not used for authentication.
- Authenticators store only one **discoverable credential** per User Handle per relying
  party, per WebAuthn RFC 5.4.3, limiting how many passkeys one account holds per device.
- **ExcludeCredentials** operates solely on Credential IDs and does not interact with User
  ID, User Name or User Display Name during the registration ceremony.

## 1. Introduction

Passkeys and the underlying WebAuthn protocol form the new standard of secure and user
friendly authentication for web and native apps. To securely and efficiently implement
passkeys-based authentication, its of utmost importance to understand the details of
**user IDs, user names, display names, user handles, and credential IDs** in this context.
These elements play an important role and can easily be misunderstood causing large
efforts to fix them if they were initially implemented the wrong way.

This blog post should help developers and product managers alike to better understand what
these specific terms (**WebAuthn Credential ID, User ID, User Handle, User Display Name,
User Name**) mean, how they differ, what makes it challenging and whats the
industry-recommended way of implementing them.

Our focus here is not merely on definitions but on the relationships and operational
complexities these terms entail. Why is understanding the difference between a '**User
Name**' and a '**User Display Name**' more than an academic exercise? How does the choice
of a '**User Handle**' affect the privacy and security of your users? These are the
questions we aim to answer.

In a field marked by rapid innovation and technical intricacies, staying ahead means not
only keeping pace with current trends but also anticipating future developments.

Let's embark on this journey together, unraveling the complexities, understanding the
challenges, and embracing the innovations in the world of WebAuthn and passkey
applications.

## 2. Understanding the WebAuthn Terminology

![overview webauthn identifiers](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_identifiers_7a4cc65b02.png)

Understanding the different terms is very important. In the following, we explain in more
depth and also use a practical example situation to make things more tangible.

**Example situation:**

Lets say you want to create a new account at a passkey-enabled website. Your real name is
**John Doe (fullName)** and your email address is
**[john.doe@mail.com](mailto:john.doe@mail.com)** **(loginEmail)**. The website is
accessible at **[https://www.acme.com](https://www.acme.com)** and it requires to sign-up
with an email address, so that they can send you more emails regarding their product.

Assume that the very simplified backend database would look like this, storing all users
in user and all passkeys in passkey table:

![Passkey User Credential Table Scheme](https://www.corbado.com/website-assets/657c892cfe5e08d90bf9e945_table_passkey_user_d3511637c4.png)

In brackets we added which WebAuthn ceremony field corresponds to which database field.
Keep in mind that a lot of relevant fields are missing, as this scheme is just to explain
the relationship of the most important values: credentialId, user.id, user.name,
user.displayName and response.userHandle.

Additionally, the following JSON shows a response during an authentication (login)
ceremony that is sent from the [authenticator](https://www.corbado.com/glossary/authenticator) to the
[relying party](https://www.corbado.com/glossary/relying-party):

```json
{
    "id": "5W2vmAU1Mg5vkwzkxRNMdEZwnbrietMwFPdayOdpGkA",
    "rawId": "5W2vmAU1Mg5vkwzkxRNMdEZwnbrietMwFPdayOdpGkA",
    "type": "public-key",
    "response": {
        "authenticatorData": "t8DGRTBfls-BhOH2QC404lvdhe_t2_NkvM0nQWEEADcFAAAAAQ",
        "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiRUdZdEFNZ2k4QjJFeTFGTlZmVkY5M201TEV6X0Nmd1R5MDBXMnpvUEVONCIsIm9yaWdpbiI6Imh0dHBzOi8vb3BvdG9ubmllZS5naXRodWIuaW8iLCJjcm9zc09yaWdpbiI6ZmFsc2V9",
        "signature": "Dei3zdjUf9oOcwuaxLc9y0zGfKvP9WHLqH3lInnxPPYsCkG_bs8bI-YjIWMHvlLkYua9RUajvK6qmbW8WiVLBlZ89a9Yy_XLCbSEyrUFjAyq_-awNeBObNRZ5woMIf1ntg8eH2O2HgvDuj1yk9u4WVbp93yZPX3e7NiCJ9d9i-wImNzIdnGN1ujX814fL9o3fys1vWSA6U8y4bvzgOk1Y58Bi7T6NpCI0ar7u73JsXEaDnexfBi1UooqOyfExyhRD4DeB5lk5kLVI_ONqcSfUASxgrjzHIoF5IsnV0cOlP7P3tKqtHCKcNd1JIknifp9tTy1EhFek4KBid-M8D8NAQ",
        "userHandle": "d2luZG93cyAxMSBjaHJvbWUgMTIw"
    },
    "authenticatorAttachment": "platform"
}
```

### 2.1 What's the WebAuthn Credential ID?

![overview webauthn credential id](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_credential_id_7adbeb5df3.png)

The WebAuthn **Credential ID** is a unique ID generated by the
[authenticator](https://www.corbado.com/glossary/authenticator) (e.g. your smartphone, laptop or hardware
[security key](https://www.corbado.com/glossary/security-key) like [YubiKey](https://www.corbado.com/glossary/yubikey)) during the
registration (sign-up) process of a new credential (passkey). This **Credential ID** is
required for passkey authentication, as it is used to distinguish individual credentials
(passkeys). Each **Credential ID** is exclusive to a specific credential (passkey).

#### 2.1.1 Credential ID of Resident Keys (Discoverable Credentials)

In case of [resident-keys](https://www.corbado.com/glossary/resident-key) (discoverable credentials), the
**Credential ID** is stored by the [authenticator](https://www.corbado.com/glossary/authenticator). When a user
attempts to authenticate, the authenticator provides the **Credential ID** to the
[relying party](https://www.corbado.com/glossary/relying-party) to indicate which credential (passkey) is being
used. Moreover, theres a limit: at most one
[discoverable credential](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys)
per User ID (`user.id`) per [relying party](https://www.corbado.com/glossary/relying-party) can be stored.

#### 2.1.2 Credential ID of Non-Resident Keys (Non-Discoverable Credentials)

In case of non-resident keys (non-discoverable credentials), the **Credential ID** is
stored by the relying party server. When a user attempts to authenticate, the user needs
to manually select the **Credential ID** in a dialogue of the relying party. If just one
non-[resident key](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys) is
available, this one will be sent to the client.

**Example:** "5W2vmAU1Mg5vkwzkxRNMdEZwnbrietMwFPdayOdpGkA"

**Can it be changed?:** No

**Pre-defined format:** No

**Suggested value:** Given by authenticator

### 2.2 What's the WebAuthn User ID (user.id)?

![overview webauthn user id](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_user_id_dedf093371.png)

The WebAuthn **User ID (`user.id`)** is an ID specified by the relying party (RP) to
represent a user account within their system. In the context of passkeys, the **User ID
(`user.id`)** plays a crucial role in linking a particular user with their credentials
(passkeys).

During the registration process, the RP provides the **User ID (`user.id`)** to the
authenticator, which then binds this **User ID (`user.id`)** to the newly created
credential (passkey). This binding is essential for the authenticator to differentiate
between different users credentials (passkeys), especially in multi-user environments. The
**User ID (`user.id`)** should be unique for each user within the context of the RPs
system and is therefore the same for all registered credentials (passkeys), ensuring a
consistent and secure user identification process throughout the authentication lifecycle.

**Example:** d2luZG93cyAxMSBjaHJvbWUgMTIw

**Can it be changed?:** No

**Pre-defined format:** No

**Suggested value:** Primary key of user in RPs system (unique ID, UUID, autoinc)

### 2.3 What's the WebAuthn User Handle (response.userHandle)?

![overview webauthn user handle](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_user_handle_0cea979e5e.png)

The **User Handle (`response.userHandle`)** , is another critical piece in passkey
authentication. It is chosen by the relying party and is meant to represent the user
account within their system.

The **User Handle (`response.userHandle`)** is returned in the response of the
authenticator which is sent back to the relying party. It is equal to User ID (user.id).
Thats why it is called User ID (`user.id`) when the user is created on the relying party
server but when the authenticator responds, it sets the **User Handle
(`response.userHandle`)** to the value of User ID (user.id).

The **User Handle (`response.userHandle`)** is associated with the credentials (passkeys)
registered by a user and, for resident keys (discoverable credentials), is stored by the
authenticator.

Its primary function is to enable the authenticator to map a set of credentials (passkeys)
to a specific user account. Unlike the Credential ID, the **User Handle
(`response.userHandle`)** is not necessarily unique as multiple Credential IDs can be
associated with the same **User Handle (`response.userHandle`)**.

A secondary use of the **User Handle (`response.userHandle`)** is to allow
[authenticators](https://www.corbado.com/glossary/authenticator) to know when to replace an existing
[resident key](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys)
(discoverable credential) with a new one during the registration ceremony. In this
context, [excludeCredentials](https://www.corbado.com/glossary/excludecredentials) can be used to prevent the
replacement of existing credentials (passkeys). Specific error messages are shown if the
[excludeCredentials](https://www.corbado.com/glossary/excludecredentials) list matches any of the locally on the
authenticator available credentials (passkeys). However, even in this matching case, the
WebAuthn registration ceremony is still triggered (meaning that the
[Face ID](https://www.corbado.com/faq/is-face-id-passkey), Touch ID or [Windows Hello](https://www.corbado.com/glossary/windows-hello)
popup appears). The reason why this popup appears, even though it fails in the matching
case, is that for privacy reasons, the user needs to successfully sign the challenge
before the authenticator and relying party tell the users that there is already a
credential (passkeys).

**Example:** d2luZG93cyAxMSBjaHJvbWUgMTIw

**Can it be changed?:** No

**Pre-defined format:** No

**Suggested value:** Primary key of user in RPs system (unique ID, UUID, autoinc)

### 2.4 What's the WebAuthn User Display Name (user.displayName)?

![overview webauthn user displayname](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_user_displayname_ea2a1f4595.png)

The WebAuthn **User Display Name (`user.displayName`)** is a user-friendly, readable name
chosen by the user during the registration process. This name is typically used for
display purposes within the application interface and is not used for authentication.

The primary purpose of the **User Display Name (`user.displayName`)** is to enhance the
user experience by providing a recognizable and human-readable identifier for the user,
which can be their real name, a nickname, or any other preferred designation. It's
important for developers and product managers to note that the **User Display Name
(`user.displayName`)** is for convenience and personalization and should not be relied
upon as a secure identifier for authentication processes.

It's recommended that the relying party should not restrict the users choice for **User
Display Name (`user.displayName`)** more than necessary.

**Example:** John Doe

**Can it be changed?:** Yes

**Pre-defined format:** No

**Suggested value:** Full given and family name

### 2.5 What's the WebAuthn User Name (user.name)?

![overview webauthn user name](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/overview_webauthn_user_name_1793d1c243.png)

The WebAuthn **User Name (`user.name`)** serves to distinguish between user accounts,
particularly in scenarios where multiple accounts might have similar or identical User
Display Names (`user.displayName`). It is a unique ID within the RP's system, and unlike
the **User Display Name (`user.displayName`)** , it is used in the authentication process.
The **User Name (`user.name`)** can be an email address, a specific username, or any other
form of unique ID chosen by the user or assigned by the system.

In the context of passkeys, the User Name (`user.name`) is crucial for linking a specific
user account to its credentials (passkeys) and for ensuring the integrity of the
authentication process, especially when dealing with user accounts that share similar User
Display Names (`user.displayName`).

**User name (`user.name`)** can be arbitrary strings, not necessarily only email
addresses, phone numbers or usernames.

**Example:** [john.doe@mail.com](mailto:john.doe@mail.com)

**Can it be changed?:** Yes

**Pre-defined format:** No

**Suggested value:** Primary identification (most likely email)

### 2.6 Overview of Storage Requirements and Authenticator Limits

The following table outlines a short summary which storage requirements for the RP
database should be taken into account together with the storage limitations of
[authenticators](https://www.corbado.com/glossary/authenticator).

![WebAuthn Relying Party Database Authenticator Limits](https://www.corbado.com/website-assets/657c893ac5be48cc01b148c7_webauthn_storage_requirements_authenticator_limits_5fe3951a04.png)

### 2.7 FAQ

#### 2.7.1 Can the User ID be Empty or "NULL"?

Technically, the WebAuthn specification does not explicitly forbid a NULL value for
user.id (empty values are forbidden though). However, in practice, it's highly recommended
to use a non-NULL User ID (`user.id`). This is because the User ID (`user.id`) is intended
to uniquely identify a user on the server. A NULL value would not serve this purpose and
could lead to ambiguities or security issues.

**Implications for Resident Keys (Discoverable Credentials):**

These are stored on the authenticator and can be used to authenticate a user without prior
knowledge of the User ID (`user.id`). However, the User ID (`user.id`) is still important
as it allows the server to identify the user once the Credential ID is presented.

**Implications for Non-Resident Keys (Non-Discoverable Credentials):**

These require the user to be authenticated first. In this case, the User ID (`user.id`)
helps the server to fetch the correct Credential ID and public key for the user to
complete the authentication process and return the Credential ID.

In summary, while it might be technically possible to have an empty User ID (`user.id`),
it is not advisable due to the potential for confusion and security implications. The User
ID (`user.id`) plays a crucial role in both discoverable and non-discoverable credentials,
helping to ensure that the right user is authenticated with the correct credentials.

#### 2.7.2 What's the Difference Between User Name and User Display Name?

User Name (`user.name`) is typically the user's unique login identifier within your system
(e.g. the email address). This value is crucial for the relying party (RP) to distinguish
between different user accounts.

Contrarily, the User Display Name (`user.displayName`) is meant for display purposes and
is more user-friendly. It's often the user's full name or a name that the user prefers to
be addressed by. This is the name shown to the user in various interfaces, like browser
prompts or password managers, making the authentication experience more personalized and
understandable.

Misconfiguration of these values can lead to user confusion or identification issues. It's
important for an RP to accurately configure User Name (user.name) and User Display Name
(`user.displayName`) to ensure a seamless user experience. Incorrect settings might make
it challenging to identify the context or the specific account a passkey is associated
with, especially in environments with multiple deployments or user accounts.

#### 2.7.3 How can I Implement Seamless / Accountless Authentication?

**Usernameless / accountless authentication** represents a modern approach to
[user verification](https://www.corbado.com/blog/webauthn-user-verification) that removes the need for
traditional usernames. Instead, it relies on cryptographic credentials (passkeys).

To implement usernameless authentication in your system, you need to follow these steps:

1. **Add passkey** authentication to your system.
2. Enable **support for resident keys (discoverable credentials)**. These are credentials
   stored on the authenticator that can be used without requiring the user to input a
   username.
3. During user registration, create a passkeys with the**requireResidentKey property set
   to true**. This ensures that the credential is stored on the authenticator,
   facilitating usernameless authentication.
4. Modify the login flow to **support Conditional UI** that creates an authentication
   request that does not require the user to enter a username. The authenticator responds
   with the stored credential, which includes a unique user identifier allowing the server
   to recognize the returning user.
5. **Update backend logic** to handle usernameless authentication. Ensure the server can
   correctly process the User Handle (`response.userHandle`) returned by the authenticator
   to retrieve the corresponding user account.

#### 2.7.4 What Data can be Changed Client-Side (on the Authenticator)?

Changing passkey meta-data on the client side is something that is quite complex as its
not guaranteed that changes are reflected on the server-side (and vice versa). Especially
deleting passkeys on the server-side is not really propagated to the client-side causing a
potentially bad user experience. Currently, the workaround to change the User Name
(user.name) and / or User Display Name (`user.displayName`) looks like that you create a
new passkey for this relying party with new values for User Name (user.name) and / or User
Display Name (`user.displayName`). While doing so you need to make sure that you use the
same User ID (`user.id`), which would overwrite the old passkey.

However, theres a recent WebAuthn explainer that suggests to add new functions to the
WebAuthn API to propagate server-side deleted passkeys to the client and update User Name
(`user.name`) as well as User Display Name (`user.displayName`), which is relevant
especially in [Conditional UI](https://www.corbado.com/glossary/conditional-ui) cases. Read more
[here](https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-Report-API-explainer).

## 3. The Complexities and Challenges

This section delves into these complexities that emerge when implementing passkey based
authentication systems and dealing with User IDs, User Names, User Display Names, User
Handles and Credential IDs.

### 3.1 Complications in WebAuthn Specifications (Level 2 vs. Level 3)

The current draft of the Level 3 version also contradicts itself when it comes to the
handling of the [assertion](https://www.corbado.com/glossary/assertion) on the relying party after successful
local authentication. These differences in how credentials and user identification are
handled can be seen by comparing sections 1.3.3 and 7.2 (6+7) of the
[WebAuthn Level 3](https://www.corbado.com/blog/passkeys-prf-webauthn) draft.

**1.3.3 Flow:**

The server examines the [assertion](https://www.corbado.com/glossary/assertion), extracts the Credential ID,
looks up the registered credential public key in its database, and verifies the
[assertion](https://www.corbado.com/glossary/assertion) signature.

If valid, it looks up the User ID (`user.id`) associated with the
[assertions](https://www.corbado.com/glossary/assertion) Credential ID. This User ID (`user.id`) is now
authenticated. The server now does whatever it would otherwise do upon successful
authentication - return a success page, set authentication cookies, etc.

If the Credential ID is not recognized by the server (e.g., it has been deregistered due
to inactivity) then the authentication has failed. Each relying party will handle this in
its own way.

**7.2 (6+7) Flow:**

Its crucial to determine if the user was identified before or not as the two cases differ:

1. If the user was identified before the authentication (login) ceremony was initiated,
   e.g., via a provided username or cookie, verify that the identified user account has a
   credential (passkey) whose Credential ID equals the credential.rawId of the assertion.
   If the User Handle (response.userHandle ) is present, verify that it equals the User
   Handle (`response.userHandle`) of the user account.
2. If the user was not identified before the authentication (login) ceremony was
   initiated, you need to verify that the User Handle (`response.userHandle`) is present.
   Verify that the user account identified by the User Handle (`response.userHandle`) is
   linked to a credential (passkeys) whose Credential ID equals credential.rawId.

As you can see, the big difference between section 1.3.3 and section 7.2 of the WebAuthn
specification is that in 1.3.3 the Credential ID is first used to query the credential
(passkey) table, while in 7.2 the User Handle (`response.userHandle`) is used (especially
in case B) to query the user table before checking the credential (passkey) table.

### 3.2 Limit the Number of Credentials per Authenticator per Relying Party

A critical aspect of WebAuthn is the management of User Handles (`response.userHandle`)
and credentials. The WebAuthn RFC 5.4.3 outlines that
[authenticators](https://www.corbado.com/glossary/authenticator) map pairs of relying party IDs and User Handles
(`response.userHandle`) to public key credential sources. This mapping dictates that an
authenticator stores only one
[discoverable credential](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys)
per User Handle (`response.userHandle`) per Relying Party. The challenge lies in the
security and uniqueness of User Handles (`response.userHandle`). Authenticators must know
when to replace an existing
[discoverable credential](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys)
with a new one during the registration ceremony, a process that requires careful handling
to maintain security and [user privacy](https://www.corbado.com/faq/ensure-gdpr-compliance-with-passkeys).

### 3.3 User Handle Should Not Expose Private Information

Maintaining privacy and security in the WebAuthn framework is paramount. The User Handle
(`response.userHandle`), being a key component in the authentication process, must be
handled in a way that it does not reveal private information. The RFC suggests that User
Handles (`response.userHandle`) should be unique account-level identifiers and cautions
against using direct hash transformations of sensitive data, which could lead to security
[vulnerabilities](https://www.corbado.com/glossary/vulnerability).

### 3.4 Confusing Lookup of Credentials in AllowCredentials

The Credential ID plays a central role in the authentication ceremony. It is generated by
the authenticator and must be unique for each credential. This uniqueness is critical when
returning signatures valid for a specific account in an
[AllowCredentials](https://www.corbado.com/glossary/allowcredentials) context. The challenge lies in correctly
implementing the lookup mechanism for Credential IDs based on provided identification
information (e.g., email or username). This process becomes more intricate when dealing
with empty [AllowCredentials](https://www.corbado.com/glossary/allowcredentials), where the correct approach
involves looking up the Credential ID in the database, then determining login feasibility
based on existing or deleted user accounts.

### 3.5 Confusing UI for User Name and User Display Name when Deleting Passkeys

Often the User Name (`user.name`) and User Display Name (`user.displayName`) in the
browsers or password managers user interfaces do not provide the context you would need to
securely analyze or delete the right passkeys. This makes it complex for users to
distinguish between the right passkeys and can potentially lead to passkeys being deleted
by accident.

### 3.6 How does ExcludeCredentials work with User ID, User Name or User Display Name?

[AllowCredentials](https://www.corbado.com/glossary/allowcredentials) specifies the list of credentials
(passkeys) that are allowed to authenticate the user. This list contains Credential IDs
that the server is aware of and associates with the user's account. During authentication,
the authenticator only returns signatures that are valid for the credentials listed in
AllowCredentials. This ensures a secure and specific authentication process, linking the
authentication attempt directly to the intended user account.

Changing the User ID (`user.id`), User Name (`user.name`) or User Display Name
(`user.displayName`) does not impact the AllowCredentials process directly. This is
because AllowCredentials focuses on Credential IDs rather than user User ID (`user.id`),
User Name (`user.name`) or User Display Name (`user.displayName`).

### 3.7 How does ExcludeCredentials work with User ID, User Name or User Display Name?

[ExcludeCredentials](https://www.corbado.com/glossary/excludecredentials) is used to prevent the creation of a
new credential for a user if that user already has a registered credential on the
authenticator. It's a security measure to avoid multiple registrations of the same user on
the same device.

ExcludeCredentials contains a list of Credential IDs that are already registered for the
user. During the registration process, the authenticator checks this list against the new
credential it is about to create. If the new credential's ID matches any in the
ExcludeCredentials list, the registration is halted to prevent duplication.

ExcludeCredentials operates on the basis of Credential IDs and does not directly interact
with User ID (`user.id`), User Name (`user.name`) or User Display Name
(`user.displayName`). Its primary function is to check for the uniqueness of the
credential (passkey) being registered, not to validate user information.

## 4. Developer Recommendations for Passkey Implementation

![best passkey implementation tipps](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/best_passkey_implementation_tipps_1f1c16935e.png)

### 4.1 User ID Muster Never be an Email Address / Phone Number

The User ID (`user.id`) was created to allow the relying party to have control over how
the primary key of the user database looks like. Its considered to be very bad practice to
use anything else than a primary key as User ID (`user.id`), as the User ID (`user.id`)
never changes in WebAuthn from a technical point of view. Whereas in reality, its quite a
common scenario to have changing email addresses or phone numbers being reassigned after a
period of inactivity. Therefore, the User ID (`user.id`) must never contain any personally
identifying information about the user and thus must never be an email address or phone
number. Moreover, the User ID (`user.id`) must never be empty, though it maybe null.
Assigning a non-descript, unique identifier to each user account enhances security and
maintains [user privacy](https://www.corbado.com/faq/ensure-gdpr-compliance-with-passkeys)

### 4.2 Provide Human-Readable Names Instead of Only Providing Credential IDs for Passkeys

Enhancing UX is key when dealing with passkeys. One effective way is to provide
human-readable names for these credentials. This allows users to easily distinguish
between different passkeys, especially if they have multiple. Here are some specific
suggestions:

- Allow users to edit the names of the credentials (passkeys). This gives users the
  flexibility to adopt their own naming conventions, enhancing their experience and making
  it easier to manage credentials (passkeys).
- Suggest default names based on the ecosystem or device where the passkey was created,
  such as [Windows Hello](https://www.corbado.com/glossary/windows-hello),
  [1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis),
  [iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain), or Chrome on macOS. You can also use the
  [user agent](https://www.corbado.com/blog/client-hints-user-agent-chrome-safari-firefox) to suggest names like
  Windows 10 passkey #1. These context-based names help users quickly identify the purpose
  and origin of each passkey.

### 4.3 Leverage User Name as a RP for Differentiating Credentials

As highlighted by
[Matthew Miller](https://blog.millerti.me/2023/02/14/controlling-the-name-displayed-during-webauthn-registration-and-authentication/),
it's recommended for a Relying Party (RP) to use User Name (user.name) as a unique
identifier (besides User ID). This allows users to easily recognize and manage their
passkeys in various user interfaces. Although some clients and operating systems might
support User Display Name (`user.displayName`), its more reliable to count on the User
Name (`user.name`) as the identifier regularly shown to users. This practice ensures
consistency across different platforms and enhances the manageability of credentials.

### 4.4 Conditional UI Mostly Uses User Names

Implement [Conditional UI](https://www.corbado.com/glossary/conditional-ui) that supports the User Name
(user.name), such as an email address or username, or other provided identification
information to retrieve potential Credential IDs. This approach is particularly useful in
configuring the AllowCredentials option in **PublicKeyCredentialRequestOptions**. Since
the exact Credential ID used for authentication might not be known in advance, using the
User Name (`user.name`) as a hint can streamline the authentication process.

## 5. Conclusion

As we've navigated the complexities of WebAuthn User ID, User name, User Display Name,
User Handle and Credential ID in passkey applications, the importance of the right
understanding and correct implementation is clear. We hope that we could have clarified
some of the confusing parts.

## Frequently Asked Questions

### How do I implement usernameless authentication using passkeys?

Enable resident keys (discoverable credentials) and set the requireResidentKey property to
true during registration so credentials are stored on the authenticator. Configure your
login flow to support Conditional UI so no username input is required, then update your
backend to process the User Handle (response.userHandle) returned by the authenticator to
identify the correct user account.

### What is the difference between WebAuthn User Name and User Display Name, and does it matter which I configure?

User Name (user.name) is the unique login identifier, such as an email address, used by
the relying party to distinguish between accounts. User Display Name (user.displayName) is
a human-readable label shown in interfaces like browser prompts and password managers, and
is not relied upon for authentication. Misconfiguration of either can cause user confusion
or make it difficult to identify which passkey belongs to which account.

### Can I use an email address as the WebAuthn User ID when setting up passkeys?

No. The User ID (user.id) must never be an email address or phone number because these
identifiers can change or be reassigned after a period of inactivity, breaking the binding
between a user and their credentials. Use a non-descript unique identifier such as a
primary key, UUID or auto-increment value from your user database instead.

### How do I update a passkey's User Name or User Display Name after registration?

The current recommended workaround is to create a new passkey for the same relying party
using the same User ID (user.id), which overwrites the existing credential with the
updated User Name or User Display Name values. A WebAuthn explainer on the W3C GitHub
proposes new WebAuthn API functions to propagate server-side metadata changes to the
client, but this is not yet standardized.
