Skip to content
Published on

パスキーの可搬性は半分しか届いていない — CXFは標準になったが、CXPはいまだ2024年のワーキングドラフトのまま

シェア
Authors

はじめに — 「パスキーをエクスポートできる」という言葉が指す実際の範囲

2026年6月、Androidにパスキーのインポート/エクスポートが入りました。前年にはiOS 26が同じことをしています。見出しだけを読めば話は片づいたように見えます — パスキーはもう可搬性を持ち、ロックインの心配は解消された、と。

ところが仕様のディレクトリを直接開くと様子が違います。FIDOの資格情報交換は1つではなく2つの文書に分かれており、その完成度は桁が違います。片方は標準になり、もう片方は21ヶ月間ワーキングドラフトのままです。そして完成した側は、未完成な側にセキュリティを依存しています。

本稿はこの非対称性が実務上何を意味するかを整理します。結論を先に言えば、2026年7月時点で出荷されているのは「エコシステムを越えるパスキー可搬性」ではなく「OSが仲介する、同一デバイス内でのアプリ間の移行」です。この違いはマーケティングの文言では消えますが、アーキテクチャでは消えません。

2つの仕様、2つの速度

FIDO Allianceの仕様ディレクトリ(fidoalliance.org/specs/cx/)をそのまま読むとこうなっています。

cxf-v1.0-wd-20240522.html          CXF ワーキングドラフト    2024-05-22
cxf-v1.0-wd-20241003.html          CXF ワーキングドラフト    2024-10-03
cxf-v1.0-rd-20250313.html          CXF レビュードラフト      2025-03-13
cxf-v1.0-ps-20250814.html          CXF Proposed Standard    2025-08-14
cxf-v1.0-errata-20260309.html      CXF errata                2026-03-09
cxf-v1.0-ps-errata-20260309.html   CXF PS + errata反映済み    2026-03-09

cxp-v1.0-wd-20240522.html          CXP ワーキングドラフト    2024-05-22
cxp-v1.0-wd-20241003.html          CXP ワーキングドラフト    2024-10-03
                                   ...ここで終わり

CXF(Credential Exchange Format) は何をやり取りするか — データ構造とフォーマット — を定義します。ワーキングドラフトからレビュードラフトを経て2025年8月14日にProposed Standardとなり、2026年3月9日にerrataが付きました。標準化としては順当な軌跡です。

CXP(Credential Exchange Protocol) はどうやり取りするか — 2つのプロバイダ間の実際の転送プロトコル — を定義します。2024年10月3日のワーキングドラフトが最後です。レビュードラフトもProposed Standardもありません。今日(2026年7月16日)時点で21ヶ月間そのままです。

なお2026年3月のerrataは内容としては編集上の修正にすぎません。Appendix Aの例示ペイロードで規範本文とずれたまま残っていたhmacSecretキーをhmacCredentialsに直し、欠けていたexample-fileの内容を埋めた、それだけです。errata文書自身が「The contents of example-file were missing and cfx example was updated」と記しています。規範的な挙動が変わったわけではないので、「2026年にCXFが大きく改訂された」と読んではいけません。

CXPのワーキングドラフトが自分自身について語ること

CXPワーキングドラフトの「Status of This Document」をそのまま引くとこうです。

This is a Working Draft Specification and is not intended to be a basis for any
implementations as the Specification may change. This document is merely a FIDO
Alliance working group internal and member-confidential document. It has no
official standing of any kind and does not represent consensus of the FIDO Alliance.

No rights are granted to prepare derivative works of this Specification.

読み飛ばしてしまいがちな定型文ですが、これがパスキー可搬性という話の転送側半分だと考えると、一文一文が重く響きます。「いかなる実装の根拠とすることも意図していない」「FIDO Allianceのワーキンググループ内部の会員限定文書にすぎない」「いかなる種類の公式な地位も持たず、FIDO Allianceの合意を代表しない」。

文書の未完成度は目次にも表れています。CXP §5「Implementation Requirements」— このセクションは仕様のどのアルゴリズムと機能が実装必須かを定義するはずの節ですが — 中身は「This section defines which algorithms and features of this specification are mandatory to implement. Applications using this specification can impose additional requirements upon implementations that they use.」という2文だけで、そのまま§6 Security Considerationsに移ります。実装必須アルゴリズムの集合が空です。相互運用の土台がまだ敷かれていません。

