接続のパスキー 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"}'