接続のパスキー rpId を変更する
POST /v1/connections/{connection_id}:change-rp-id · 権限 connections:write
パスキーの接続を新しい rpId に移し、移行期間を開始します。パスキーは登録時の rpId に紐づくため、ユーザーがパスキーを持っている場合、rpId を変更できるのはこの方法だけです。settings.rp_id を変更する PATCH は 409 rp_id_change_requires_migration で拒否されます。
移行期間中、ユーザーは以前の rpId のパスキーで引き続きサインインでき、新しいパスキーは新しい rpId で登録されます。移行期間が終了したとき、または rpId の移行を完了する で早期に終了したとき、以前の rpId に残っているパスキーは取り消されます(理由 rp_id_changed)。他のサインイン方法を持たないユーザーは、パスワードレスのメールサインインまたはアカウント復旧が必要になります。1 つの環境で同時に実行できる移行は 1 件だけです。
接続の rpId、移行レコード、管理操作の監査ログ、passkey_rp_id.migration_started イベントは一括で書き込まれます。rpId、または実行中の移行の以前の rpId に該当するカスタムドメインは削除できません(409 domain_in_use_by_rp_id)。
リクエスト
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
connection_id |
path | はい | パスキー接続の ID(conn_…)。 |
If-Match |
header | はい | 接続の ETag(接続を取得する を参照)。 |
Idempotency-Key |
header | いいえ | 再試行されたリクエストを安全にするための任意のキー(16〜64 文字)。 |
new_rp_id |
string | はい | 新しい rpId。環境内の active 状態のカスタムドメインのホスト名(小文字、IDNA A ラベル)、または各サインインホストをそれぞれ独立した rpId として使う場合は空文字列。最大 253 バイト。 |
confirm_rp_id |
string | はい | 確認用に new_rp_id をもう一度入力した値。 |
migration_window_days |
integer | いいえ | 以前の rpId のパスキーを引き続き使用できる日数。30〜365、デフォルトは 90。 |
{
"new_rp_id": "login.example.com",
"confirm_rp_id": "login.example.com",
"migration_window_days": 90
}
レスポンス
200 OK。移行の内容と、接続の新しいバージョンを示す ETag ヘッダーが返されます。
{
"id": "rpm_01j9xr4a6b8c0d2e4f6g8h0j2k",
"connection_id": "conn_01j9xp6q0r1s5t7v9w1x3y5z7b",
"previous_rp_id": null,
"new_rp_id": "login.example.com",
"status": "active",
"started_at": "2026-10-27T10:00:00Z",
"ends_at": "2027-01-25T10:00:00Z",
"completed_at": null,
"revoked_count": null,
"new_registration_count": null,
"fallback_enabled_by_migration": false
}
| フィールド | 説明 |
|---|---|
previous_rp_id, new_rp_id |
変更前と変更後の rpId。null は各サインインホストがそれぞれ独立した rpId であることを意味します。 |
status |
期間の実行中は active、期間が終了すると completed、期間の途中で早期終了した場合は completed_early。 |
ends_at |
移行期間が終了する予定の日時。 |
completed_at, revoked_count, new_registration_count |
移行が終了したときに書き込まれます。active の間は null。 |
fallback_enabled_by_migration |
パスキーが唯一の第一要素だったため、移行期間中にフォールバックのサインイン方法が有効化された場合は true。 |
エラー
| HTTP | code | 発生条件 |
|---|---|---|
| 400 | unknown_field |
ボディに未知のフィールドが含まれています。 |
| 404 | not_found |
接続が存在しないか、別の環境に属しています。 |
| 409 | rp_id_migration_in_progress |
この環境で別の rpId 移行が実行中です。 |
| 412 | precondition_failed |
If-Match が現在のバージョンと一致しません。 |
| 422 | validation_failed |
フィールドが欠落しているか、長すぎる、または範囲外です。new_rp_id が環境内の active 状態のカスタムドメインではないか、現在の rpId と同じです。confirm_rp_id が一致しません。または接続がパスキー接続ではありません(errors[].pointer: /new_rp_id, /confirm_rp_id, /migration_window_days, /connection_id)。 |
| 428 | precondition_required |
If-Match ヘッダーがありません。 |
| 401 | unauthenticated |
認証情報がないか、無効または取り消し済みです。 |
| 403 | insufficient_permissions |
認証情報に必要な権限がありません。 |
| 429 | rate_limited |
レート制限を超えました。Retry-After の期間を待ってから再試行してください。 |
| 503 | service_unavailable |
依存先のサービスが一時的に利用できません。Retry-After の期間を待ってから再試行してください。 |
例
curl -X POST "https://api.eu.keenauth.com/v1/connections/conn_01j9xp6q0r1s5t7v9w1x3y5z7b:change-rp-id" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H 'If-Match: "3"' \
-H "Content-Type: application/json" \
-d '{"new_rp_id":"login.example.com","confirm_rp_id":"login.example.com"}'
keenauth connections change-rp-id conn_01j9xp6q0r1s5t7v9w1x3y5z7b --if-match '"3"' --yes \
--data '{"new_rp_id":"login.example.com","confirm_rp_id":"login.example.com"}'