プロトコルの骨格自体はあります。Diffie-Hellman鍵交換で2つのプロバイダ間にセキュアチャネルないしデータペイロードを作り、HPKEパラメータ(modeはbase / psk / auth / auth-psk)を折衝し、アーカイブにはDEFLATEを使います。流れはインポート側がExport Requestを作る → 権限を持つ主体が移行を決定する → エクスポート側が資格情報データを暗号化する → Export Responseを送る → インポート側がバンドルを復号する、の5段階です。設計は合理的です。ただし「設計がある」と「標準である」は別の話です。

CXFが実際に運ぶもの — 平文の秘密鍵

ここからが本題です。CXF仕様のPasskey項目におけるkeyメンバーの定義はこうです。

key
  The private key associated to this passkey instance.
  The value MUST be PKCS#8 ASN.1 DER formatted byte string which is then
  Base64url encoded.
  The value MUST give the same public key value that was provided by the
  original authenticator during registration.

仕様Appendix Aの例示ペイロードを見ると実感が湧きます。(以下はCXF PS + errata文書の例をそのまま引き写したものです。)

{
  "id": "akKA3Y0jQRuK7sKplB0Y9w",
  "title": "WebAuthn.io",
  "credentials": [
    {
      "type": "passkey",
      "credentialId": "Y3JlZGVudGlhbElkRXhhbXBsZQ",
      "rpId": "webauthn.io",
      "username": "johndoe",
      "userDisplayName": "John Doe",
      "userHandle": "cnEzaNHWcYK3coWZjvoaV1Hj9gnI12mKe2dL2HZVFlY",
      "key": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgARu_0sCt20EpgVxb4Puq3Ga5VVLpuTY75ngvZlyq3X6hRANCAASmdk1xLsK0oOlhxIPp0d1ZuS0sT9nf6BZtSelhqvLBW0fOL33l_bXgsr_STUHjCLn8l6gcRJwe7OQvbQubZ1dY"
    }
  ]
}

keyフィールドに入っているあの文字列がP-256の秘密鍵です。ラッピングも暗号化もパスフレーズもありません。同じ例では、パスワードは"value": "securepassword123"として、TOTPシードは"secret": "JBSWY3DPEHPK3PXP"として、並んで平文で入っています。

これはバグではなく設計です。CXFはフォーマットにすぎず、自身の§1.2 Scopeで明示的に線を引いています — 「This document outlines the data structures and format needed to exchange credentials and does not make any assumptions about the protocol used for the transfer, such as the protocol outlined by CXP.」転送については何の前提も置かないという意味です。つまりCXFという文書1つだけを見れば、その成果物はあなたのすべての秘密鍵とパスワードとTOTPシードが入った平文JSONです。

では機密性は誰が担うのか

CXFの§5 Security Considerationsはこの問いにこう答えます。

Note: [CXP] ensures that the credential exchange remains confidential between
the exporting provider and importing provider.

つまりCXFは「機密性はCXPが保証する」と述べ、CXPは「自分はいかなる実装の根拠とすることも意図しておらず、公式な地位もない」と述べています。完成した仕様が、未完成の仕様にセキュリティを委ねている構図です。これが本稿の核心です。

CXFはこの空白を認識しており、逃げ道を1つ用意しています。同じ§5.1はこう規定します — orchestrating party(交換を仲介する主体)はCXPを実装せずCXFだけを実装してもよい(MAY)。ただしCXPを実装しないなら、開発者は必ず(MUST)その資格情報交換のセキュリティメカニズムを文書化し、その文書を公開ウェブサイトに掲載しなければ(MUST)なりません。公開する文書には、仲介者がデータを中継するだけであること、データを保持したり他の用途に使ったりしないこと、受け取ったデータを改変せずに渡すことを明記する必要があります。

率直に読めば、これは標準化された暗号プロトコルを各ベンダー自身の文書化された約束に置き換えるものです。何もないよりはましですが、相互運用可能なセキュリティ保証とは別物です。検証可能なプロトコルの代わりに、「私たちはこうしています」という公開宣言を受け取るだけだからです。

