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

# Passwordless Authentication on Database Connections

> Learn how to configure true passwordless authentication on a new or existing database connection.

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>;
};

<ReleaseStageNotice feature="Passwordless Authentication on Database Connections" stage="ea" contact="support" terms="true" />

Auth0 allows you to configure email and phone-based passwordless authentication directly on a [database connection](/docs/authenticate/database-connections). Rather than creating a separate connection for one-time password (OTP) authentication, you can offer passwordless login directly from your database connection. This reduces implementation complexity and simplifies the login experience for end-users.

<Callout icon="triangle-exclamation" color="#F59E0B" iconType="regular">
  Passwordless for database connections is not supported for use with Classic Login.
</Callout>

## How it works

Auth0 uses an [Identifier-First Authentication](/docs/authenticate/login/auth0-universal-login/identifier-first) approach in which users are verified with OTP authentication:

1. An end user enters an identifier to login with [Auth0's Universal Login](/docs/authenticate/login/auth0-universal-login).
2. Auth0 looks up the authentication methods for each identifier configured on your database connection.
3. The user is presented with the most suitable option based on the `default_method` and available authentication methods (for example, receive an OTP by email or phone or provide a password).
4. If OTP is the determined authentication method, Auth0 sends a code to the user's email or phone.
5. The user enters the code and is authenticated. If you've configured passkeys, the user is prompted for progressive passkey enrollment.

<Card title="Before you start">
  * Configure your tenant to use the [Identifier-First Authentication Profile](https://auth0.com/docs/authenticate/login/auth0-universal-login/identifier-first).
  * If you plan to use phone-based OTP (SMS or Voice), you must enable the [Unified Phone Experience](/docs/customize/phone-messages/unified-phone/configure-unified-phone) setting under [**Branding > Phone Provider**](https://manage.auth0.com/#/phone/templates/phone/provider).
  * [Attributes](/docs/authenticate/database-connections/activate-and-configure-attributes-for-flexible-identifiers) must be enabled on the database connection.
  * If you plan to use existing (legacy) passwordless connections in conjunction with passwordless authentication on database connections, and you don't want to configure your existing passwordless connections to use the Unified Phone Provider:
    1. Navigate to [**Auth0 Dashboard > Authentication > Passwordless**](https://manage.auth0.com/#/connections/passwordless).
    2. Select **Configure** by SMS.
    3. Make sure the **Use Tenant-Level Messaging Provider** setting is disabled.
</Card>

## Configure attributes (identifiers)

When configuring email and phone-based passwordless authentication on database connections, you must first determine which attribute(s) you want end-users to provide during signup and login.

Review the identifier type and corresponding authentication method:

| Identifier | Authentication Method(s)     |
| ---------- | ---------------------------- |
| Email      | Password, Email OTP, Passkey |
| Phone      | Password, Phone OTP, Passkey |
| Username   | Password                     |

For email and phone identifiers, if password is **not** enabled, you must have OTP verification enabled for sign up. You can configure email and phone attributes as optional on signup, so users can sign up with just an email or just a phone number.

When a user authenticates via email OTP, `email_verified` is automatically set to `true` on their profile. When a user authenticates via phone OTP, `phone_verified` is automatically set to `true`.

<Warning>
  If you want end-users to authenticate with passkeys, you **must** have an alternative authentication method configured, such as email or phone. Passkey-only authentication is not supported.
</Warning>

To learn more, read [Activate and Configure Attributes for Flexible Identifiers](/docs/authenticate/database-connections/activate-and-configure-attributes-for-flexible-identifiers).

## Create a new database connection

If you do not have an existing database connection, create one using the Auth0 Dashboard or Management API.

<Tabs>
  <Tab title="Auth0 Dashboard" icon="browser">
    1. Navigate to [**Auth0 Dashboard > Authentication > Database**](https://manage.auth0.com/#/connections/database). Choose **Create DB Connection** to create the connection.
    2. Enter a unique name for your connection.
    3. Choose one or more attributes for end-users to log in or sign up.
    4. Select your authentication method(s). You can further configure these methods once you've created the connection.
    5. Toggle on **Disable Sign Ups** if you don't want users to sign up using public endpoints.
    6. Toggle on **Promote Connection to Domain Level** if you want to use this connection with third-party applications.
    7. Select **Create**.

    For a true passwordless connection, complete the following additional steps:

    1. In your new connection, select the **Attributes** tab.
    2. To disable Username as an identifier, select **Configure** and toggle off **Use Username as Identifier**.
    3. To configure Email and Phone identifiers, select **Configure**.

    * For Email attributes, select **One-Time Password (OTP)** under Verification Methods and enable **Verify email on sign up** for true passwordless configuration. This ensures `email_verified` is automatically set so users are always prompted for OTP on login and signup.

    4. Select **Save**.

    5. Configure settings for authentication methods that correspond to the chosen identifiers. You cannot disable password unless you have `phone_otp` and/or `email_otp` configured.

    6. Under Password settings, select **Policy** and choose **Block** for:

       * Password on Login
       * Password on Signup
       * Self-service change password (updates automatically)

    7. Toggle on **Support users without a password**.
           <Warning>
             You may get an error if you do not toggle on **Support users without a password**.
           </Warning>

    8. Select **Save**. In the prompt, select **Continue** to confirm you understand that existing users may be affected.

    9. Navigate to the **Applications** tab and enable the connection for your application or API.
  </Tab>

  <Tab title="Management API" icon="code">
    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      To use the Management API, you need a [Management API access token](/docs/secure/tokens/access-tokens/management-api-access-tokens/get-management-api-access-tokens-for-production).
    </Callout>

    Call the [Create a Connection](https://auth0.com/docs/api/management/v2/connections/post-connections) endpoint. Use the `default_method` option to set the first authentication method for each identifier.

    ```bash expandable lines theme={null}
    curl --location 'https://YOUR_AUTH0_TENANT/api/v2/connections' \
    --header 'Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN' \
    --header 'Accept: application/json, text/plain, */*' \
    --header 'Content-Type: application/json' \
    --data '{
      "name": "YOUR_CONNECTION_NAME",
      "strategy": "auth0",
      "is_domain_connection": false,
      "options": {
        "disable_signup": false,
        "attributes": {
          "email": {
            "identifier": {
              "active": true,
              "default_method": "email_otp"
            },
            "profile_required": true,
            "signup": {
              "status": "required",
              "verification": {
                "active": true
              }
            },
            "verification_method": "otp",
            "unique": true
          },
          "phone_number": {
            "identifier": {
              "active": true,
              "default_method": "password"
            },
            "profile_required": true,
            "signup": {
              "status": "required",
              "verification": {
                "active": true
              }
            }
          },
          "username": {
            "identifier": {
              "active": true
            },
            "profile_required": true,
            "signup": {
              "status": "required"
            },
            "validation": {
              "min_length": 1,
              "max_length": 15,
              "allowed_types": {
                "email": false,
                "phone_number": false
              }
            }
          }
        },
        "authentication_methods": {
          "password": {
            "enabled": true
          },
          "passkey": {
            "enabled": false
          },
          "email_otp": {
            "enabled": true
          },
          "phone_otp": {
            "enabled": true
          }
        }
      }
    }'
    ```
  </Tab>
</Tabs>

## Update existing connections

If you have current database connections, update the settings for passwordless in the Auth0 Dashboard or Management API.

<Tabs>
  <Tab title="Auth0 Dashboard" icon="browser">
    1. **Open the connection**: Navigate to [**Auth0 Dashboard > Authentication > Database**](https://manage.auth0.com/#/connections/database) and select the connection you want to update.
    2. **Activate Attributes**: Under the **Attributes** tab, select **Activate** to enable the New Attributes Configuration.
    3. **Add Email and Phone attributes**: Choose **+ Add Attributes** and add Email and Phone Number if they are not already present.

           <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
             For a true passwordless (OTP) connection, the username identifier is not supported.
           </Callout>
    4. **Enable OTP authentication methods**: Under the **Authentication Methods** tab:
       * Configure Phone to **Allow** Phone OTP and save your changes.
       * Configure Email to **Allow** Email OTP and save your changes.
    5. **Block password authentication**: Under Password settings, choose **Policy** and select **Block** for:

       * Password on Login
       * Password on Signup
       * Self-service change password

       Toggle on **Support users without a password**.

           <Warning>
             You may get an error if you do not toggle on **Support users without a password**.
           </Warning>
    6. **Save**: Select **Save**.
  </Tab>

  <Tab title="Management API" icon="code">
    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      To use the Management API, you need a [Management API access token](/docs/secure/tokens/access-tokens/get-management-api-access-tokens-for-production).
    </Callout>

    Call the [Update a Connection](https://auth0.com/docs/api/management/v2/connections/patch-connections-by-id) endpoint. Add the `default_method` option to set the first authentication method. For Email attributes, set either `password` or `email_otp`. For Phone attributes, set `password` or `phone_otp`.

    ```bash theme={null}
    curl -L -X PATCH "https://YOUR_AUTH0_TENANT/api/v2/connections/<connection_id>" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN" \
    -d '{
      "options": {
        "passwordPolicy": "none",
        "authentication_methods": {
          "password": { "enabled": true },
          "passkey": { "enabled": true },
          "email_otp": { "enabled": true },
          "phone_otp": { "enabled": true }
        },
        "attributes": {
          "email": {
            "signup": {
              "status": "required",
              "verification": { "active": true }
            },
            "unique": true,
            "identifier": {
              "active": true,
              "default_method": "email_otp"
            },
            "profile_required": true,
            "verification_method": "otp"
          },
          "phone_number": {
            "signup": {
              "status": "required",
              "verification": { "active": true }
            },
            "identifier": {
              "active": true,
              "default_method": "phone_otp"
            },
            "profile_required": true
          }
        }
      }
    }'
    ```
  </Tab>
</Tabs>

## Use Auth0 Actions

For more insight into passwordless authentication factors on database connections, configure attributes with Auth0 Actions.

### Post-login trigger

The `post-login` trigger fires after a user authenticates but before the authorization server returns a token. The `event.authentication` object in [Auth0 Dashboard > Actions > Triggers > Post Login](https://manage.auth0.com/#/actions/flows) exposes the following methods:

| Method               | Parameter | Description                                                             |
| -------------------- | --------- | ----------------------------------------------------------------------- |
| Email OTP            | `email`   | Email OTP used to authenticate the user as the first factor.            |
| Phone OTP with text  | `sms`     | Phone OTP (SMS) used to authenticate the user as the first factor.      |
| Phone OTP with voice | `tel`     | Phone OTP with voice used to authenticate the user as the first factor. |
| Password             | `pwd`     | Password used to authenticate the user as the first factor.             |

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  `email_verified` and `phone_verified` are set automatically on the user profile when a user authenticates via email OTP or phone OTP. If you previously used a post-login Action to manually set these flags, you can remove that workaround.
</Callout>

Use `event.authentication` to:

* Detect which passwordless factor the user completed (`email`, `sms`, `tel`, or `pwd`)
* Add custom claims to tokens based on the authentication method
* Conditionally run logic based on how the user authenticated

#### Example

The following example reads `event.authentication.methods` to detect which passwordless factor the user completed and adds it as a custom claim on the ID token.

```javascript theme={null}
exports.onExecutePostLogin = async (event, api) => {
  if (!event.authentication?.methods || event.authentication.methods.length === 0) {
    return;
  }

  if (event.connection.name !== 'YOUR_AUTH0_CONNECTION') {
    return;
  }

  const firstFactor = event.authentication.methods[0];

  if (firstFactor.name === 'email') {
    api.idToken.setCustomClaim('https://your-app.com/auth_method', 'email_otp');
  } else if (firstFactor.name === 'sms' || firstFactor.name === 'tel') {
    api.idToken.setCustomClaim('https://your-app.com/auth_method', 'phone_otp');
  } else if (firstFactor.name === 'pwd') {
    api.idToken.setCustomClaim('https://your-app.com/auth_method', 'password');
  }
};
```

### Post-challenge trigger

The `post-challenge` trigger fires after users complete a challenge, such as password reset, phone validation, or MFA. The `event.authentication` object in [Auth0 Dashboard > Actions > Triggers > password-reset-post-challenge](https://manage.auth0.com/#/actions/flows) exposes the following attributes:

| Attribute | Parameter      | Description                                  |
| --------- | -------------- | -------------------------------------------- |
| Email     | `email`        | Password reset with email OTP or magic link. |
| Phone     | `phone_number` | Password reset with phone OTP.               |

#### Example

The following example reads `event.authentication.methods` to detect which passwordless factor completed the challenge and adds it as a custom claim on the ID token.

```javascript theme={null}
exports.onExecutePostChallenge = async (event, api) => {
  if (!event.authentication?.methods || event.authentication.methods.length === 0) {
    return;
  }

  if (event.connection.name !== 'YOUR_AUTH0_CONNECTION') {
    return;
  }

  const firstFactor = event.authentication.methods[0];

  if (firstFactor.name === 'email') {
    api.idToken.setCustomClaim('https://your-app.com/challenge_method', 'email_otp');
  } else if (firstFactor.name === 'phone_number') {
    api.idToken.setCustomClaim('https://your-app.com/challenge_method', 'phone_otp');
  }
};
```

## Benefits

* **Simplified Implementation:** Fewer connections to configure and maintain. No need for account linking unless using social/federated connections in conjunction with database connections.
* **Improved User Experience**: Offer combinations of email and phone-based OTP with passwords, passkeys, and social/federated login all from the same identifier-first experience in Universal Login.
* **Flexible Signup Flows**: Configure email and phone attributes as optional on signup, allowing users to sign up with just an email or just a phone number — ideal for mobile-first or email-only experiences.
* **Voice OTP**: Voice OTP is included as a first factor when configured in the Unified Phone Experience.

## Limitations

* Available for Universal Login-based flows only; not yet supported for API-based authentication.
* Passwordless for database connections is not supported for use with Classic Login.
* Passwordless for database connections does not support Implicit Signup & Login.
* In legacy passwordless connections, there was no difference in user experience between signup and login. Database connections distinguish between the signup and login experience, which requires *explicit* signup and login.
  * If a user without an Auth0 identity enters the login flow, the system will not automatically sign them up. The user receives an error after validating the OTP.
  * If a user with an Auth0 identity enters the signup flow, the user receives an error after validating the OTP.

## Learn more

* [Passwordless Authentication](/docs/authenticate/passwordless)
* [Passwordless Connection Limitations](/docs/authenticate/passwordless/passwordless-connection-limitations)
* [Passwordless Connections Best Practices](/docs/authenticate/passwordless/best-practices)
* [Activate and Configure Attributes for Flexible Identifiers](/docs/authenticate/database-connections/activate-and-configure-attributes-for-flexible-identifiers)
