Last Updated: Sep 27, 2024
Overview
This article explains how to migrate users using the Password Hashes export from Auth0.
Applies To
- Export
- Password Hashes Export
- Migrate users
- Connections
Solution
Data format
The provided file is in NDJSON format (New line delimited JSON ). The export file would look like this:
{ ... one user... }
{ ... another user ... }
{ ... and so on ... }
Each user object will have some properties. Most of them are self-explanatory, but it’s good to clarify a couple of them related to the user id. A sample single user would look like this (formatted for better readability):
{
"_id":{"$oid":"5dea9f9c82dd7c0e76e4ec93"},
"email_verified":false,
"email":"nico9090@nico.com",
"passwordHash":"$2b$10$.qHPp/srqo1NAAAAAvlkmOdqAbH2Rg0qPv2Txj3ZwXfjJnewSjc4m",
"password_set_date":{"$date":"2019-12-06T18:36:12.412Z"},
"tenant":"nico-sabena",
"connection":"Username-Password-Authentication",
"_tmp_is_unique":true,
"alt_id":"euclid"
}
Every user will have an _id field, while the alt_id is optional. alt_id
will be present on users coming from a custom DB (where the custom DB script provides the user id) or when creating regular DB connection users with the Management API v2 and providing a custom user id.
In the above case, the user identifier is likely to be something like auth0|euclid. If the alt_id field was not present, then the full user_id would be auth0|5dea9f9c82dd7c0e76e4ec93.
The connection parameter is important if the export was requested from multiple databases, as that is the field that indicates where the user came from.
Is it possible to use this file to import directly to Auth0 (e.g., with the Users Import Extension)?
No, not really. The format accepted by the Bulk Import Users API (or extension) is different. The full specification can be found at Bulk User Import Database Schema and Examples. Some important things to consider:
- The size of the import file is limited to 500kb
- The expected format is a JSON array, not NDJSON.
- To import the original user ids, provide a
user_id
field with the value found in the exported user’salt_id
(if present), or the$oid
value.
E.g., for the sample user above:
[
{
"user_id":"euclid", // to keep the same user id
"email_verified":false,
"email":"nico9090@nico.com",
"password_hash":"$2b$10$.qHPp/srqo1NAAAAAvlkmOdqAbH2Rg0qPv2Txj3ZwXfjJnewSjc4m"
},
{...} // other entries in the array
]
To keep the user id when this user did not have an alt_id
:
[
{
"user_id":"5dea9f9c82dd7c0e76e4ec93", // to keep the same user id
"email_verified":false,
"email":"nico9090@nico.com",
"password_hash":"$2b$10$.qHPp/srqo1NAAAAAvlkmOdqAbH2Rg0qPv2Txj3ZwXfjJnewSjc4m"
},
{...} // other entries in the array
]
Using jq to convert data
While it is possible to convert data in different ways, a useful tool is jq.
This command will read an input file (input.json
), pipe it through a couple of jq filters, and write it in an output file that’s ready to import (output.json
):
cat input.json | jq '{user_id: (if has("alt_id") then .alt_id else ._id."$oid" end), email, username, email_verified, password_hash: .passwordHash}' | jq -s 'del(.[][] | nulls)' > output.json
The first jq
pass picks relevant fields, and the second one removes null values and transforms the input into one big array.
The above command will pick the alt_id
as the user id, and use the _id.$oid
if alt_id
is not available.
Alternatively, use the alt_id
if present and let Auth0 assign a random user_id
if the alt_id
is not provided by replacing ._id."$oid
with null
:
cat input.json | jq '{user_id: (if has("alt_id") then .alt_id else null end), email, username, email_verified, password_hash: .passwordHash}' | jq -s 'del(.[][] | nulls)' > output.json
How to add/migrate metadata or other information too?
The password hashes export provided by Auth0 Support does not include the user metadata fields. To include it, export the data separately (the regular bulk user export from the extension or Management API v2) and merge that data with the password hashes provided by Auth0 support so that the final import file has all the data. E.g.:
[
{
"user_id":"5dea9f9c82dd7c0e76e4ec93", // to keep the same user id
"email_verified":false,
"email":"nico9090@nico.com",
"password_hash":"$2b$10$.qHPp/srqo1NAAAAAvlkmOdqAbH2Rg0qPv2Txj3ZwXfjJnewSjc4m",
[...], // other properties like these:
"given_name":"Nicolás",
"app_metadata": {
[...]
},
"user_metadata": {
[...]
}
},
{...} // other entries in the array
]