実際に出荷されたもの — OSが仲介する同一デバイス内転送

ではAppleとGoogleが2026年に実際に出荷したのは何でしょうか。ここで先の緊張がどう解消されたかが見えてきます。

Apple。 ASCredentialExportManagerASCredentialImportManagerがiOS 26.0、iPadOS 26.0、macOS 26.0、Mac Catalyst 26.0、visionOS 26.0に入りました。Appleの開発者文書をそのまま読むと動作は明確です。

The operating system acts as an intermediary to establish the identities of the
password manager apps involved and performs the exchange; this process doesn't
write any data to the file system.

OSが仲介者として両アプリの身元を確認し、交換を直接実行し、この過程でファイルシステムには一切データを書き込みません。アプリはエクステンションのplistにSupportsCredentialExchangeを宣言し、SupportedCredentialExchangeVersionsにサポートするバージョンを配列で記す必要がありますが、Apple文書によれば現在取り得る値は1.0ひとつだけです。

この設計を見ると、なぜCXPがなくても済んだのかがわかります。同一デバイス内でOSが信頼された仲介者として振る舞えば、2つのプロバイダが互いを認証しチャネルを折衝する必要がありません。平文のCXFペイロードがディスクに落ちることなく、OSの境界の内側だけで動くからです。つまりAppleはCXPを実装したのではなく、CXPが解こうとしていた問題を迂回したわけです。プラットフォームの制御権でプロトコルを置き換えた形です。

Google。 Google Play services v26.21(2026-06-01)のリリースノートのSecurity & Privacy項目にはこう書かれています — 「[Phone] You can now import and export passwords and passkeys between Google Password Manager and third-party password managers with the Credential Exchange standard.」

ここは正確を期す必要があります。Googleの公式リリースノートは「Credential Exchange standard」とだけ書いており、CXPを名指ししていません。一部メディアは「AndroidがCXPとCXFをサポートする」と書きましたが、それは二次情報源による解釈です。Google自身の文言はそれよりも曖昧で、タグも[Phone]だけです。そして関連するSDKアーティファクトであるcom.google.android.gms:play-services-identity-credentialsは、GoogleのMavenリポジトリ上で最新版がいまだ16.0.0-alpha11です(最終更新2026-02-09)。alpha01からalpha11まで来ましたが、まだbetaにもなっていません。

まとめると、両社が実際に出荷したのは同一デバイス内でOSが仲介するアプリ間の移行です。デバイスをまたぐ転送、エコシステムをまたぐ転送 — CXPが担うはずの部分そのもの — はまだです。

移せないパスキーたち

CXFには実務者が見落としやすい規範的な制約が2つあります。どちらも「一部のパスキーはそもそもエクスポートできない」という話です。

第一に、署名カウンタが0でないパスキー。 CXF仕様のPasskey節にあるNoteをそのまま引くとこうです。

Note: Passkeys using a non-zero signature counter MUST be excluded from the export
and the exporter SHOULD inform the user that such passkeys are excluded from the
export. Importers MUST set a zero value for the imported passkey signature counters
and MUST NOT increment them after the fact.

エクスポート側は署名カウンタが0でないパスキーを必ず(MUST)除外しなければならず、インポート側はインポートしたパスキーのカウンタを0にし(MUST)、その後インクリメントしてはいけません(MUST NOT)。署名カウンタはもともと認証器の複製を検知するための仕組みであり、可搬性とは原理的に衝突します。複製を検知する仕組みと、合法的に複製する機能は両立しないからです。仕様はこの衝突を可搬性の側に倒して解決しており、その代償としてカウンタを使う資格情報は交換から外れます。

ここは仕様を正確に読む必要があります。WebAuthn Level 3 §6.1.1によれば、RPは保存済みカウンタと新たに受け取ったsignCountを比較しますが、複製の疑いと判定されるのは「どちらか一方でも0でなく(if either is non-zero)、かつ新しい値が保存値以下のとき」です。つまりカウンタが常に0のパスキーは、そもそもこの検査に引っかかりません。仕様はカウンタを実装しない認証器がsignCountを0に固定することも明記しているので、0は仕様が想定する正常値です。

