Authenticate with Your Own User Store
Availability varies by Auth0 plan
Your Auth0 plan or custom agreement affects whether this feature is available. To learn more, read Pricing.
Use a custom database connection when you want to provide access to your own independent (legacy) identity data store for the following purposes:
Authentication: Use your database as an identity provider in Auth0 to authenticate users. (Referred to as legacy authentication.)
Import Users: Use automatic migration (trickle or lazy migration)
Proxy access to an Auth0 tenant: Use Auth0 multi-tenant architecture.
You can create and configure a custom database connection by doing one of the following tasks:
Use the Create connections endpoint with the
auth0
strategy.Navigate to Auth0 Dashboard > Authentication > Database, create the connection, and enable the Use my own database option to allow database action script editing.
How it works
As shown in the diagram below, you use custom database connections as part of Universal Login workflow in order to obtain user identity information from your own, legacy identity store.
In addition to artifacts common for all database connection types, a custom database connection allows you to configure action scripts: custom code that’s used when interfacing with your legacy identity store. Auth0 provides custom database action script templates for configuration, and the ones you use will depend on whether you are creating a custom database connection for legacy authentication or for automatic migration.
Best practice
Action scripts can be implemented as anonymous functions, however anonymous functions make it hard in debugging situations when it comes to interpreting the call-stack generated as a result of any exceptional error condition. For convenience, we recommend providing a function name for each action script.
Legacy authentication scenario
In a legacy authentication scenario, a new user record is created within Auth0 during the user's first login, but Auth0 does not store a hash of the user's password. Auth0 will always use the legacy identity store and the identity it contains when authenticating the user.
Automatic migration scenario
During automatic or trickle migration, Auth0 creates a new user in an identity store (database) managed by Auth0. From then on, Auth0 always uses the identity in the Auth0 managed identity store for authenticating the user. For this to occur, first Auth0 requires the user be authenticated against the legacy identity store and only if this succeeds will the new user be created. The new user will be created using the same id and password that was supplied during authentication.
Best practice
Creation of a user in an automatic migration scenario typically occurs after the login
action script completes. We therefore recommend that you do not attempt any deletion of a user from a legacy identity store as an inline operation (i.e., within the login
script) but perform the deletion as an independent process. This will prevent accidental deletion of a user should an error condition occur during the migration process.
In an automatic migration scenario, users remain in the legacy identity store and can be deleted or archived if required. One side effect of this can occur if a user is deleted from Auth0 but still remains present in the legacy identity store. In this case, a login actioned by the deleted user could result in either the login
and/or getUser
script being executed and the user being migrated from the legacy identity store once again.
Best practice
We recommend marking any legacy user identity as having been migrated before either login
or getUser
completes and prior to any eventual legacy store deletion.
Size
The total size of implementation for any action script should not exceed 100 kB. The larger the size the more latency is introduced due to the packaging and transport process employed by the Auth0 serverless Webtask platform, and this will have an impact on the performance of your system.
Environment
Action scripts execute as a series of called JavaScript functions in an instance of a serverless Webtask container. As part of this, a specific environment is provided, together with a number of artifacts supplied by both the Webtask container and the Auth0 authentication server (your Auth0 tenant) itself.
npm modules
Auth0 serverless Webtask containers can make use of a wide range of npm modules; npm
modules not only reduce the overall size of action script code implementation, but also provide access to a wide range of pre-built functionality.
Many publicly available npm
modules are supported out-of-the-box. The list has been compiled and vetted for any potential security concerns. If you require an npm
module that is not supported out-of-the-box, then you can make a request through the Auth0 support portal or your Auth0 representative. Auth0 will evaluate your request to determine suitability. There is currently no support in Auth0 for the user of npm
modules from private repositories.
Variables
Auth0 action scripts support environment variables, accessed via what is known as the globally-available configuration
object. To learn more, read the Add Configuration Parameters section in Create Custom Database Connections.
Best practice
The configuration
object should be treated as read-only, and should be used for storing sensitive information such as credentials or API keys for accessing external identity stores. This mitigates having security sensitive values hard coded in an action script.
The configuration object can also be used to support whatever Software Development Life Cycle (SDLC) strategies you employ by allowing you to define variables that have tenant specific values. This mitigates hard coded values in an action script which may change depending upon which tenant is executing it.
global object
Auth0 serverless Webtask containers are provisioned from a pool that's associated with each Auth0 tenant. Each container instance makes available the global
object, which can be accessed across all action scripts that execute within the container instance. The global
object acts as a global variable that’s unique to the container, and that can be used to define information or functions used across all action scripts that run in the container instance.
This means that the global
object can be used to cache expensive resources as long as those resources are not user-specific. For example, you could use it to store an Access Token for a third-party (logging) API that provides non-user-specific functionality. Or you could store an Access Token to your own non-user-specific API defined in Auth0 and obtained via the Client Credentials Flow.
Each time a Webtask container is recycled, or for each instantiation of a new Webtask container, the global
object it defines is reset. Thus, any declaration of assignment within the global
object associated with a container should also include provision for initialization too.
Best practice
To provide performance flexibility, serverless Webtask containers are provisioned in Auth0 on an ad-hoc basis and are also subject to various recycle policies. In general, we recommend that you do not consider the life of a global
object to be anything more than 20 minutes.
Security
Access legacy identity storage via custom API
Protecting legacy identity storage from general access is a recommended best practice. Exposing a database directly to the internet, for example, can be extremely problematic: database interfaces for SQL and the like are extremely open in terms of functionality, which violates the principle of least privilege when it comes to security.
Best practice
We recommend that you implement an API to provide least privilege to your legacy identity store (database), rather than simply opening up general access via the internet.
The alternative is to create a simple (custom) API, protected via use of an access token, that each action script can call. This would act as the interface to the legacy identity store. Client credentials grant flow can then be used to obtain an access token from within a script, and this can subsequently be cached for reuse in the global
object in order to improve performance. The API can then provide a discrete number of protected endpoints that perform only the legacy management functionality required (for example, read user
, change password
).
Best practice
By default, Auth0 will give you a token for any API if you authenticate successfully and include the appropriate audience. Restricting access to the legacy identity store API by restricting access token allocation via use of a Rule, will prevent unauthorized usage and mitigate a number of attack vector scenarios, such as where redirect to /authorize
is intercepted and the audience to the API is added.
Allowlist access to legacy identity storage
Whether managing access to a legacy identity store via custom API, or using the native interface provided, restricting access to the list of IP addresses associated with your Auth0 tenant. Allowlisting constrains access to the legacy identity store ensuring that only custom database action scripts defined in Auth0 are permitted.