> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-docs-ia-custom-database-connections.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Create Custom Database Connections

> Use your own external user store as an IdP in Auth0 by creating a custom database connection.

If you have your own external user store, you can use it as an <Tooltip tip="Identity Provider (IdP): Service that stores and manages digital identities." cta="View Glossary" href="/docs/glossary?term=identity+provider">identity provider</Tooltip> in Auth0 to authenticate users.

To do so, first you connect Auth0 to your external user store by creating a custom database connection, then you write database action scripts to define how Auth0 interfaces with your user store. We provide database action script templates for several common databases:

* MongoDB
* MySQL
* PostgreSQL
* Microsoft SQL Server
* ASP.NET Identity
* Web services accessed with Basic Auth

You can modify these templates or write your own entirely to connect to any kind of external user store.

## Instructions

<Steps titleSize="h3">
  <Step title="Prerequisites">
    * Your external user store must be reachable from Auth0's servers. If it is behind a firewall, allow inbound traffic from [Auth0's outbound IP addresses](/docs/secure/security-guidance/data-security/allowlist).

    * Your external user store must have the appropriate fields to store [normalized user profile attributes](/docs/manage-users/user-accounts/user-profiles/normalized-user-profile-schema), such as `id`, `nickname`, `email`, and `password`.

    * The `id` (or `user_id`) value returned from your database action scripts must be unique across all custom database connections because Auth0 uses this value to [identify users](/docs/manage-users/user-accounts/identify-users).

      To avoid user ID collisions when using multiple custom database connections, we recommend prefixing `id` values with the connection name (omitting whitespace).
  </Step>

  <Step title="Create the custom database connection">
    From [**Auth0 Dashboard > Authentication > Database**](https://manage.auth0.com/#/connections/database), select **+ Create DB Connection**. On [the **New Database Connection** page](https://manage.auth0.com/#/connections/database/new), enter the following configuration.

    * Enter a name, which must:

      * Contain only alphanumeric characters and dashes.
      * Start and end with an alphanumeric character
      * Not exceed 35 characters.

    * Choose one or more [attributes](/docs/authenticate/database-connections/activate-and-configure-attributes-for-flexible-identifiers) as user identifiers.

    * Choose one or more authentication methods (like [passwords](/docs/authenticate/database-connections/flexible-password-policy) or [passkeys](/docs/authenticate/database-connections/passkeys)).

    * Enable the **Use my own database** toggle.

    When you're done, select **Create**. Auth0 creates the database connection and redirects you to its configuration page.
  </Step>

  <Step title="Write database action scripts">
    Once you create your custom database connection, you need to write [database action scripts](/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts) to define how Auth0 interfaces with your external user store for functionality like login, sign up, email verification, password resets, and user deletion.

    At minimum, you must implement a [Login script](/docs/authenticate/database-connections/custom-db/templates/login):

    1. From the database connection's page, select the **Custom Database** tab.

    2. In the **Database Action Scripts** section, select **Login**.

    3. Write your own database action script with the provided function signature, or use the **Load Template** drop-down menu to select a template to start from.

           <Accordion title="MySQL Login action script example">
             For example, the MySQL Login action script template looks like this:

             ```js expandable Login database action script template for MySQL theme={null}
             function login(identifierValue, password, callback) {
               const mysql = require('mysql');
               const bcrypt = require('bcrypt');

               const connection = mysql.createConnection({
                 host: 'localhost',
                 user: 'me',
                 password: 'secret',
                 database: 'mydb'
               });

               connection.connect();

               const query = 'SELECT id, nickname, email, password FROM users WHERE email = ?';

               connection.query(query, [ identifierValue ], function(err, results) {
                 if (err) return callback(err);
                 if (results.length === 0) return callback(new WrongUsernameOrPasswordError(identifierValue));
                 const user = results[0];

                 bcrypt.compare(password, user.password, function(err, isValid) {
                   if (err || !isValid) return callback(err || new WrongUsernameOrPasswordError(identifierValue));

                   callback(null, {
                     user_id: user.id.toString(),
                     nickname: user.nickname,
                     email: user.email
                   });
                 });
               });
             }
             ```

             This example assumes the database contains a `users` table containing the appropriate columns. The script connects to the database, uses a query to retrieve the first user with `email == user.email`, validates the entered passwords with `bcrypt.compareSync` and, if successful, returns an object containing the user profile information (including `id`, `nickname`, and `email`).
           </Accordion>

    All database action scripts must call the Auth0-supplied [`callback` function](/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts#callback) exactly once, immediately before it completes (either implicitly or explicitly with a `return` statement).
  </Step>

  <Step title="Add configuration parameters (optional)">
    In the **Configuration Parameters** section (below **Database Action Scripts**), you can store values that are available to all database action scripts in the global `configuration` object.

    Values are encrypted, so you can also use configuration parameters to store sensitive information such as credentials or API keys for accessing external identity stores or define variables with tenant-specific values.

    To extend the previous MySQL example, if you add the **Key** `MYSQL_PASSWORD` with the **Value** as the MySQL password, you can use that configuration parameter to connect:

    ```javascript MySQL connection configuration parameter example theme={null}
    const connection = mysql.createConnection({
        host: 'localhost',
        user: 'me',
        password: 'secret', // [!code --]
        password : configuration.MYSQL_PASSWORD, // [!code ++]
        database: 'mydb'
    });
    ```

    Treat the `configuration` object as read-only and use it to avoid hard-coding values in your action scripts.
  </Step>

  <Step title="Test and save the database action script">
    1. To test your database action script, select **Save and Try** above the code block.

    2. In the **Try the login script** window that opens, enter the user credentials you want to use to test.

           <Frame>
             <img src="https://mintcdn.com/docs-staging-docs-ia-custom-database-connections/GLNR_MCIZBQ18Neh/docs/images/cdy7uua7fh8z/8uBGZhHYZwOcO19ljJNNp/ccd69d84fdbdff90dc779a6b1ea8a6fd/db-connection-try-login-script.png?fit=max&auto=format&n=GLNR_MCIZBQ18Neh&q=85&s=7119b0c07d70eec2846c00417cec88e2" alt="Try the login script window." width="496" height="360" data-path="docs/images/cdy7uua7fh8z/8uBGZhHYZwOcO19ljJNNp/ccd69d84fdbdff90dc779a6b1ea8a6fd/db-connection-try-login-script.png" />
           </Frame>

    3. Select **Try** to open the runtime selector. Choose your runtime to execute the script.

           <Tip>
             You can [change the default NodeJS runtime](/docs/get-started/tenant-settings#extensibility) in your tenant settings.
           </Tip>

    When you're done, close the **Try the login script** window, then select **Save** to save the script.
  </Step>
</Steps>

## Next steps

### Enable automatic migration

You can continue using your external user store as your IdP. If you want to transition to Auth0's user store instead, you can [incrementally migrate users to Auth0](/docs/manage-users/user-migration/configure-automatic-migration-from-your-database) (sometimes called *trickle* or *lazy* migration).

### Enable Organization context

If you use custom database connections with [Organizations](/docs/manage-users/organizations), you can make Organization details like `id`, `name`, and `metadata` available to your database action scripts by enabling [the `context` object](/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts#context-object)

Doing so passes an additional `context` argument to custom database scripts containing Organization data. For example, when a user authenticates on an Organization’s login prompt, the login database action script is passed.

<Warning>
  You cannot disable the `context` object after you enable it.
</Warning>

First, enable the `context` object:

1. From to [Auth0 Dashboard > Authentication > Database](https://manage.auth0.com/dashboard/us/#/connections/database/), select your database connection.

2. Select the **Custom Database** tab.

3. Next to **Context object in database scripts**, select **Enable**.

4. In the **Are you absolutely sure?** window that opens, select **Confirm**.

Next, add the `context` object to your database action scripts. This parameter directly precedes the `callback` parameter. For example, in the Login script function signature:

```js Original Login script function signature theme={null}
function login(email, password, callback) { ... }
```

```js Login script function signature with the context object theme={null}
function login(email, password, context, callback) { ... }
```

The `context` object contains Organization data in the following format:

```json lines theme={null}
{
    "organization": {
        "display_name": "My Organization",
        "id": "org_XXXXXX",
        "metadata": {
            "example": "value"
        },
        "name": "my-organization"
    }
}
```

When events are triggered with Organization context, the corresponding data is made available to all database action scripts except the [Delete script](/docs/authenticate/database-connections/custom-db/templates/delete), which is always passed an empty `context` object.

## Limits and considerations

* Auth0 does not sanitize or validate any username/password combination passed by a custom database.

* Database action scripts are subject to Auth0's [Rate Limit Policy](/docs/troubleshoot/customer-support/operational-policies/rate-limit-policy).
