Migrating Users to Passage

Learn how to easily migrate to Passage

In this guide we will cover paths for two scenarios:

  • You want to use Passage as a complete identity provider

  • You want to use Passage for authentication but not as a full user management system

Using Passage for authentication & user management

This is best for apps without a large legacy codebase and complex user model. Since you are leveraging Passage as the source of truth for all user data, this is the simplest migration path.

At a high level, you will create your desired metadata schema for any user data you want to store. Then you will use the Passage API or the Import Users functionality in Console to migrate all of your user data.

Created Metadata Schema

In the Passage Console, create metadata fields for any user data you want to store beyond our standard identifiers. This is typically public information like names, but could also be internal information like roles or group IDs. This schema should be created before uploading users to ensure that all data gets properly imported. Learn all about this by reading our guide here.

Import User Data

You can do this via the Console or the Management API. If you use the Console, the Import Users button will provide you a template CSV file with all the fields you need to provide. Fields can be left blank if you don't have information for all users. Fill out and upload the CSV file to Passage.

Once complete, your users can successfully sign in and register with Passage! Follow the Passage Quickstart Docs to setup your front-end and back-end.

Using Passage for authentication only

This is best for apps with a complex user model, enabling you to leverage Passage for passwordless authentication while you migrate user management over time. Passage will perform authentication while keeping your user model up to date as the source of truth for your application logic.

High Level Flow

Import user identifiers into Passage

For this use case, you will only need to import user identifiers (e.g. emails or phone numbers) into Passage. You can do this via the Console or the Management API. If you use the Console, the import users button will provide you a template CSV file. Fill out and upload the CSV file to Passage.

Populate your users table with PassageIDs

Once users are uploaded, you can either use the response from the Import API or List Users API endpoint to get a list of users and their Passage ID's. Perform a schema migration to add a passage_id column to your users table, then populate the new column with the results of the above API operation.

Note: You could also update the users' Passage ID in an on-demand fashion the next time they login using the backend SDKs.

Implement middleware

For the most part, you can implement the backend auth middleware using the same pattern you would for any Passage application. You can see examples for the supported languages here.

The main difference is that the middleware will need to set the user context based on the application's user table after authenticating with Passage. To account for new and existing users, you will want to implement a function that gets the user information based on the Passage ID if it exists, or creates a new user. This allows you to set your user data on the request context and ensures that a user is created on your model if they register after the initial one time user import. The middleware would look like this:

let passageUserSyncMiddleware = (() => {
    return async (req, res, next) => {
        try {
            let userID = await passage.authenticateRequest(req);
            if (userID) {
              // Use the Passage User ID to find a match in your user system 
              // return it to set the context 
	      req.userID = yourController.getOrCreateUser(userID)
        } catch(e) {
            // failed to authenticate
            res.status(401).send('Could not authenticate user!');

app.get("/login", passageUserSyncMiddleware, async(req, res) => {
    let userID = req.userID
    // logic  
app.get("/dashboard", passageUserSyncMiddleware, async(req, res) => {
    let userID = req.userID
    // logic  

Managing User Updates

If you choose to use the Passage Profile element to allow your users to manage their identifiers and devices, we recommend checking the user information via the Passage SDK before sending emails to the user for other purposes.

End user impact and communication

Once Passage is live on your site, each of your users will need to login on their next visit. On first login attempt they will be prompted to go through a magic link flow to verify their identity and add a device to their account to use for sign-in. No password reset flow is needed!

Regardless of which approach you take, communicating with your users is critical to ensuring a good experience and smooth transition. We recommend including a quick intro on your login and registration pages to explain the change. Here’s an example:

If you need assistance with migration to Passage, don't hesitate to reach out to us at [email protected].

Last updated