本記事は 2025年5月16日 に更新された「How to Migrate Users to Auth0: A Technical Guide」を翻訳した記事です。
はじめに
今日のデジタル環境において、アイデンティティ管理はアプリケーションのセキュリティとユーザーエクスペリエンスにとって極めて重要です。組織が成長、進化するにつれて、アイデンティティ基盤の統合や最新化が必要になることがよくあります。主要なIDaaS (Identity-as-a-Service) プラットフォームであるAuth0は、認証と認可を管理するための堅牢で柔軟なソリューションを提供します。既存ユーザーを新しいプラットフォームへ移行させるのは、複雑な作業になる場合があります。不適切な移行は、ユーザーの不満、セキュリティの脆弱性、そして潜在的なビジネスの中断につながる可能性があります。Auth0は、このプロセスをできるだけシンプルにすることを目指しています。
本記事では、ユーザーベースをAuth0に移行するための包括的なガイドを提供します。Auth0が提供する主要な戦略は、自動移行 (トリクル移行または遅延移行とも呼ばれます) と、Management APIを使用した一括移行です。これらについて詳しく解説します。一定期間トリクル移行を利用し、その後残りのユーザーベースを一括でインポートするなど、両方の方法を組み合わせることも一般的です。各方法にはそれぞれの利点と考慮事項があり、適切なアプローチの選択は、特定の要件、技術的な制約、ユーザーへの影響の許容度に大きく依存します。これらの方法を理解し慎重に計画することで、Auth0プラットフォームへのユーザーのスムーズで安全な移行を実現できます。
移行戦略の選択
技術的な実装に入る前に、適切な移行戦略を選択することが最も重要です。Auth0は、主に自動 (トリクル/遅延) 移行と一括移行という異なるアプローチを提供しており、それぞれが異なるシナリオに適しています。最適な選択は、組織とユーザーベースに特有のいくつかの重要な要素を慎重に評価することにかかっています。
考慮すべき主な要因
- ダウンタイムの許容度: 移行中にアプリケーションのダウンタイムを許容できますか。一括移行では、特にレガシーシステムをオフラインにする必要がある場合、メンテナンス期間が必要になることがあります。一方、自動移行はユーザーのログイン中に透過的に行われるように設計されており、中断を最小限に抑えます。
- ユーザーエクスペリエンスへの影響: ユーザーは変更に対してどの程度敏感ですか。自動移行は通常、最もシームレスなエクスペリエンスを提供します。ユーザーは移行されていることに気づかず、パスワードをリセットする必要もありません。一括移行では、特に互換性のないパスワードハッシュの場合、移行後の初回ログイン時にユーザーにパスワードリセットフローが必要になる可能性があり、これが摩擦を引き起こす可能性があります。
- データの複雑さ: ユーザープロファイルの豊富さを考慮してください。移行対象はユーザー名とパスワードだけですか、それとも複雑なカスタム属性、ロール、権限、多要素認証 (MFA) の登録情報などがありますか。どちらの方法も追加データの移行をサポートしていますが、その複雑さは、データマッピングとスクリプト作成 (自動) またはデータ変換 (一括) に必要な労力に影響を与える可能性があります。
- セキュリティ要件: 現在、ユーザーのパスワードはどのように保存されていますか。レガシーシステムがAuth0と互換性のないハッシュアルゴリズムを使用している場合、自動移行のパスワード検証スクリプトは慎重な実装が必要です。一括移行ではパスワードハッシュをエクスポートする必要があるため、エクスポートとインポートのプロセス中に厳格なセキュリティプロトコルが求められます。ハッシュがエクスポートできない、または互換性がない場合は、パスワードリセット戦略が避けられません。
- レガシーシステムの可用性: 自動移行では、移行期間中、レガシーユーザーデータベースがアクセス可能であり、Auth0からの認証要求に応答し続ける必要があります。一括移行では、データのエクスポート後、レガシーシステムをより早く廃止できます。
- 移行のタイムライン: 一括移行は、一般的に全体の移行をより速く完了でき、定義された期間内にすべてのユーザーを移動させます。自動移行はユーザーがログインするにつれて段階的に行われるため、ユーザーベース全体の完了にはるかに長い時間がかかる可能性があります。
- 技術リソース: チームのスキルと可用性を評価してください。自動移行には、カスタムデータベーススクリプト (通常はAuth0内のJavaScript) の記述能力が必要です。一括移行には、データ抽出、変換、そして場合によってはAuth0 Management APIとの対話スクリプトの作成が必要です。
概要比較
これらの要素を特定のコンテキストと照らし合わせて慎重に検討することで、自動移行、一括移行、または両方の方法を使用する戦略のどれがAuth0への移行に最適かを判断できます。
ユーザーの自動移行 (トリクル/遅延移行)
ユーザーの自動移行は、トリクル移行または遅延移行とも呼ばれ、ユーザーにパスワードのリセットを要求したり、移行に気づかせたりすることなく、レガシーIDシステムからAuth0へ透過的にユーザーを移行させる戦略です。この方法はAuth0のカスタムデータベース接続機能を利用し、ユーザーがAuth0経由でアプリケーションにログインしようとするたびに、個別に移行します。
コンセプト
基本的な考え方はシンプルです。ユーザーがログインしようとすると、Auth0はまずその接続のAuth0データベースにユーザーがすでに存在するかどうかを確認します。ユーザーが存在する場合 (つまり、すでに移行済みの場合) 、Auth0は直接ユーザーを認証します。ユーザーがAuth0に存在しない場合、Auth0はカスタムDBスクリプトを呼び出してユーザーの移行を開始します。これらのスクリプトは、レガシーデータベースに接続し、ユーザーが入力した認証情報をレガシーストアに対して検証し、検証が成功するとユーザーのプロファイル情報をAuth0に返します。その後、Auth0は返されたデータを使用して自社のデータベースにユーザーのプロファイルを自動的に作成し (提供されたパスワードを最新の標準でハッシュ化することを含む) 、ログインを完了します。以降、そのユーザーのログインはAuth0が直接処理し、レガシーデータベースを完全にバイパスします。この方法を一定期間使用し、その後自動的に移行されなかったユーザーを一括で移行するのが一般的です。
長所
- シームレスなユーザーエクスペリエンス: パスワードハッシュに互換性があるか、スクリプトで検証できるユーザーにとって、移行は目に見えません。既存の認証情報で中断なくログインでき、パスワードをリセットする必要もありません。
- 段階的な展開: ユーザーがアプリケーションを操作するにつれて移行が自然に行われるため、大規模な一括移行に伴うリスクを低減します。
- 初期作業の軽減: 一括移行とは異なり、ユーザーベース全体を同時にエクスポートして変換する必要がないため、初期のデータ処理作業が少なくなる場合があります。
短所
- レガシーシステムへの依存: 移行期間中、レガシーユーザーデータベースはAuth0が未移行ユーザーを照会するために、常に稼働し、アクセス可能で、高性能である必要があります。
- 長期化する移行タイムライン: すべてのアクティブなユーザーがログインして移行されるまでにかなりの時間がかかる可能性があり、非アクティブなユーザーはこの方法では移行されないかもしれません。
- 初回のログインがわずかに遅くなる: 移行中のユーザーの最初のログイン試行には、追加のステップ (カスタムスクリプトとレガシーDBの呼び出し) が含まれるため、その後のログインと比較してわずかな遅延が発生する可能性があります。
- スクリプトの複雑さ: カスタムスクリプトを実装するには、パスワード検証、エラー条件、データマッピングを慎重に処理する必要があります。
前提条件
- カスタムデータベース機能を含むAuth0プラン。
- レガシーユーザーデータベースへのアクセス認証情報と接続詳細。
- Auth0のサーバーがレガシーデータベースに到達できるネットワークパス (ファイアウォールが適切に設定されていることを確認してください) 。
- レガシーシステムでパスワードがどのようにハッシュ化されているかの理解。
設定手順
自動移行の設定には、Auth0ダッシュボード内で特定の種類のデータベース接続をセットアップし、必要なアクションスクリプトを実装することが含まれます。
- カスタムデータベース接続の作成:
Auth0ダッシュボード > Authentication > Database
に移動します。Create DB Connection
をクリックします。名前 (例:legacy-users-migration
) を付けてCreate
をクリックします。 - カスタムデータベースの有効化: 接続の設定で、
Custom Database
タブに移動します。Use my own database
のスイッチをONに切り替えます。これにより、データベースアクションスクリプトセクションが表示されます。 - Auth0へのインポートを有効化: 接続の
Settings
タブに移動します。下にスクロールし、Import Users to Auth0
のスイッチをONに切り替えます。この重要なステップにより、Auth0はカスタムスクリプトによる認証成功後にユーザーを自身のデータベースに保存するようになります。Save
をクリックします。 - データベースアクションスクリプトの実装:
Custom Database
タブに戻ります。少なくともLogin
スクリプトを実装する必要があります。Login
スクリプト (必須): このスクリプトは自動移行の中心です。ユーザーが入力したemail
(またはユーザー名) とpassword
、そしてcallback
関数を受け取ります。- 目的: 提供された
password
をレガシーデータベース内のユーザーのレコードと照合して検証します。パスワードハッシュの比較を正しく処理します (例: レガシーDBがbcryptを使用している場合はbcrypt.compare
を使用) 。 - 成功時: 認証情報が有効な場合、レガシーデータベースからユーザーのプロファイルデータを取得します (少なくとも
user_id
とemail
を含める必要があり、email_verified
やname
、カスタムフィールドなどの関連属性もすべて含めます) 。callback
関数を、エラーにはnull
、ユーザープロファイルオブジェクトにはcallback(null, userProfile);
として呼び出します。 - 失敗時: 認証情報が無効な場合、またはレガシーDBにユーザーが存在しない場合は、エラーオブジェクトを指定して
callback
を呼び出すか (例:callback(new Error('Invalid credentials'));
) 、Auth0にユーザーが見つからないとして処理させたい場合は単にcallback(null, null);
を呼び出します。 - コード例 (概念的なNode.js形式):
- 目的: 提供された
function login (email, password, callback) { // 1. Connect to your legacy database legacyDb.connect(function(err, client) { if (err) return callback(err); // 2. Find user by email in the legacy DB client.query('SELECT id, email, hashed_password, name FROM users WHERE email = $1', [email], function(err, result) { if (err || result.rows.length === 0) { // User not found or DB error return callback(null, null); } const user = result.rows[0]; // 3. Compare the provided password with the stored hash bcrypt.compare(password, user.hashed_password, function(err, isValid) { if (err || !isValid) { // Password mismatch or bcrypt error return callback(new Error('Invalid credentials')); } // 4. Construct Auth0 user profile const userProfile = { user_id: user.id.toString(), // Must be a string email: user.email, name: user.name, // Add other custom attributes from your legacy DB here email_verified: true // Assuming email is verified in legacy DB }; // 5. Return profile to Auth0 for migration callback(null, userProfile); }); }); }); }
Get User
スクリプト (任意ですが推奨): このスクリプトは、サインアップ試行時 (レガシーDBにユーザーがすでに存在するかチェックするため) 、Auth0経由で開始されたパスワード変更時、または特定のManagement API呼び出し時などのシナリオで実行されます。email
(またはユーザー名) とcallback
を受け取ります。目的: パスワードを検証せずにレガシーデータベースからユーザーのプロファイルを取得します。これは、ログインフロー外で変更が発生した場合でもAuth0のプロファイルを同期させたり、重複サインアップを防いだりするのに役立ちます。
実装:
Login
スクリプトと似ていますが、メール/ユーザー名に基づいてユーザープロファイルを取得するだけで、見つかった場合はcallback(null, userProfile)
、見つからない場合はcallback(null, null)
を呼び出します。
- 接続のテスト: アプリケーションで接続を有効にする前に、アクションスクリプトエディタ内の「Try」ボタンを使用して、サンプル認証情報でスクリプトをテストします。
移行後
ほとんどまたはすべてのアクティブなユーザーが移行されたと確信できたら (Auth0データベース接続のユーザー数とレガシーシステムを比較して監視できます) 、レガシーデータベースへの依存を断ち切ることを検討します。
- アクションスクリプトの更新:
Login
とGet User
の両スクリプトを、単にcallback(null, null);
を返すように変更します。これにより、Auth0がレガシーデータベースを照会するのを効果的に停止します。 - 「Import Users to Auth0」を有効のままにする: 重要なのは、接続設定で
Import Users to Auth0
トグルを無効にしないことです。ユーザーがインポートされた後にこれを無効にすると、Auth0は (現在は機能しない) スクリプトを常に呼び出すようになり、実質的にユーザーをロックアウトしてしまいます。これを有効にしておくことで、Auth0はすでに移行されたユーザーに対して内部ストアを引き続き使用します。 - レガシーデータベースの廃止: この時点で、レガシーユーザーデータベースインフラの廃止を安全に計画できます。
ユーザーの一括移行
ユーザーの一括移行は、段階的でログイン時にトリガーされる自動移行とは異なるアプローチです。これはレガシーシステムからユーザーデータをエクスポートし、通常は計画されたオフラインプロセスとして、バッチでAuth0にインポートします。この戦略は、より速い全体的な移行タイムラインが望まれる場合や、レガシーシステムを比較的迅速に廃止する必要がある場合にしばしば好まれます。
コンセプト
基本的なプロセスは、既存のIDストアから、非常に重要なパスワードハッシュを含むユーザープロファイル情報を抽出することです。このデータは、Auth0が理解する特定の形式 (通常はJSON) に変換されます。最後に、Auth0のツール (主にManagement APIまたはユーザーインポート/エクスポートエクステンション) を使用してこのデータをアップロードし、Auth0テナントのデータベース接続内に対応するユーザープロファイルを作成します。
長所
- より速い移行タイムライン: 比較的短く、定義された期間内に多数のユーザーを移行できます。
- レガシーシステムの廃止: レガシーIDシステムをより早くオフラインにできるため、運用コストと複雑さを削減できる可能性があります。
- 予測可能なプロセス: 移行は計画された期間内に行われるため、ユーザーが個別にログインするのを待つよりも予測可能性が高まります。
短所
- ユーザーの中断の可能性: レガシーのパスワードハッシュがAuth0と互換性がない場合、または安全にエクスポートできない場合、ユーザーは移行後の最初のログイン時にパスワードをリセットする必要がある可能性が高く、ユーザーエクスペリエンスに影響を与える可能性があります。
- データ処理の複雑さ: ユーザーデータを必要な形式に慎重に抽出し、検証し、変換する必要があります。データの誤りはインポートの失敗を引き起こす可能性があります。
- セキュリティに関する考慮事項: ユーザーデータ、特にパスワードハッシュをエクスポートするには、転送中および保存中のデータを保護するために厳格なセキュリティ対策が必要です。
- ダウンタイムの可能性: 必要な調整や、インポート中にレガシーシステムをオフラインにするかどうかによっては、メンテナンス期間が必要になる場合があります。
手法の概要
Auth0は、ユーザーを一括インポートするための2つの主要なメカニズムを提供します。
- Management API (
POST /api/v2/jobs/users-imports
): これは、特に大規模なユーザーベースや自動化が望まれる場合に、ほとんどのシナリオで推奨されるアプローチです。プログラムによる対話を通じて、より高度な制御、柔軟性、およびスケーラビリティを提供します。 - ユーザーインポート/エクスポートエクステンション: Auth0ダッシュボードで利用可能なツールで、ユーザーファイル (JSONまたはCSV) をアップロードするためのユーザーインターフェースを提供します。小規模な手動インポートには簡単ですが、大規模または自動化された移行にはあまり適していません。
このガイドでは、典型的な移行プロジェクトに対する堅牢性の観点から、Management APIを使用する方法に焦点を当てます。
Management API (/api/v2/jobs/users-imports
) の使用
この非同期エンドポイントを使用すると、ユーザーデータファイルを送信してインポートジョブを開始できます。
前提条件
- ターゲットのAuth0接続: ユーザーがインポートされる既存のAuth0データベース接続が必要です。その
connection_id
をメモしておきます。 - Management APIトークン: Auth0ダッシュボード (
Applications -> APIs -> Auth0 Management API -> API Explorer
タブ) からAPIトークンを取得します。このトークンにはcreate:users
権限 (スコープ) が必要です。 - ユーザーデータ抽出: レガシーシステムから抽出したユーザーデータを含むファイル。
パスワードハッシュ - 重要な考慮事項
パスワードのリセットを強制せずにパスワードを正常に移行できるかどうかは、レガシーシステムのパスワードハッシュアルゴリズムがAuth0と互換性があるかどうかにかかっています。Auth0は、いくつかの標準的なハッシュアルゴリズム (例: bcrypt, PBKDF2, scrypt - 現在のリストと特定のパラメーターについてはAuth0のドキュメントを確認してください) をサポートしています。
- 互換性のあるハッシュ: レガシーハッシュに互換性がある場合は、インポートファイルに直接含めることができます。Auth0は形式を認識して安全に保存するため、ユーザーは既存のパスワードでログインできます。
- 互換性のないハッシュ: レガシーアルゴリズムがサポートされていない場合、またはハッシュを安全にエクスポートできない場合は、パスワードを直接移行できません。この場合:
- インポートファイルからパスワードハッシュを省略します。
- ユーザーは、インポートされた後の最初のログイン試行時にパスワードリセットを実行する必要があります。
- この要件を事前にユーザーに明確に伝えます。
- セキュリティ: 平文のパスワードは決してインポートしないでください。常にハッシュで作業してください。
ユーザーデータファイルの準備
- 形式: APIエンドポイントは、JSONファイル形式のユーザーデータを想定しています。JSON配列の各エントリが1人のユーザーを表します。
- スキーマ: 各ユーザーオブジェクトの構造は、Auth0の要件に準拠する必要があります。主なフィールドは次のとおりです。
email
(string, 必須)email_verified
(boolean, 必須)user_id
(string, 任意ですがレガシーIDとのリンクに推奨)password_hash
(object, パスワード移行時に必須 - アルゴリズムに基づいた構造についてはAuth0ドキュメントを参照)app_metadata
(object, 任意)user_metadata
(object, 任意)custom_password_hash
(object, カスタムスクリプトを使用する場合の非対応ハッシュ用 - 一括インポートではあまり一般的ではない)- すべてのフィールドとパスワードハッシュ構造の正確な詳細については、公式の一括インポートデータベーススキーマと例のドキュメントを参照してください。
- ファイルサイズの制限: 各インポートジョブは、最大500KBのJSONファイルを受け付けます。より大きなユーザーベースの場合は、データを複数のファイルに分割し、複数のインポートジョブを送信します。
- ストリーミング: APIエンドポイントは、ストリームデータを処理するように設計されています。
curl
やNode.jsのようなツールを使用する場合は、ファイル全体をメモリにロードするのではなく、ファイルコンテンツをストリーミングしていることを確認してください。
インポートジョブの開始
/api/v2/jobs/users-imports
エンドポイントにPOST
リクエストを送信することでインポートをトリガーします。これはmultipart/form-data
リクエストです。
- ヘッダー:
Authorization: Bearer YOUR_MGMT_API_TOKEN
を含めます。 - フォームデータパラメーター:
users
: ユーザーデータを含むJSONファイル。connection_id
: ターゲットのAuth0データベース接続のID。upsert
(boolean, 任意, デフォルト:false
):true
の場合、ジョブはemail、user_idなどで一致する既存のAuth0ユーザーの更新を試みます。特定のフィールドのみを更新するため、注意して使用してください。false
の場合、重複ユーザーが見つかるとジョブは失敗します。external_id
(string, 任意): 追跡目的でジョブに割り当てることができるカスタム識別子。send_completion_email
(boolean, 任意, デフォルト:true
): ジョブの完了または失敗時にAuth0がテナント管理者にメールを送信しないようにする場合はfalse
に設定します。
例 (curl
):
curl --request POST \ --url https://YOUR_DOMAIN/api/v2/jobs/users-imports \ --header 'Authorization: Bearer YOUR_MGMT_API_TOKEN' \ --form 'users=@"/path/to/your_users.json"' \ --form 'connection_id="con_xxxxxxxxxxxxxxxx"' \ --form 'send_completion_email=false'
ジョブの監視
最初のPOST
リクエストは、ジョブIDとpending
ステータスを返してすぐに完了します。
{ "status": "pending", "type": "users_import", "created_at": "2025-04-30T19:00:00.000Z", "id": "job_xxxxxxxxxxxxxxxx" }
一括インポートは非同期プロセスです。ジョブのIDを使用してステータスをポーリングする必要があります。
- エンドポイント:
GET /api/v2/jobs/{id}
({id}
は上記のレスポンスからのjob_id
) 。 - リクエスト: APIトークンを含む
Authorization
ヘッダーを含めます。 - レスポンス: レスポンスには現在のステータス (
pending
,processing
,completed
,failed
) が表示され、完了時には作成、更新、失敗したユーザー数を含むサマリーと、ジョブが失敗した場合の具体的なエラー詳細が表示されます。
同時実行数の制限
Auth0は通常、同時一括インポートジョブを制限している (多くの場合2つ) ことに注意してください。同時に多すぎるジョブを送信すると、429 Too Many Requests
エラーを受け取ります。新しいジョブを送信する前に、既存のジョブが完了するのを待ってください。
Management APIを使用した一括移行は、特に自動化と速度が重要な要件である場合に、ユーザーをAuth0に移行するための強力でスケーラブルな方法を提供します。データ抽出、変換、パスワードハッシュ、およびジョブの監視に関する慎重な計画が成功の鍵となります。
Auth0でIDスタックを最新化しませんか?
自動移行によるシームレスなユーザーエクスペリエンスを求める場合でも、一括移行スクリプトの制御を好む場合でも、適切なアプローチを選択すれば、ユーザーに中断を与えることなくアップグレードできます。完全なガイドで実装の詳細を確認し、アーキテクチャに合った移行パスを選択してください。
参考資料
About the author

David Bolton
Senior Engineer, Office of the Field CTO
David started in the technical field with Apple nearly a decade ago. He then held various positions in the industry, from software engineering to founding ambassador. David developed a passion for cybersecurity, leading to his joining Auth0 four years ago. He has since worked pre- and post-sales, specializing in designing scalable AuthZ and AuthN solutions for large enterprises and on the Okta for Good leadership council.
When not working, he is likely playing tennis, tinkering with a computer, or searching for a new restaurant to try.