> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-actions-triggers-prototype.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Enable and Configure Passkey Authentication for Database Connections

> Use the Auth0 Dashboard to enable passkeys as an authentication method on a database connection and configure the passkey authentication UI, progressive enrollment, and local enrollment.

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "Beta",
    "ea": "Early Access"
  };
  const stageText = stageTextMap[stage] || "a product release stage";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>This feature is available for {linkify(`${plans} plans`, "https://auth0.com/pricing")}. </>}
            {contact && "To participate, contact " + contact + ". "}
            {terms && <>By using this feature, you agree to the applicable Free Trial terms in Okta's {linkify("Master Subscription Agreement", "https://www.okta.com/legal")}.</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>The {feature} feature is in {linkify(stageText, prsLink)}.</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

## Prerequisites

Before you can enable passkeys for a database connection, you must complete the following prerequisites.

On your tenant, you must:

* [Enable Universal Login](/docs/authenticate/login/auth0-universal-login/universal-login-vs-classic-login/universal-experience).

* [Enable Identifier First authentication](/docs/authenticate/login/auth0-universal-login/identifier-first).

* Disable custom login pages. In the Auth0 Dashboard, go to [Branding > Universal Login > Manage Classic Login > Login](https://manage.auth0.com/#/login_page), and disable the **Custom Login Page** toggle.

On your database connection, you must:

* Either disable [requiring usernames](/docs/authenticate/database-connections/require-username) for your database connection or, alternatively, [enable Flexible Identifiers](/docs/authenticate/database-connections/flexible-identifiers-and-attributes).

* Either disable [using your own database](/docs/authenticate/database-connections/custom-db/create-db-connection) or, alternatively, enable [user import](/docs/authenticate/database-connections/custom-db/templates) (**Import Users to Auth0**).

  To use your own database without user import (**Import Users to Auth0**) enabled, follow the [additional prerequisites below on updating your database action scripts](#early-access-use-your-own-database-without-user-import-enabled).

Database connections with passkeys enabled must also still have passwords enabled. This ensures users can continue to access their accounts from browsers and older devices that may not yet support passkeys.

### <Badge color="yellow">Early Access</Badge> Use your own database without user import enabled

Passkey authentication now supports using your own database without user import enabled. This lets you offer passkey authentication on custom database connections while continuing to authenticate users against your external user store.

As a prerequisite, you must update the Get User and Create [database action scripts](/docs/authenticate/database-connections/custom-db/templates) to support user handling by both identifier and `user_id`.

<Accordion title="How to update database action scripts to enable passkeys for your own database without user import enabled">
  <ReleaseStageNotice feature="passkeys for using your own database wihtout user import enabled" stage="ea" terms="true" />

  1. First, confirm that user import is disabled for your database connection.

  2. [Enable context object support](/docs/authenticate/database-connections/custom-db/create-db-connection#enable-context-object). This makes the `context` parameter available in your database action scripts, which is necessary to support both identifier and `user_id` lookups.

  3. The Get User script must support both lookup by identifier (`context.identifierType` is not set) and lookup by `user_id` (`context.identifierType` is set to `user_id`).

     Update your [Get User database action script](/docs/authenticate/database-connections/custom-db/templates/get-user) from `getByEmail` to the provided `getUser` function:

     ```js theme={null}
     function getByEmail(email, callback) { // [!code --] 
     function getUser(identifierValue, context, callback) { // [!code ++] 
         const axios = require('axios');

         // Retrieve the user identifier from context // [!code ++]
         const identifierType = context.identifierType || 'email'; // [!code ++]

         // Replace with your external user retrieval endpoint 
         const url = configuration.baseAPIUrl
                     + `/get_user/${email}?type=email`; // [!code --]
                     + `/get_user/${identifierValue}?type=${identifierType}`; // [!code ++]

         axios.get(url)
             .then(response => {
                 // Return the user object if found
                 const user = response.data; 
                 return callback(null, {
                     user_id: user.user_id,
                     email: user.email
                     // Optionally include other user attributes 
                 });
             })
             .catch(error => {
                 // Handle error response 
                 return callback(null);
             });
     }
     ```

  4. The Create script must return a valid user profile. When attributes are enabled, the returned user profile must follow the same validation as the Login and Get User scripts. When attributes are not enabled, the returned user profile must include the `user_id` value.

     Update your [Create database action script](/docs/authenticate/database-connections/custom-db/templates/create) to return a valid user profile:

     ```js theme={null}
     function create(user, callback) {
         const axios = require('axios');

         // Replace with your external user creation endpoint
         const url = 'https://example.com/api/create'; 

         const payload = {
             email: user.email
             // Add other user properties as needed
         };

         axios.post(url, payload)
             .then(response => {
                 // Return the user object if created
                 const createdUser = response.data; 

                 return callback(null, {
                     user_id: createdUser.user_id,
                     email:createdUser.email
                     // Optionally include other user attributes
                 });
             })
             .catch(error => {
                 // Handle error response 
                 return callback(error);
             }); 
     }
     ```
</Accordion>

## Configure passkeys

Once you complete the prerequisites, you can use the Auth0 Dashboard to enable and configure passkeys.

<Steps titleSize="h3">
  <Step title="Open passkey configuration">
    Go to [Authentication > Database](https://manage.auth0.com/#/connections/database) and select the name of the database connection you want to edit.

    Select the **Authentication Methods** tab. Then, in the **Passkey** section, select **Configure** to open the **Passkey** panel.

    If it isn't already checked, check **Enable passkeys**.
  </Step>

  <Step title="Choose passkey authentication UI">
    The passkey authentication UI determines how users can trigger passkey authentication during login and sign-up.

    In the **Passkey Authentication UI** section, choose one of the three options:

    | Passkey authentication UI | Description                                                                                                                                                                                   |
    | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Passkey button & autofill | Users can authenticate with passkeys using autofill or the passkey button.                                                                                                                    |
    | Autofill                  | Users must log in with their browser's autofill feature to use passkeys. Autofill allows users to select a saved account from a dropdown menu instead of manually entering their credentials. |
    | Passkey button            | Users must select the **Continue with a passkey** button on the login prompt.                                                                                                                 |

    If autofill is not available in the user's browser, users can log in using the passkey button (if enabled) or using password credentials.
  </Step>

  <Step title="Enable progressive enrollment (optional)">
    Progressive enrollment prompts users to create a passkey (if they have not done so already) after logging in with an identifier and password. This step is not required and users can choose to delay this action every 30 days.

    Progressive enrollment can be useful when migrating users to passkeys to help them transition between authentication methods.

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      When creating an account through an [Organization invitation email](/docs/manage-users/organizations/configure-organizations/invite-members), users cannot choose passkey authentication. You can enable progressive enrollment so these users can create passkeys after logging in with a password.
    </Callout>

    The **Progressive Enrollment** checkbox is checked by default, but you can uncheck it to disable it.
  </Step>

  <Step title="Enable local enrollment (optional)">
    When a passkey user logs in to a new device using a cross-device passkey, local enrollment prompts them to create a local passkey on the new device. This is not required, so users can choose to skip creating a local passkey.

    The **Local Enrollment** checkbox is checked by default, but you can uncheck it to disable it.
  </Step>

  <Step title="Save settings">
    Select **Save** to save your configuration changes.

    If the save button is disabled, use the **Passkey Authentication Prerequisites** section at the top of the **Passkey** panel to confirm that your tenant and database connection are configured correctly.
  </Step>
</Steps>

## Next steps

To ensure the best experience for end users when using passkeys, you may want to consider the following additional steps.

### Configure relying party ID (RP ID)

To allow users to use a single passkey to authenticate across all subdomains (for example, both a native application served at `app.example.com` and a web application served at `login.example.com`), you can set the RP ID to the parent or root domain.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  When you customize the RP ID in the Auth0 Dashboard or Management API, all passkeys for other domains will be unusable, and your end users must re-enroll.
</Callout>

Your application’s domain must be added to the **Allowed Origins (CORS)** list in your [application settings](https://manage.auth0.com/#/applications) for the RP ID to work correctly.

To set the RP ID in Auth0 Dashboard:

1. Navigate to **[Auth0 Dashboard > Tenant Settings](https://manage.auth0.com/#/tenant/relying_party_ids)**.
2. Select the **Relying Party IDs** tab.
3. Choose **Edit Relying Party ID**.
4. Enter the domain.
5. If this RP ID is the root domain, select the checkbox to set the domain as the default for your tenant.
6. Select **Save**.
7. Next, navigate to the application you want to set a relying party ID.
8. Select the application settings.
9. Under the **Application URIs** section, add your application's domain in Allowed Origins (CORS).
10. Select **Save**.

### Configure a custom domain

When a user enrolls a passkey, it associates with the <Tooltip tip="Entity (such as a service or application) that depends on a third-party identity provider to authenticate a user." cta="View Glossary" href="/docs/glossary?term=relying+party">relying party</Tooltip> domain. If the domain name changes, any passkeys associated with the old domain become invalid.

Consider configuring a [custom domain](/docs/customize/custom-domains) for your tenant prior to enabling passkeys to avoid any interruptions for end-users.

If you have [Multiple Custom Domains](/docs/customize/custom-domains/multiple-custom-domains) enabled on your tenant, Auth0 maintains a one-to-one relationship between a domain and the passkey for that domain.

Users can enroll a passkey for only one domain (the first one they enroll with) of the multiple custom domains on the tenant. For passwordless login, the selected custom domain should be reflected in the Magic Link for the passwordless login flow.

### Bypass multi-factor authentication

If you have [multi-factor authentication](/docs/secure/multi-factor-authentication) enabled, the default behavior is to require the completion of an MFA challenge regardless of whether the authentication method was a password or a passkey.

Given the high level of security that passkeys provide, you can [skip MFA for passkey authentication using a post-login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#reduce-friction-with-passkeys).