したがって正直に言えば、インポートで入ってきたパスキーに起きることは「誤検知でロックされる」ではなく、単に複製検知のシグナルを失うだけです。CXFは可搬性のためにクローン検知を引き換えにしたことになります。ただし仕様より厳格なロジック — たとえば「カウンタは常に増加しなければならない」を直接実装している場合 — は話が別です。そのロジックは仕様が正常だと定めた値に引っかかり、正常なユーザーをブロックしてしまいます。ちなみに仕様は、カウンタの不一致が複製なのか誤作動なのか競合状態なのかを区別しないと明記しており、対応は各RPのリスク許容度に委ねています。

第二に、ハードウェアセキュリティキー。 こちらはより根本的です。FIDO Allianceの公式フィードバックリポジトリ(fido-alliance/credential-exchange-feedback)で、CTAP実装者が「ハードウェア認証器にある資格情報を別の認証器に移すにはどの標準を見ればよいか」と質問しました(issue #33、2025-08-02)。fido-allianceのGitHub組織メンバーの回答はこうでした。

No certified FIDO hardware authenticator allows a credential to leave its secure
element, so what you're asking for does not exist, by design.

認証済みのFIDOハードウェア認証器は、資格情報がセキュアエレメントを離れることを一切許可しておらず、これは設計上そうなっているとのことです。同じスレッドで彼は、資格情報交換はCTAPとは何の関係もなく、対象は「credential manager間のマイグレーション」だと明言しています。

2つの制約を合わせると、絵は鮮明になります。資格情報交換はソフトウェアの資格情報マネージャー同士のマイグレーションツールです。YubiKeyに入ったパスキーを移す話ではなく、今後もそうなりません。ハードウェアキーを使う組織が「もうパスキーは可搬になった」という見出しを見てバックアップ戦略を立てるなら、誤った前提の上に立てていることになります。ハードウェアキーのバックアップ戦略は依然として「2つ以上登録する」です。

まだ解けていないこと — エクスポート拒否とロックイン

可搬性の仕様が実際にロックインを防ぐのかという疑問があります。2025年1月21日に開いたissue #24「Risk of lock-in from export blocking」がこの問題を正面から提起しています。要旨はこうです — CXPはプロバイダがエクスポート要求を拒否したり選別して承認したりする余地を残しているように見え、そうなるとプロバイダFOOが値上げしたときに競合BARへのエクスポートだけを狙い撃ちで止めることができ、ユーザーの資格情報が人質になる、というものです。提起者はこれを「permissionlessly exportable」(現在のプロバイダの許可なしにエクスポートできる性質)が仕様の範囲に入るべきかという問題として整理しました。

注目すべきは回答です。CXFの貢献者として名前が挙がっているFIDO側の参加者は2025年3月に「懸念は十分に聞いており、Alliance内部でも議論が多い」と述べ、5月にはこう付け加えています。

The general vibe is supportive and language has been added to this effect, though
it looks like we haven't done a public working draft in some time so I don't think
that's externally visible yet.

内部的には関連する文言が追加されたが、公開ワーキングドラフトを長らく出していないため外部からはまだ見えていない、ということです。そして2026年7月の現時点でも依然として見えていません — 公開されている最新のCXPは、当時も今も2024年10月3日のワーキングドラフトのままだからです。issueは開いたままです。

これは仕様プロセスを非難する話ではありません。会員限定で作業を進めるのはFIDOの長年のやり方であり、標準はもともと遅いものです。ただし実務者の立場から正直に言えば、ロックイン防止の文言が実際にどう使われているかを私たちは読むことができず、読めない保証は計画に織り込めません。

同じissueスレッドに出た反論も記録しておく価値があります。一方は「サードパーティのサービスに頼ると決めた以上、どのログイン方式でも同じではないか」と述べ、提起者は、Firefoxのようなローカルのオープンソースソフトウェアならアップデートがエクスポートを止めても旧バージョンをインストールしたりコードを修正したりできるが、セキュアエレメントに入った資格情報は原理的に製造元・運用者の許可が必要だと反論し、ドメインレジストラとICANNの関係を比喩として挙げています。どちらが正しいかをここで判定するつもりはありません。ただ、この論争が2025年1月から未解決のまま開いているという事実自体が、可搬性が技術問題である以前にガバナンス問題だということを示しています。

では今、何をすべきか

実務判断に落とし込むとこうなります。

今期待してよいこと

  • 同一デバイス内で資格情報マネージャーを切り替えるシナリオ。iOS/iPadOS/macOS/visionOS 26、そしてAndroid(Play services 26.21以上、現在は[Phone])で実際に動作します。
  • CSVエクスポートを置き換えること。これがCXFの本当の成果です。CXP仕様の序文自体が問題定義としてCSVを名指ししています — 安全でないフォーマット、標準構造の欠如によるマイグレーション失敗。構造化されたJSONスキーマができただけでも、この2点は改善されます。
  • パスワード・TOTP・その他の項目まで一緒に移すこと。CXFはパスキー専用ではなく、資格情報マネージャー内の複数の項目タイプを定義しています。

まだ計画に織り込んではいけないこと

  • デバイス間・エコシステム間の転送。iPhoneからAndroidへパスキーを直接渡すのはCXPの仕事であり、CXPはいまだ公開ワーキングドラフトです。
  • ハードウェアセキュリティキーのマイグレーションやバックアップ。設計上存在しません。2つ以上登録することが依然として唯一の答えです。
  • ファイルとしてエクスポートしてユーザーが自分で保管するバックアップ。現在出荷されている経路はOS仲介のアプリ対アプリであり、Apple文書によればファイルシステムには何も書き込まれません。issue #24である参加者が指摘した通り、「自分が握っているコピーが欲しい」という要求と現在の設計は方向が異なります。
  • プロバイダがエクスポートを拒否しないという保証。公開されている仕様にはまだその保証がありません。

RPを運用しているなら確認すべきこと

  • 署名カウンタのロジックが仕様より厳格になっていないか。WebAuthnの複製検知は値が0でないときにしか発動しないため、標準通りに実装していればインポートされたパスキーは静かに通過します。しかし「カウンタは必ず増加しなければならない」を直接実装しているなら、正常なユーザーをブロックしてしまいます。そしてどちらであっても、インポートされたパスキーについてはカウンタベースの複製検知がもはやシグナルを与えないという事実は変わりません。
  • バックアップ状態(BE/BS)フラグをどう使っているか。issue #33のスレッドでFIDO側の回答が指摘した通り、BE/BSは「共有可能かどうか」ではなく、同期パスキーかデバイス固有パスキーか、そして認証器が現在バックアップ済みだと信じているかどうかを示すだけです。このフラグを共有可否として解釈するポリシーがあるなら、前提が誤っています。
  • アカウント復旧の経路。可搬性が良くなったからといって復旧が解決するわけではありません。マネージャーを切り替えられることと、すべてのデバイスを失ったときに戻ってこられることは別問題であり、後者は依然として各RPの宿題として残っています。

おわりに

まとめるとこうです。資格情報交換は2つの仕様であり、完成度が違います。CXFは何をやり取りするかを定義し、Proposed Standardになりました — これは実際の成果であり、CSVの時代を終わらせるものです。CXPはどうやり取りするかを定義するはずですが2024年10月のワーキングドラフトで止まっており、その文書は自分自身が実装の根拠ではなく公式な地位もないと自ら記しています。ところがCXFが運ぶペイロードにはPKCS#8の平文秘密鍵が入っており、CXFのセキュリティ考慮事項は機密性をCXPに委ねています。

プラットフォーム各社はこの空白をプロトコルではなく制御権で埋めました。OSが仲介者となり、同一デバイス内で交換を実行し、ディスクには何も書き込みません。賢い解決策であり実際に動作しますが、これは「パスキーが可搬になった」ではなく「1台のデバイス内でマネージャーを切り替えられるようになった」です。その間の距離こそがCXPが埋めるべき場所であり、その場所はまだ空いたままです。

だから見出しではなく、仕様ディレクトリのファイル名を見てください。cxp-v1.0-wd-20241003.html — あの日付が変わるまで、エコシステムを越えるパスキー可搬性はロードマップであって、出荷済みの機能ではありません。

参考資料