フェデレーテッド認証情報管理 API

W3C 最初の公開作業草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2024/WD-fedcm-1-20240820/
最新公開バージョン:
https://www.w3.org/TR/fedcm/
編集者草稿:
https://w3c-fedid.github.io/FedCM/
履歴:
https://www.w3.org/standards/history/fedcm-1/
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/fedcm
フィードバック:
GitHub
仕様内インライン
編集者:
(Google Inc.)
元編集者:
(Google Inc.)

概要

ユーザーがプライバシーを保護しながら、フェデレーションアカウントでウェブサイトにログインできるWebプラットフォームAPIです。

この文書のステータス

このセクションは、公開時点での本書のステータスについて説明します。現在のW3C公開文書およびこの技術レポートの最新改訂版は、W3C技術レポートインデックス https://www.w3.org/TR/ にてご覧いただけます。

この文書は Federated Identity Working Group により 勧告トラックを用いて最初の公開作業草案として発行されました。本書はW3C勧告となる予定です。

(アーカイブ) 公開メーリングリスト public-fedid-wg@w3.org (手順参照) は、この仕様に関する議論に推奨されます。 メール送信時は、件名に「fedcm」と記載してください。 例:「[fedcm] …コメントの概要…

この文書は最初の公開作業草案です。

最初の公開作業草案としての公開は、W3Cおよびそのメンバーによる承認を意味するものではありません。本書は草案であり、いつでも更新・置換・廃止される可能性があります。他の作業中文書として以外の引用は不適切です。

この文書はFederated Identity Working Groupによって作成されました。

この文書はW3C特許ポリシーに則って運営されるグループによって作成されました。 W3Cは、グループの成果物に関連した特許開示の公開リストを管理しています。 そのページには特許開示の方法も記載されています。 本人が必須クレームを含むと考える特許を実際に知っている場合は、W3C特許ポリシー第6節に従って情報開示する必要があります。

この文書は2023年11月3日版W3Cプロセス文書に従って管理されています。

1. はじめに

このセクションは規範的ではありません。

ウェブの進化に伴い、プライバシー重視の変更が継続的に行われてきました (例:SafariFirefoxChrome) および基礎となるプライバシー原則の変更(例:Privacy Model)。

この進化によって、ウェブプラットフォームの基本的な仮定が再定義または廃止されています。サードパーティコンテキストでのCookieへのアクセスもその仮定のひとつです。ウェブ全体にとって良いことである一方、サードパーティCookieの廃止は、特定のフェデレーション認証設計で利用されていた基本的な構成要素を失うことになります。

Federated Credential Management APIは、サードパーティCookieに依存していたフェデレーション認証設計のためのギャップを埋めることを目的としています。 このAPIは、サードパーティCookieに依存するフェデレーション認証をサインインからサインアウト、取り消しまでサポートするために必要なプリミティブを提供します。

サードパーティCookieを使用せずにフェデレーション認証のプリミティブを提供するために、APIはユーザーエージェントRP(フェデレーションサインインのためにユーザー情報を要求するウェブサイト)と IDP(フェデレーションサインインのためにユーザー情報を提供するウェブサイト)の間の媒介者として配置します。この媒介には、RPIDPがユーザーとの接続を認識する前に、ユーザーの許可が必要です。

この仕様はユーザーエージェントIDPの変更に大きく依存し、RPへの依存は最小限です。FedCM APIは認証やトークン取得の手段を提供します。

単一アカウントでログイン可能なウェブサイトの実装例です。
<html>
<head>
  <title>Welcome to my Website</title>
</head>
<body>
  <button onclick="login()">Login with idp.example</button>

  <script>
  let nonce;
  async function login() {
    try {
      // ランダムな数値を返すメソッドがあると仮定します。値を変数に保存し、
      // 後でトークンに含まれる値と照合できます。
      nonce = random();
      // ユーザーにIDPのアカウント選択を促し、RPでフェデレーションログインを行います。
      // 成功すると、PromiseはIdentityCredentialオブジェクトを返し、|token|を
      // 取得できます。これはIDPからRPへ渡される不透明な文字列です。
      let token = await navigator.credentials.get({
        identity: {
          providers: [{
            configURL: "https://idp.example/manifest.json",
            clientId: "123",
            nonce: nonce,
          }]
        }
      });
    } catch(e) {
      // FedCM呼び出しは成功しませんでした。
    }
  }
  </script>
</body>
</html>

概要として、Federated Credential Management APIは協調するIDPRPの仲介によって機能します。

§ 3 Identity Provider HTTP APIでは、IDPが公開するHTTP APIセットと、§ 2 The Browser APIで利用できるエントリーポイントを定義しています。

ユーザーエージェントは、APIがトラッキング目的で利用されることを非現実的にするよう仲介しつつ、認証連携の機能性を維持します。

2. ブラウザーAPI

ブラウザーAPIはRPIDPが呼び出せるAPIを公開し、ユーザーのID交換を仲介します。

サインアップ/サインインAPIはRPが ブラウザーにIDPとの関係仲介と トークンの発行を依頼するために使われます。

注: RPはサインアップとサインインを区別せず、同じAPIを区別なく呼び出します。

すべてが正常に進行すると、Relying Partyにはユーザー認証に使えるトークンを含むIdentityCredential が返却されます。

const credential = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
    }]
  }
});

Cookie付きで送信されるフェッチでは、リソースが同一オリジンリクエストとしてロードされた場合と同様に、分割されていないCookieが含まれます。 これは、SameSite 値(サードパーティとしてリソースがロードされた場合に使われる)に関係なく、です。これにより、IDPがFedCM APIを採用しやすくなります。APIではRPがフェッチの結果を参照できないため、セキュリティ上の問題はありません。

2.1. ログインステータスAPI

2.1.1. ログインステータスマップ

ユーザーエージェントは、グローバルかつ永続的なログインステータスマップ(初期値は空のmap)を保持します。このmapのキーoriginIDPのorigin)であり、は、"unknown"、"logged-in"、 "logged-out"のいずれかのenumです。

originのログインステータスを取得するには:
  1. ログインステータスマップ[origin]が存在すれば、それを返す。

  2. それ以外の場合は、unknownを返す。

originのログインステータスをvalueに設定するには:
  1. valuelogged-inまたはlogged-outのいずれかであることを確認する。

  2. Set ログインステータスマップ[origin]をvalueに設定する。

2.1.2. インフラストラクチャアルゴリズム

environment settings objectsettings)が祖先と同一サイトかどうかは、以下のアルゴリズムがtrueを返す場合である:
  1. settingsrelevant global object関連付けられたDocumentがなければ、falseを返す。

  2. documentsettingsrelevant global object関連付けられたDocumentとする。

  3. documentbrowsing contextがなければ、falseを返す。

  4. originsettingsoriginとする。

  5. navigabledocumentnode navigableとする。

  6. navigableがnullでないを持つ間:

    1. navigablenavigableに設定する。

    2. navigableactive documentoriginorigin同一サイトでなければ、falseを返す。

  7. trueを返す。

2.1.3. HTTPヘッダーAPI

IDPは、以下のようにHTTPレスポンスヘッダーを利用してログインステータスを設定できます。

HTTPヘッダーのチェックはFetch仕様で扱われるべきです。すべてのリソースロードに影響するためです。

http-redirect fetchおよびhttp fetchレスポンスごとに、valueをレスポンスのヘッダーリストから "Set-Login"という名前・"item"型で 構造化フィールド値の取得を行った結果とする。valueがnullでなければ、以下の手順でこのヘッダーを処理する:

  1. originをレスポンスのURLoriginとする。

  2. clientrequestclientとする。

  3. リクエストのdestination"document"でなければ:

    1. clientがnullならreturn。

    2. originがリクエストのrequestorigin同一サイトでなければreturn。

    3. client祖先と同一サイトでなければreturn。

  4. valueがタプルであることを確認する。

  5. tokenvalueの最初の要素とする。

  6. token"logged-in"なら、originのログインステータスをlogged-inに設定する。

  7. token"logged-out"なら、originのログインステータスをlogged-outに設定する。

2.1.4. JavaScript API

IDPは、保存されたログインステータスを更新するためのJavaScript APIも利用できます:

enum LoginStatus {
  "logged-in",
  "logged-out",
};

[Exposed=Window, SecureContext] 
interface NavigatorLogin {
  Promise<undefined> setStatus(LoginStatus status);
};

partial interface Navigator {
  [SecureContext] readonly attribute NavigatorLogin login;
};
setStatus() が引数statusで呼び出されたとき:
  1. current settings object祖先と同一サイトでなければ、 SecurityError DOMExceptionをthrowする。

  2. origincurrent settings objectoriginとする。

  3. valuestatus"logged-in"ならlogged-in"logged-out"ならlogged-outとする。

  4. originのログインステータスをvalueに設定する。

2.1.5. ログインステータスマップデータのクリア

ユーザーエージェントは以下の場合にもログインステータスマップデータをクリアしなければなりません:

ユーザーがすべてのCookieまたはサイト設定データをクリアした場合

ユーザーエージェントはマップ全体をクリアしなければなりません。

ユーザーが特定のoriginのすべてのCookieまたは全サイトデータをクリアした場合

ユーザーエージェントは、削除されたCookieが送信可能なoriginに対するすべてのエントリを削除しなければなりません。

注: 例えば、ドメインCookieは削除されたoriginのサブドメインにも影響する場合があります。google.comのCookieをクリアすると、accounts.google.comのログインステータスもリセットされるべきです。 これはgoogle.comのドメインCookieに依存している可能性があるためです。

ユーザーが個別のCookieを削除した場合(ユーザーエージェントが許可する場合)

動作はユーザーエージェント定義です。

注: ユーザーエージェントは状態をunknownにリセットしたい場合があります。 これは、そのCookieが認可状態に影響するかどうか判断できないためです。

ユーザーエージェントがClear-Site-Dataヘッダーを "cookies"または"*"として受信し、requestclientがnullでなく、clientのorigin同一originかつトップレベルoriginである場合

originのCookieクリア中は、ログインステータスマップキーが入力originであるエントリを削除する必要があります。

Clear-Site-Dataがpartitioned cookiesをサポートした場合、この文言を更新する必要があります。

注: 他のウェブサイトが起因するCookie変更はこのマップに影響しないはずです。IDPのログイン状態が変化した際は明示的にSet-Loginヘッダーを送信すべきです。RPの状態はこのマップに影響しません。このマップはIDPの状態のみを反映します。

2.2. 接続済みアカウントセット

ユーザーエージェントは、グローバルな接続済みアカウントセット(初期値は空の順序付きセット)を持ちます。要素は(rp, idp, account)の三つ組で、rpRPのorigin、idpIDPのorigin、accountはアカウント識別子を表す文字列です。このセットは、ユーザーがFedCMを使用してidpaccountrpにログインした三つ組の集合を示します。

接続済みアカウントセットRPで二重キー化されるべきです(つまり、リクエスターと埋め込み元両方、iframeとトップレベルの両方を含むべきです)。そうしないと、トップレベルの状態が埋め込み元によって利用・変更され、リークや不要なクロスオリジン通信が発生します。

ユーザーがoriginの閲覧データ(Cookie、localStorageなど)をクリアした場合、ユーザーエージェントはremoveを用いてoriginに一致する三つ組を接続済みアカウントセットから全て削除しなければなりません。

connected account keyの算出IdentityProviderConfig providerIdentityProviderAccount accountglobalObjectを受け取って以下を実行。(rp, idp, account)の三つ組を返す。
  1. configUrlproviderconfigURLglobalObjectparse urlを実行した結果とする。

  2. idpOriginconfigUrlに対応するoriginとする。

  3. rpOriginglobalObjectassociated Documentoriginとする。

  4. accountIdaccountidとする。

  5. (rpOrigin, idpOrigin, accountId)を返す。

IdentityProviderAccount account自動再認証対象かどうか:IdentityProviderConfig providerglobalObjectを受けて以下を実行。Booleanを返す。
  1. accountapproved_clients含み、かつaccountapproved_clientsproviderclientId含まないなら、falseを返す。

  2. tripleconnected account keyの算出provideraccountglobalObjectを渡して得る。

  3. 接続済みアカウントセットtriple含む場合、その値を返す。

接続状態の算出IdentityProviderAccount accountIdentityProviderConfig providerglobalObjectを渡して以下を実行。 connectedまたはdisconnectedを返す。
  1. accountapproved_clients含む場合:

    1. accountapproved_clientsproviderclientId含むなら、connectedを返す。

    2. disconnectedを返す。

  2. tripleconnected account keyの算出provideraccountglobalObjectを渡して得る。

  3. 接続済みアカウントセットtriple含む場合、connectedを返す。

  4. disconnectedを返す。

RPとIdPアカウント間の接続作成IdentityProviderConfig providerIdentityProviderAccount accountglobalObject(RPのもの)を渡して以下を実行:
  1. configUrlproviderconfigURLglobalObjectparse urlを実行した結果とする。

  2. idpOriginconfigUrlに対応するoriginとする。

  3. rpOriginglobalObjectassociated Documentoriginとする。

  4. accountIdaccountidとする。

  5. tripleを(rpOrigin, idpOrigin, accountId)とする。

  6. Append triple接続済みアカウントセットに追加する。

接続の削除accountIdrpOriginidpOriginを受けて以下を実行。accountIdの接続が正常に削除されたかどうかを返す。
  1. tripleを(rpOrigin, idpOrigin, accountId)とする。

  2. 接続済みアカウントセットtriple含む場合:

    1. Remove triple接続済みアカウントセットから削除する。

    2. trueを返す。

  3. falseを返す。

すべての接続の削除rpOriginidpOriginを受けて以下を実行:
  1. すべての(rp, idp, accountId)triple接続済みアカウントセットでループ:

    1. rprpOriginと等しく、かつidpidpOriginと等しい場合、remove triple接続済みアカウントセットから削除する。

2.3. IdentityCredentialインターフェース

この仕様は新しいCredential型である IdentityCredentialを導入します:

dictionary IdentityCredentialDisconnectOptions : IdentityProviderConfig {
  required USVString accountHint;
};

[Exposed=Window, SecureContext]
interface IdentityCredential : Credential {
  static Promise<undefined> disconnect(optional IdentityCredentialDisconnectOptions options = {});
  readonly attribute USVString? token;
  readonly attribute boolean isAutoSelected;
};
id

idの 属性getterは空文字列を返します。

token

tokenの 属性getterは設定された値を返します。 これはIDPから提供される生成済みtokenを表します。

isAutoSelected

isAutoSelectedの 属性getterは設定された値を返します。これはUIフローでユーザーのIDクレデンシャルが自動選択されたかどうかを示します。 その結果このIdentityCredentialが生成されました。

[[type]]

IdentityCredential[[type]]の 値は"identity"です。

[[discovery]]

IdentityCredential[[discovery]]の 値はremoteです。

本仕様の主なエントリポイントは、Credential Management APIが公開するエントリポイントを通じて利用します。

2.3.1. disconnectメソッド

静的なdisconnect メソッドがIdentityCredentialDisconnectOptions optionsで呼び出された場合、以下の手順を実行する:
  1. globalObject現在のグローバルオブジェクトとする。

  2. documentglobalObject関連付けられたDocumentとする。

  3. documentallowed to useidentity-credentials-get ポリシー制御機能の利用が許可されていない場合、"NotAllowedError" DOMExceptionをthrowする。

  4. promiseを新しいPromiseとする。

  5. 並列で切断試行optionspromiseglobalObjectで実行する。

  6. promiseを返す。

切断試行IdentityCredentialDisconnectOptions optionsPromise promiseglobalObjectで呼び出された場合、以下の手順を実行する:
  1. Assert: これらの手順は並列で動作している。

  2. configUrloptionsconfigURLglobalObjectparse urlを実行した結果とする。

  3. configUrlが失敗なら、reject promiseを"InvalidStateError" DOMExceptionでrejectする。

  4. Content Security Policy Level 3connect-srcディレクティブでconfigUrlに対してチェックを行う。失敗した場合は、reject promiseを"NetworkError" DOMExceptionでrejectする。

  5. このglobalObjectに対して他に保留中のdisconnect 呼び出しがある場合(例:例外がまだthrowされていない、または関連するPromiseがまだ解決されていない場合)、reject promiseを"NetworkError" DOMExceptionでrejectする。

  6. configUrlpotentially trustworthy originでなければ、reject promiseを "NetworkError" DOMExceptionでrejectする。

  7. ユーザーがglobalObjectでFedCM APIを無効にしている場合、reject promiseを "NetworkError" DOMExceptionでrejectする。

  8. アカウントaccountが存在せず、接続済みアカウントセット含む値としてconnected account keyの算出accountoptionsglobalObjectを渡して得た値がなければ、reject promiseを"NetworkError" DOMExceptionでrejectする。 このチェックは接続済みアカウントセットをイテレートするか、高速化のため別データ構造を保持してもよい。

  9. configproviderglobalObject設定ファイル取得を実行した結果とする。

  10. configが失敗なら、reject promiseを"NetworkError" DOMExceptionでrejectする。

  11. disconnectUrlproviderconfig.disconnect_endpointglobalObjectmanifest URL算出を実行した結果とする。

  12. disconnectUrlが失敗なら、reject promiseを"NetworkError" DOMExceptionでrejectする。

  13. 切断リクエスト送信disconnectUrloptionsglobalObjectで実行し、その結果をresultとする。

  14. idpOriginconfigUrlに対応するoriginとする。

  15. rpOriginglobalObject関連付けられたDocumentoriginとする。

  16. resultが失敗の場合:

    1. すべての接続の削除rpOriginidpOriginで実行する。

    2. reject promiseを"NetworkError" DOMExceptionでrejectする。

    3. return。

  17. accountIdresult(失敗でないことに注意)とする。

  18. 接続の削除accountIdrpOriginidpOriginで実行し、結果をwasAccountRemovedとする。

  19. wasAccountRemovedがfalseなら、すべての接続の削除rpOriginidpOriginで実行する。

  20. resolve promiseする。

2.3.1.1. 切断リクエスト

切断リクエスト送信アルゴリズムは、RPでフェデレーションログインに使用されたアカウントを切断するためのリクエストを送信します。

切断リクエスト送信URL disconnectUrlIdentityCredentialDisconnectOptions optionsglobalObjectで呼び出された場合、以下の手順を実行。この処理はUSVString または失敗を返す。
  1. requestBodyurlencoded serializerでリスト

    1. ("client_id", optionsclientId)

    2. ("account_hint", optionsaccountHint)

  2. requestを新しいrequestとして以下の通り作成:

    url

    disconnectUrl

    method

    "POST"

    body

    UTF-8 encodeされたrequestBody

    redirect mode

    "error"

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "webidentity"

    origin

    globalObject関連ドキュメントorigin

    header list

    listに、headernameAcceptvalueapplication/x-www-form-urlencoded)を1つだけ含める

    credentials mode

    "include"

    mode

    "cors"

  3. accountIdをnullとする。

  4. fetch requestrequestglobalObjectで実行し、processResponseConsumeBodyは、response responseresponseBodyを引数に以下の手順を実行する:

    1. jsonresponseresponseBodyJSON fetchレスポンス抽出を実行した結果とする。

    2. ECMAScript値からIDL値変換jsonDisconnectedAccount型のaccountに変換する。

    3. 前2ステップのいずれかで例外がthrowされた場合、accountIdに失敗をセットしreturnする。

    4. accountIdaccountaccount_idとする。

  5. accountIdがセットされるまで待つ。

  6. accountIdを返す。

dictionary DisconnectedAccount {
  required USVString account_id;
};

2.3.2. CredentialRequestOptions

このセクションではJavaScript呼び出し時に渡されるディクショナリを定義します:

const credential = await navigator.credentials.get({
  identity: { // IdentityCredentialRequestOptions
    providers: [{  // sequence<IdentityCredentialRequestOptions>
      configURL: "https://idp.example/manifest.json", // IdentityProviderConfig.configURL
      clientId: "123", // IdentityProviderConfig.clientId
      nonce: "nonce" // IdentityProviderConfig.nonce
    }]
  }
});

この仕様ではCredentialRequestOptions オブジェクトの拡張を導入します:

partial dictionary CredentialRequestOptions {
  IdentityCredentialRequestOptions identity;
};

IdentityCredentialRequestOptions にはRPがサポートし事前登録している(つまり、IDPRPclientIdを与えている)IdentityProviderConfigのリストが含まれます。 IdentityCredentialRequestOptions にはIdentityCredentialRequestOptionsContext も含まれ、ユーザーエージェントがより意味のあるダイアログをユーザーに提供できます。

enum IdentityCredentialRequestOptionsContext {
  "signin",
  "signup",
  "use",
  "continue"
};

dictionary IdentityCredentialRequestOptions {
  required sequence<IdentityProviderRequestOptions> providers;
  IdentityCredentialRequestOptionsContext context = "signin";
};

IdentityProviderConfigRPがサポートしている(事前登録済み)IDPを表します。

dictionary IdentityProviderConfig {
  required USVString configURL;
  required USVString clientId;
};

dictionary IdentityProviderRequestOptions : IdentityProviderConfig {
  USVString nonce;
  DOMString loginHint;
  DOMString domainHint;
};
configURL

アイデンティティプロバイダーの設定ファイルのURLです。

clientId

IDPRPに帯域外で提供したclient_idです。

nonce

RPが選択するランダムな数値です。通常はクライアントセッションとtokenの関連付けやリプレイ攻撃の緩和に使われます。十分なエントロピーがあり、推測困難である必要があります。

loginHint

RPがユーザーエージェントに表示してほしいアカウントに対応するログインヒントを表す文字列です。指定された場合、ユーザーエージェントはこのログインヒント値に一致しないアカウントを表示しません。通常、希望するIdentityProviderAccountの属性のいずれかに一致します。

domainHint

RPが関心を持つドメイン、またはすべてのアカウントを希望する場合は"any"を表す文字列です。指定した場合、一致しないドメインヒントのアカウントは表示されません。

2.3.3. [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 内部メソッド

[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) アルゴリズムは、Credential Management 1 § 2.5.1 クレデンシャル要求の内部で並列実行され、クレデンシャルを要求し、IdentityCredential またはエラーを返します。

この内部メソッドは3つの引数を受け取ります:

origin

この引数は、呼び出し元の relevant settings objectorigin です。これは get() 実装によって決定されます。すなわち CredentialsContainerRequest a Credential 抽象操作です。

options

この引数は CredentialRequestOptions オブジェクトで、その identity メンバーが 存在します。

sameOriginWithAncestors

この引数は Boolean 値で、呼び出し元の environment settings object祖先と同一オリジン の場合のみ true です。クロスオリジンの場合は false です。

注: この 内部メソッド の呼び出しは、permissions policy によって許可されたことを示します。これは Credential Management Level 1 のレベルで評価されます。 詳細は § 4 Permissions Policy Integration を参照してください。したがって、 sameOriginWithAncestors は未使用です。

options.signal はリクエストの中断シグナルとして使用されます。

IdentityCredential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) アルゴリズムが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければなりません。これは IdentityCredential を返す(または呼び出し元にエラーを投げる)。
  1. Assert: これらの手順は 並列で実行している。

  2. options["identity"]["providers"] のサイズが1でない場合、グローバルタスクをキューし、DOM操作タスクソースglobalObjectに新しい"NetworkError" DOMExceptionを投げる

    注: globalObjectは現在 [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) アルゴリズムに渡されません。issue参照。

    複数の IDP からのアカウント選択対応については こちら参照。

  3. ユーザーエージェントは次のステップに進むタイミングを決定できます。

    注: 例えば、ユーザーエージェントはネットワークリクエスト前にIDプロバイダー選択画面を表示したり、URLバーにボタンを出してユーザー操作を待ったりできます。

  4. provideroptions["identity"]["providers"][0]とする。

  5. credentialIdentityCredential作成provideroptionsglobalObjectで実行した結果とする。

  6. credentialがペアの場合:

    1. 2番目の要素値をthrowImmediatelyとする。

    2. 以下すべて満たす場合、ユーザーエージェントは次のステップまでランダムな時間待つ必要がある:

      • throwImmediatelyがfalse

      • promise拒否遅延ユーザーエージェント自動化により無効化されていない

      • ユーザーエージェントが、RPがアカウントにログインしているかどうかを露呈しないための他の方法を実装していない

      注: ここでの意図は、Promiseが即座に解決された場合、RPがダイアログが表示されなかったことをネットワーク遅延のみで推測できてしまうことを防ぐためです。ダイアログ表示があれば、ユーザーが1つ以上のIDPアカウントにログインしていることを示します。この情報漏洩を防ぐため、特にユーザー確認なしで遅延を入れる仕様です。ただし、UAは異なるUIアプローチで防ぐ場合もあります。

    3. グローバルタスクをキューし、DOM操作タスクソースで新しい"NetworkError" DOMExceptionを投げる。

  7. それ以外の場合はcredentialを返す。

2.3.4. IdentityCredentialの作成

IdentityCredential作成アルゴリズムは各種FedCMフェッチを呼び出し、ユーザーエージェントUIを表示し、 IdentityCredential を生成し、RPに返します。

IdentityCredentialの作成IdentityProviderRequestOptions providerCredentialRequestOptions optionsglobalObjectで実行。IdentityCredential または (failure, bool) のペア(boolは例外遅延スキップ指示)を返す。
  1. Assert: これらの手順は 並列で実行している。

  2. loginStatusログインステータス取得providerconfigURLoriginを使って得る。

  3. loginStatusunknownなら、ユーザーエージェントはlogged-outに設定してもよい。

  4. loginStatuslogged-outなら、ユーザーエージェントは以下いずれかを行う:

    • (failure, false)を返す。

    • ユーザーに継続するか確認。ユーザーが継続する場合、ユーザーエージェントはloginStatusunknownに設定すべき。IDPログインダイアログ表示の選択肢も含めることができる。

      • ユーザーがダイアログをキャンセルしたら(failure, true)を返す。

      • ユーザーがこの選択肢を選んだ場合:

        1. config設定ファイル取得providerglobalObjectで得る。

        2. configが失敗なら(failure, true)を返す。

        3. IDPログインダイアログ表示configproviderで実行。

        4. そのアルゴリズムが失敗なら(failure, true)を返す。

    RPが第2の選択肢を要求できるようにした方がよいかもしれません(ユーザー操作に依存して)。詳細はこのissue参照。

  5. requiresUserMediationproviderconfigURLoriginユーザ仲介が必要で得る。

  6. mediationoptionsmediationとする。

  7. requiresUserMediationがtrueかつmediationが "silent" なら(failure, true)を返す。

  8. config設定ファイル取得providerglobalObjectで得る。

  9. configが失敗なら(failure, false)を返す。

  10. アカウント取得ステップaccountsListアカウント取得configproviderglobalObjectで得る。

  11. accountsListが失敗またはサイズが0の場合:

    1. ログインステータス設定configURLoriginlogged-outに設定する。 サーバーにクレデンシャルが送信されていない場合、このステップは省略可能。

      注: 例えば、DNSエラー等でフェッチ失敗の場合は、クレデンシャルが送信されていないため、IDPはユーザーのIDを認識しません。このケースでは、ユーザーがサインインしているかどうか不明のため、ステータスリセット不要な場合もあります。

    2. 不一致ダイアログステップloginStatuslogged-inの場合、ユーザーにダイアログ表示。内容はユーザーエージェント定義。このダイアログは IDPログインダイアログ表示configproviderで実行できる選択肢を含むべき。 このダイアログは IDPログイン確認ダイアログ

      注: この状況は、ブラウザがユーザーがサインインしていると予測したものの、アカウント取得でサインアウトが示唆された場合です。

      注: このダイアログは、サーバーにクレデンシャルが送信された場合に必ず何らかのUIを表示することで、ユーザーのサイレントトラッキングを不可能にします。

      1. 以下いずれかになるまで待機:

        • ユーザーがダイアログを閉じたら(failure, true)を返す。

        • IDPログインダイアログ表示が実行された場合:

          1. 結果をresultとする。

          2. resultが失敗なら(failure, true)を返す。ユーザーエージェントは失敗理由を示すダイアログを表示してもよい。

          3. それ以外の場合はアカウント取得ステップに戻る。

  12. Assert: accountsListは失敗でなく、サイズは0でない。

  13. ログインステータス設定configURLoriginlogged-inに設定。

  14. providerloginHint が空でない場合:

    1. accountList内の各accountについて、accountlogin_hintsproviderloginHint含まない場合、accountaccountListから削除。

    2. accountListが空になった場合、不一致ダイアログステップへ。

  15. providerdomainHint が空でない場合:

    1. accountList内の各accountについて:

      1. domainHint が"any"の場合:

        1. accountdomain_hints が空なら、accountaccountListから削除。

      2. それ以外の場合は、accountdomain_hintsproviderdomainHint含まない場合、accountaccountListから削除。

    2. accountListが空になった場合、不一致ダイアログステップへ。

  16. accountsList内の各accについて:

    1. acc["picture"] が存在する場合、アカウント画像取得accglobalObjectで実行。

    注: ユーザーエージェントは、初期表示でアカウント画像取得を必要としないUI選択も可能です。その場合、画像取得は必要時まで遅延できます。これらフェッチ失敗は無視されるため、順序は任意です。

  17. registeredAccountnumRegisteredAccountsをそれぞれnullと0に設定。

  18. accountをnullに設定。

  19. accountsList内の各accについて:

    1. accproviderglobalObject自動再認証対象なら、registeredAccountaccをセットしnumRegisteredAccountsを1増やす。

  20. permissiondisclosureTextShownisAutoSelectedをfalseで初期化。

  21. mediationが"required"でなく、 requiresUserMediationがfalseかつnumRegisteredAccountsが1の場合:

    1. accountregisteredAccountを、permissionにtrueをセットする。この処理時、ユーザーエージェントはユーザーに自動再認証されていることを示すUIを表示してもよい(MAY)。

    2. isAutoSelectedにtrueをセットする。

  22. それ以外の場合、mediationが"silent"なら(failure, true)を返す。

  23. それ以外で、accountsListのサイズが1の場合:

    1. accountaccountsList[0]をセット。

    2. 接続状態算出accountproviderglobalObjectconnectedなら、 サインイン許可ダイアログを表示し、結果をpermissionにセット。 ユーザーエージェントはoptionscontext でダイアログをカスタマイズ可能。

    3. それ以外の場合、サインアップ許可リクエストaccountconfigproviderglobalObjectで実行し、結果をpermissionにセット。disclosureTextShownもtrueに設定。

  24. それ以外の場合:

    1. アカウント選択accountsListから実行し、結果をaccountに。

    2. accountが失敗なら(failure, true)を返す。

    3. 接続状態算出accountproviderglobalObjectconnectedならpermissionをtrueに設定。

    4. それ以外の場合:

      1. サインアップ許可リクエストaccountconfigproviderglobalObjectで実行し、結果をpermissionにセット。

      2. disclosureTextShownをtrueに設定。

  25. 前ステップで生成されたダイアログがあれば、ユーザーの選択や許可が完了するまで待機。

  26. Assert: accountはnullではない。

  27. permissionがfalseなら(failure, true)を返す。

  28. credentialIDアサーション取得accountiddisclosureTextShownisAutoSelectedproviderconfigglobalObjectで実行した結果とする。

  29. credentialを返す。

2.3.5. 設定ファイルの取得

設定ファイルの取得アルゴリズムは、well-knownファイルと設定ファイルの両方をIDPから取得し、設定ファイルがwell-knownファイルで言及されているかを確認し、設定内容を返します。

設定ファイルの取得IdentityProviderRequestOptions providerglobalObjectを受けて以下を実行。この処理はIdentityProviderAPIConfig または失敗を返します。
  1. configUrlproviderconfigURLglobalObjectparse urlした結果とする。

  2. configUrlが失敗なら失敗を返す。

  3. Content Security Policy Level 3connect-srcディレクティブでconfigUrlに対してチェック。失敗した場合は失敗を返す。

  4. configUrlpotentially trustworthy URLでなければ失敗を返す。

  5. rootUrlを新しいURLとする。

  6. rootUrlschemeconfigUrlschemeに設定する。

  7. rootUrlhostconfigUrlhost登録可能ドメインに設定する。

  8. rootUrlpathlist«".well-known", "web-identity"»に設定する。

  9. configconfigInWellKnownの両方をnullに設定。

  10. rpOriginglobalObject関連Documentoriginとする。

  11. rpOriginopaque originでなく、かつrootUrlhostrpOrigin登録可能ドメインと等しく、rootUrlschemerpOriginschemeと等しければ、configInWellKnownをtrueに設定。

    注: ドメインCookieはサイト全体で有効なため、RPとIDPが同一サイトの場合、well-knownチェックをしてもプライバシー上の利点はありません。

  12. それ以外の場合:

    1. wellKnownRequestを新しいrequestで以下の通り作成:

      URL

      rootUrl

      client

      null

      window

      "no-window"

      service-workers mode

      "none"

      destination

      "webidentity"

      origin

      一意なopaque origin

      header list

      listに、headernameAcceptvalueapplication/json)を1つだけ含める

      referrer policy

      "no-referrer"

      credentials mode

      "omit"

      mode

      "no-cors"

      仕様ではすべてのrequestuser-agent-no-corsで作成されるよう更新予定です。詳細はpull request参照。

    2. fetch requestwellKnownRequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

      1. jsonresponseresponseBodyJSON fetchレスポンス抽出を実行した結果とする。

      2. ECMAScript値からIDL値変換jsonIdentityProviderWellKnowndiscoveryに変換。

      3. 前2ステップで例外がthrowされた場合、またはdiscovery["provider_urls"]のサイズが1より大きい場合、configInWellKnownをfalseに設定。

        provider_urls配列サイズ緩和検討中。

      4. それ以外の場合、discovery["provider_urls"][0]がproviderconfigURL一致ならconfigInWellKnownをtrue、それ以外はfalseに設定。

  13. configRequestを新しいrequestで以下の通り作成:

    url

    configUrl

    redirect mode

    "error"

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "webidentity"

    origin

    一意なopaque origin

    header list

    listに、headernameAcceptvalueapplication/json)を1つ含める

    referrer policy

    "no-referrer"

    credentials mode

    "omit"

    mode

    "no-cors"

    仕様ではすべてのrequestuser-agent-no-corsで作成されるよう更新予定です。詳細はpull request参照。

  14. fetch requestconfigRequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

    1. jsonresponseresponseBodyJSON fetchレスポンス抽出を実行した結果とする。

    2. ECMAScript値からIDL値変換jsonIdentityProviderAPIConfig型のconfigに変換。

    3. 前2ステップで例外がthrowされた場合、configに失敗をセット。

    4. config.login_urlproviderconfigglobalObjectmanifest URL算出した結果に設定。

    5. config.login_urlがnullなら失敗を返す。

  15. configconfigInWellKnownがセットされるまで待機。

  16. configInWellKnownがtrueならconfigを返す。falseなら失敗を返す。

注: 2層ファイルシステムを採用することで、IDPが設定ファイルパスに情報をエンコードして訪問中のRPを容易に特定することを防ぎます。この問題は、well-knownファイルIDPルートに必須とすることで解決します。設定ファイル自体は任意の場所に置けますが、ユーザーエージェントがwell-knownファイルで見つけなければ使用されません。これにより、IDPは実際の設定ファイルを任意パスに保管しつつ、ユーザーエージェントがRP名入りパス等によるフィンガープリンティングを防げます。詳細は§ 7.3.1 Manifest Fingerprinting参照。

dictionary IdentityProviderWellKnown {
  required sequence<USVString> provider_urls;
};

dictionary IdentityProviderIcon {
  required USVString url;
  unsigned long size;
};

dictionary IdentityProviderBranding {
  USVString background_color;
  USVString color;
  sequence<IdentityProviderIcon> icons;
  USVString name;
};

dictionary IdentityProviderAPIConfig {
  required USVString accounts_endpoint;
  required USVString client_metadata_endpoint;
  required USVString id_assertion_endpoint;
  required USVString login_url;
  USVString disconnect_endpoint;
  IdentityProviderBranding branding;
};

2.3.6. アカウントの取得

アカウントの取得アルゴリズムはaccountsエンドポイントを取得し、ユーザーがログインしているIDPアカウントのリストを判別します。これにより、後でユーザーエージェントがFedCM UIをユーザーに表示できます。

アカウントの取得IdentityProviderAPIConfig configIdentityProviderRequestOptions providerglobalObjectを受けて以下を実行。この処理はIdentityProviderAccountListを返します。
  1. accountsUrlproviderconfig["accounts_endpoint"]、globalObjectmanifest URL算出した結果とする。

  2. accountsUrlが失敗の場合は空リストを返す。

  3. requestを新しいrequestで以下の通り作成:

    url

    accountsUrl

    redirect mode

    "error"

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "webidentity"

    origin

    一意なopaque origin

    header list

    listに、headernameAcceptvalueapplication/json)を1つだけ含める

    referrer policy

    "no-referrer"

    credentials mode

    "include"

    mode

    "no-cors"

    このアルゴリズムでのcredentialed fetchは、ユーザーが許可する前にタイミング攻撃でユーザーIDが漏れる可能性があります。調査内容はこちら

    仕様ではすべてのrequestuser-agent-no-corsで作成されるよう更新予定です。詳細はpull request参照。

  4. accountsListをnullに設定。

  5. fetch requestrequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

    1. jsonresponseresponseBodyJSON fetchレスポンス抽出を実行した結果とする。

    2. ECMAScript値からIDL値変換jsonIdentityProviderAccountList型のaccountsListに変換。

    3. 前2ステップで例外がthrowされた場合、accountsListに失敗をセット。

    ここで返されるaccountsリストは重複id検証が必要です。詳細はこちら参照。

  6. accountsListがセットされるまで待機。

  7. accountsListを返す。

dictionary IdentityProviderAccount {
  required USVString id;
  required USVString name;
  required USVString email;
  USVString given_name;
  USVString picture;
  sequence<USVString> approved_clients;
  sequence<DOMString> login_hints;
  sequence<DOMString> domain_hints;
};
dictionary IdentityProviderAccountList {
  sequence<IdentityProviderAccount> accounts;
};
アカウント画像取得IdentityProviderAccount accountglobalObjectを受けて以下を実行:
  1. pictureUrlaccount["picture"]とglobalObjectparse urlした結果とする。

  2. pictureUrlが失敗なら手順を中止。ユーザーエージェントはプレースホルダー画像を利用可。

  3. pictureRequestを新しいrequestで以下の通り作成:

    url

    pictureUrl

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "image"

    origin

    一意なopaque origin

    referrer policy

    "no-referrer"

    credentials mode

    "omit"

    mode

    "no-cors"

    仕様ではすべてのrequestuser-agent-no-corsで作成されるよう更新予定です。詳細はpull request参照。

  4. fetch requestpictureRequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

    1. responseBodyがnullまたは失敗なら、ユーザーエージェントは任意のプレースホルダー画像を選択しaccountに関連付けてもよい。

    2. それ以外の場合、responseBodyを画像にデコードし、成功した場合はaccountに関連付ける。これにより、ユーザーエージェントはダイアログ表示時にデコード済み画像を利用できる。

2.3.7. IDアサーションの取得

IDアサーションの取得アルゴリズムは、ユーザーが特定のIDPアカウントでFedCMの利用を許可した後に呼び出されます。IDアサーションエンドポイントからトークンを取得し、それをRPに提供します。

IDアサーションの取得USVString accountId、boolean disclosureTextShown、boolean isAutoSelectedIdentityProviderRequestOptions providerIdentityProviderAPIConfig configglobalObjectを受けて以下を実行。この処理はIdentityCredential または失敗を返す。
  1. tokenUrlproviderconfig["id_assertion_endpoint"]、globalObjectmanifest URL算出した結果とする。

  2. tokenUrlが失敗なら失敗を返す。

  3. requestBodyurlencoded serializerで以下のリストを渡して作成:

    1. ("client_id", providerclientId)

    2. ("nonce", providernonce)

    3. ("account_id", accountId)

    4. ("disclosure_text_shown", disclosureTextShown)

    5. ("is_auto_selected", isAutoSelected)

  4. requestを新しいrequestで以下の通り作成:

    url

    tokenUrl

    method

    "POST"

    body

    UTF-8 encodeされたrequestBody

    redirect mode

    "error"

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "webidentity"

    origin

    globalObject関連ドキュメントorigin

    header list

    listに、headernameAcceptvalueapplication/x-www-form-urlencoded)を1つだけ含める

    credentials mode

    "include"

    mode

    "cors"

  5. credentialをnullとする。

  6. fetch requestrequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

    1. jsonresponseresponseBodyJSON fetchレスポンス抽出した結果とする。

    2. ECMAScript値からIDL値変換jsonIdentityProviderToken型のtokenに変換。

    3. 前2ステップで例外がthrowされた場合、credentialに失敗をセットしreturn。

    4. credentialを新しいIdentityCredentialとして、globalObjectrealmを渡して生成。

    5. credentialtokentokenをセット。

    6. credentialisAutoSelectedisAutoSelectedをセット。

  7. credentialがセットされるまで待機。

  8. credentialを返す。

dictionary IdentityProviderToken {
  required USVString token;
};

2.3.8. サインアップ許可のリクエスト

アカウント選択accountsListを受けて以下を実行。この処理はIdentityProviderAccount または失敗を返す。
  1. Assert accountsListサイズが1より大きい。

  2. accountsListから選択肢を表示するアカウントチューザーを表示する。

  3. ユーザーがアカウントチューザーから手動で選択したIdentityProviderAccountaccountとし、選択されなければ失敗。

  4. accountを返す。

サインアップ許可リクエストアルゴリズムは、client metadataエンドポイントを取得し、ユーザーが指定アカウントの利用を許可するまで待機し、許可したかどうかを返します。

サインアップ許可リクエストIdentityProviderAccount accountIdentityProviderAPIConfig configIdentityProviderRequestOptions providerglobalObjectを受けて以下を実行。Booleanを返す。
  1. Assert: これらの手順は並列で動作している。

  2. metadataclient metadata取得configproviderglobalObjectで得る。

  3. ユーザーにアカウント作成の明示的な意思を求めるダイアログを表示する。ユーザーエージェントはUIスタイル選択にIdentityProviderBrandingを利用してもよい。加えて:

    1. metadataが失敗でなく、metadata["privacy_policy_url"]が定義され、providerclientIdaccount["approved_clients"]リストに含まれていない場合、ユーザーエージェントはmetadata["privacy_policy_url"]リンクを表示しなければならない。

    2. metadataが失敗でなく、metadata["terms_of_service_url"]が定義され、providerclientIdaccount["approved_clients"]リストに含まれていない場合、ユーザーエージェントはmetadata["terms_of_service_url"]リンクを表示しなければならない。

    3. ユーザーエージェントは表示ダイアログのカスタマイズにcontextを利用してもよい。

  4. ユーザーが許可しなければfalseを返す。

  5. RPとIdPアカウント間の接続作成provideraccountglobalObjectで実行。

  6. trueを返す。

client metadata取得IdentityProviderAPIConfig configIdentityProviderRequestOptions providerを受けて以下を実行。この処理はIdentityProviderClientMetadata または失敗を返す。
  1. clientMetadataUrlproviderconfig["client_metadata_endpoint"]、globalObjectmanifest URL算出した結果とする。

  2. clientMetadataUrlが失敗なら失敗を返す。

  3. requestを新しいrequestで以下の通り作成:

    url

    clientMetadataUrl

    redirect mode

    "error"

    client

    null

    window

    "no-window"

    service-workers mode

    "none"

    destination

    "webidentity"

    origin

    globalObject関連ドキュメントorigin

    header list

    listに、headernameAcceptvalueapplication/json)を1つだけ含める

    credentials mode

    "omit"

    mode

    "no-cors"

    仕様ではすべてのrequestuser-agent-no-corsで作成されるよう更新予定です。詳細はpull request参照。

  4. metadataをnullに設定。

  5. fetch requestrequestglobalObjectで実行し、processResponseConsumeBodyは次の手順でresponseresponseBodyを処理:

    1. jsonresponseresponseBodyJSON fetchレスポンス抽出した結果とする。

    2. ECMAScript値からIDL値変換jsonIdentityProviderClientMetadata型のmetadataに変換。

    3. 前2ステップで例外がthrowされた場合、metadataに失敗をセット。

  6. metadataがセットされるまで待機。

  7. metadataを返す。

dictionary IdentityProviderClientMetadata {
  USVString privacy_policy_url;
  USVString terms_of_service_url;
};

2.3.9. 補助アルゴリズム

以下の補助アルゴリズムはFedCMフローの中で使用されます。

parse urlUSVString stringUrlglobalObject、省略可能なbaseUrl(デフォルトはnull)を受けて以下を実行。この処理はURLまたは失敗を返す。
  1. configUrlをnullに設定。

  2. グローバルタスクをキューし、DOM操作タスクソースglobalObjectに対し、configUrlurl parserstringUrlbaseUrlで実行した結果をセット。

    注: url parserはタスク内で実行する必要があるため、並列実行ではなくタスクをキューします。

  3. configUrlがセットされるまで待機。

  4. configUrlを返す。

fetch requestrequest requestglobalObject、アルゴリズムprocessResponseConsumeBodyを受けて以下を実行:
  1. グローバルタスクをキューし、ネットワークタスクソースglobalObjectを渡して以下を実行:

    1. fetch requestprocessResponseConsumeBodyprocessResponseConsumeBodyにセット)を行う。

注: fetchはタスク内で実行する必要があるため、並列実行ではなくタスクをキューします。

manifest URL算出IdentityProviderRequestOptions providerstring manifestStringglobalObjectを受けて以下を実行。この処理はURLまたは失敗を返す。
  1. configUrlparse urlproviderconfigURLglobalObjectを渡して得る。

  2. manifestUrlparse urlmanifestString(相対URL)、globalObjectconfigUrl(baseUrl)を渡して得る。

  3. manifestUrlがセットされるまで待機。

    注: manifest stringは絶対URLでも相対URLでも渡せます。

  4. manifestUrlが失敗なら失敗を返す。

  5. manifestUrlconfigUrlと同一オリジンでなければ失敗を返す。

  6. manifestUrlpotentially trustworthy URLでなければ失敗を返す。

  7. manifestUrlを返す。

JSON fetchレスポンス抽出response responseresponseBodyを受けて以下を実行。この処理はordered mapを返す。
  1. Assert: この手順はネットワークタスクソースで実行している。

  2. responseネットワークエラーまたはstatusok statusでなければ、"NetworkError" DOMExceptionをthrowする。

  3. mimeTypeMIME TYPE抽出responseheader listから得る。

  4. mimeTypeが失敗またはJSON MIME Typeでなければ、"NetworkError" DOMExceptionをthrowする。

  5. jsonparse JSON bytes to JavaScript valueresponseBodyを渡して得る。

  6. jsonがパース例外なら、"NetworkError" DOMExceptionをthrowする。

  7. jsonを返す。

IDPログインダイアログ表示IdentityProviderAPIConfig configIdentityProviderConfig providerglobalObjectを受けて以下を実行。この処理はsuccessまたはfailureを返す。
  1. Assert: この手順は並列で動作している。

  2. loginUrlをnullとする。

  3. グローバルタスクをキューし、DOM操作タスクソースglobalObjectに対し、loginUrlurl parserconfig.login_urlで実行した結果をセット。

  4. loginUrlがnullでなくなるまで待機。

  5. Assert: loginUrlは失敗でない(ユーザーエージェントはconfig.login_urlが有効なURLであることを事前に確認済み)。

  6. queryListを新しいlistとする。

  7. providerloginHintが空でなければ、("login_hint", loginHint)をappendしてqueryListに加える。

  8. providerdomainHintが空でなければ、("domain_hint", domainHint)をappendしてqueryListに加える。

  9. queryList空でない場合:

    1. queryParametersurlencoded serializerqueryListを渡して得る。

    2. loginUrlqueryがnullまたは空でなければ、queryParametersの先頭に"&"を追加。

    3. queryParametersloginUrlqueryに追加。

  10. 新しいトップレベルtraversableを作成し、loginUrlで表示する。

  11. ユーザーエージェントはbrowsing context featuresのセットアップやその他の実装定義の方法でこのtraversableの表示を調整してもよい。

  12. 以下いずれかになるまで待機:

    • ユーザーがbrowsing contextを閉じた場合:failureを返す。

    • この新しいtraversableの文脈でIdentityProvider.closeが呼び出された場合:

      1. traversableを閉じる。

      2. loginStatusget the login statuslogin_urloriginを渡して取得。

        注: IDPログインフローでは、JavaScriptHTTPヘッダーAPIによってこの値がlogged-inに設定される場合があります。別のbrowsing contextで変更されている可能性もあります。

      3. loginStatuslogged-inならsuccessを返す。

      4. それ以外の場合はfailureを返す。

2.4. IdentityProviderインターフェース

この仕様はIdentityUserInfo 辞書およびIdentityProvider インターフェースを導入します:

dictionary IdentityUserInfo {
  USVString email;
  USVString name;
  USVString givenName;
  USVString picture;
};

[Exposed=Window, SecureContext] interface IdentityProvider {
    static undefined close();
    static Promise<sequence<IdentityUserInfo>> getUserInfo(IdentityProviderConfig config);
};

決定 IdentityProvidergetUserInfo() メソッドの正しい場所かどうかを検討する。

close 関数は、ログインフローが完了したことをブラウザに通知するために用意されています。この関数がヘッダーとは別に存在する理由は、ユーザーがすでにログインしている場合でもログインフローがまだ終わっていない場合があるためです。例えば、IDPがユーザーに電話番号の確認を促したいことがあります。こうしたフローに対応するため、IDPはフローが完全に終わった時点でclose を呼ぶ必要があります。

詳細はIDPログインダイアログ表示アルゴリズムを参照してください。

IdentityUserInfo はユーザーのアカウント情報を表します。この情報は、ユーザーがすでにFedCM APIを使ってRPにログインした後にIDPに公開されます。つまり、接続済みアカウントセットが(三つ組:RP, IDP, account)を含む場合に公開されます。この情報はaccounts endpointで受け取った内容と一致します。IDPは、自身のconfigURLoriginに一致するiframeからgetUserInfo() 静的メソッドを呼び出すことでこの情報を取得できます。

const userInfo = await IdentityProvider.getUserInfo({
    configUrl: "https://idp.example/fedcm.json",
    clientId: "client1234"
});

if (userInfo.length > 0) {
  // 返されたアカウントの表示方法はIDPが決定します。
  const name = userInfo[0].name;
  const givenName = userInfo[0].givenName;
  const displayName = givenName ? givenName : name;
  const picture = userInfo[0].picture;
  const email = userInfo[0].email;
}
getUserInfo() メソッドをIdentityProviderConfig providerで呼び出したとき、以下の手順を実行する:
  1. globalObject現在のグローバルオブジェクトとする。

  2. documentglobalObject関連付けられたDocumentとする。

  3. documentallowed to useidentity-credentials-get ポリシー制御機能の利用が許可されていない場合、"NotAllowedError" DOMExceptionをthrowする。

  4. 接続済みアカウントセットが、含む値としてconnected account keyの算出accountproviderglobalObjectを渡して得た値がなければ、reject promiseを"NetworkError" DOMExceptionでrejectする。 このチェックは接続済みアカウントセットをイテレートするか、高速化のため別データ構造を保持してもよい。

  5. configUrlparse urlproviderconfigURLglobalObjectを渡して得る。

  6. configUrlが失敗なら"InvalidStateError" DOMExceptionをthrowする。

  7. documentoriginconfigUrlorigin同一オリジンでなければ、"InvalidStateError" DOMExceptionをthrowする。

  8. Content Security Policy Level 3connect-srcディレクティブでconfigUrlに対してチェック。失敗した場合は"NetworkError" DOMExceptionをthrowする。

  9. globalObjectnavigableトップレベルtraversableの場合、"NetworkError" DOMExceptionをthrowする。

  10. ユーザーがglobalObjectnavigableトップレベルtraversableでFedCM APIを無効にしている場合、"NetworkError" DOMExceptionをthrowする。

  11. promiseを新しいPromiseとする。

  12. 以下の手順を並列で実行する:

    1. config設定ファイルの取得providerglobalObjectで得る。

    2. configが失敗なら、reject promiseを新しい"NetworkError" DOMExceptionでrejectする。

    3. accountsListアカウントの取得configproviderglobalObjectで得る。

    4. hasAccountEligibleForAutoReauthenticationをfalseとする。

    5. accountsList内の各accountについて:

      1. account["approved_clients"]が空でなく、かつproviderclientId含まない場合はcontinue。

        注: これによりIDPはアカウントが再度アクセス可能かどうかを上書きできます。例えばユーザーが外部でアカウントを切断した場合などに有用です。

      2. accountproviderglobalObject自動再認証対象ならhasAccountEligibleForAutoReauthenticationをtrueにする。

    6. hasAccountEligibleForAutoReauthenticationがfalseなら、reject promiseを新しい "NetworkError" DOMExceptionでrejectする。

    7. userInfoListを新しいlistとする。

    8. accountsList内の各accountについて:

      1. appendで以下の値でIdentityUserInfouserInfoListに追加:

        email

        account["email"]

        name

        account["name"]

        givenName

        account["given_name"]

        picture

        account["picture"]

    9. resolveuserInfoListを渡して新しいPromiseを返す。

3. アイデンティティプロバイダー HTTP API

このセクションは規範的ではありません。

IDPは一連のHTTPエンドポイントを公開します:

  1. § 3.1 well-knownファイル(マニフェストへの参照)

  2. 合意済みの場所にある§ 3.2 設定ファイル(他エンドポイントへの参照)

  3. § 3.3 アカウントエンドポイント

  4. § 3.4 クライアントメタデータエンドポイント

  5. § 3.5 IDアサーションエンドポイント

  6. § 3.6 切断エンドポイントdisconnectをサポートする場合)

FedCM APIは、サイトがブラウザに対していくつかのネットワークリクエストを実行させる機能を導入します。ブラウザは、これらのリクエストが(攻撃者がIDPを偽装している場合でも)FedCMを使ってユーザーが追跡されることがないように慎重に実行する必要があります。下記の表は実行されるネットワークリクエストの情報を示しています:

エンドポイント Cookie client_id オリジン
manifests なし なし なし
accounts_endpoint あり なし なし
client_metadata_endpoint なし あり あり
id_assertion_endpoint あり あり あり
disconnect_endpoint あり あり あり

3.1. well-knownファイル

注: ブラウザはwell-knownファイルを使い、§ 7.3.1 マニフェストフィンガープリンティングを防ぎます。

IDPは、所定の場所(".well-known"パスの "web-identity"ファイル)にwell-knownファイルを公開します。

well-knownファイルは、設定ファイル取得アルゴリズムで取得されます:

(a) Cookieなしで、 (b) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (c) RP情報をOriginRefererヘッダーで漏らさずに取得します。

例:

GET /.well-known/web-identity HTTP/1.1
Host: idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity

このファイルはIdentityProviderWellKnown JSONオブジェクトとしてパースされます。

IdentityProviderWellKnown JSONオブジェクトの意味:

provider_urls (必須), 型: sequence<USVString>

有効な§ 3.2 設定ファイルへのURLリスト。

3.2. 設定ファイル

設定ファイルは、IDPが提供する他エンドポイントへの発見手段です。

設定ファイル設定ファイル取得アルゴリズムで取得されます:

(a) Cookieなしで、 (b) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (c) RP情報をOriginRefererヘッダーで漏らさずに取得し、 (d) HTTPリダイレクトを追従しない。

例:

GET /config.json HTTP/1.1
Host: idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity

レスポンスボディは、例外なくIdentityProviderAPIConfig変換できるJSONオブジェクトでなければなりません。

IdentityProviderAPIConfig オブジェクトの各メンバーの意味:

accounts_endpoint, 型: USVString

§ 3.3 アカウントエンドポイントAPIに準拠するHTTP APIへのURL。

client_metadata_endpoint, 型: USVString

§ 3.4 クライアントメタデータAPIに準拠するHTTP APIへのURL。

id_assertion_endpoint, 型: USVString

§ 3.5 IDアサーションエンドポイントAPIに準拠するHTTP APIへのURL。

disconnect_endpoint, 型: USVString

§ 3.6 切断エンドポイントAPIに準拠するHTTP APIへのURL。

branding, 型: IdentityProviderBranding

IdentityProviderBranding オプションセット。

IdentityProviderBranding により、IDPはブランド表現の希望を示すことができ、ユーザーエージェントはこれを許可プロンプトのカスタマイズに利用可能です。

注: ブランド表現はUI構造に依存せず抽象的に設計されており、ユーザーエージェント毎に異なるUI体験を提供でき、時間の経過とともに独立して進化できます。

各メンバーの意味:

background_color, 型: USVString

IDPブランドのウィジェット(ボタン等)用背景

color, 型: USVString

IDPブランドウィジェットのテキスト

icons, 型: sequence<IdentityProviderIcon>

IdentityProviderIcon オブジェクトのリスト。

name, 型: USVString

IDPのユーザーに分かりやすい名称。

注: ブランド表現はUI構造に依存しない抽象設計で、ユーザーエージェント毎に多様なUIを提供し、独立進化できます。

IdentityProviderIcon の各メンバーの意味:

url, 型: USVString

アイコン画像のURL(正方形・単一解像度であること。複数解像度.ico不可)。アイコンはmaskable仕様準拠。

size, 型: unsigned long

正方形アイコンの幅/高さ。SVG等ベクター形式なら省略可。

注: ユーザーエージェントは、提供されたアイコンに正方形領域を割り当てます。正方形でない場合は表示しない・切り抜き・変換等の選択肢もあります。

はCSS<color> 構文のサブセットで、<hex-color>hsl()rgb()<named-color> を指定できます。

例:

{
  "accounts_endpoint": "/accounts",
  "client_metadata_endpoint": "/metadata",
  "id_assertion_endpoint": "/assertion",
  "disconnect_endpoint": "/disconnect",
  "branding": {
    "background_color": "green",
    "color": "#FFEEAA",
    "icons": [{
      "url": "https://idp.example/icon.ico",
      "size": 25
    }],
    "name": "IDP Example"
  }
}

3.3. アカウントエンドポイント

アカウントエンドポイント は、ユーザーがIDPで持っているアカウント一覧を提供します。

アカウントエンドポイントアカウントの取得アルゴリズムで取得されます:

(a) IDP Cookieありで、 (b) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (c) RP情報をOriginRefererヘッダーで漏らさずに、 (d) HTTPリダイレクトを追従しない。

例:

GET /accounts_list HTTP/1.1
Host: idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

レスポンスボディは、例外なくIdentityProviderAccountList型へ変換できるJSONオブジェクトでなければなりません。

IdentityProviderAccount のメンバー意味:

id, 型: USVString

アカウントの一意識別子。

name, 型: USVString

ユーザーの氏名(フルネーム)。

email, 型: USVString

ユーザーのメールアドレス。

given_name, 型: USVString

ユーザーの名。

picture, 型: USVString

アカウント画像のURL。

approved_clients, 型: sequence<USVString>

このアカウントがすでに登録済みのRPclientIdで照合)リスト。 サインアップ許可リクエストで、プライバシーポリシーや利用規約の表示制御に使われます。

login_hints, 型: sequence<DOMString>

アカウントに一致するすべてのログインヒントの文字列リスト。RPloginHint を使い、指定値に一致するアカウントのみを表示させることができます。

domain_hints, 型: sequence<DOMString>

アカウントに一致するすべてのドメインヒントの文字列リスト。RPdomainHint を使い、指定値またはドメインヒントを含むアカウントのみ表示できます。

例:

{
 "accounts": [{
   "id": "1234",
   "given_name": "John",
   "name": "John Doe",
   "email": "john_doe@idp.example",
   "picture": "https://idp.example/profile/123",
   "approved_clients": ["123", "456", "789"],
   "login_hints": ["john_doe"],
   "domain_hints": ["idp.example"],
  }, {
   "id": "5678",
   "given_name": "Johnny",
   "name": "Johnny",
   "email": "johnny@idp.example",
   "picture": "https://idp.example/profile/456",
   "approved_clients": ["abc", "def", "ghi"],
   "login_hints": ["email=johhny@idp.example", "id=5678"],
   "domain_hints": ["idp.example"],
  }]
}

ユーザーが未ログインの場合のIDP APIレスポンスの明確化

3.4. クライアントメタデータ

クライアントメタデータエンドポイントは、RPのメタデータを提供します。

クライアントメタデータエンドポイントクライアントメタデータ取得アルゴリズムで取得されます:

(a) Cookieなしで、 (b) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (c) RPのオリジンをOriginヘッダーに入れて、 (d) HTTPリダイレクトを追従しない。

ユーザーエージェントはclient_idも渡します。

例:

GET /client_medata?client_id=1234 HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity

レスポンスボディは、例外なくIdentityProviderClientMetadata型へ変換できるJSONオブジェクトでなければなりません。

IdentityProviderClientMetadata オブジェクトのメンバー意味:

privacy_policy_url, 型: USVString

RPのプライバシーポリシーへのリンク。

terms_of_service_url, 型: USVString

RPの利用規約へのリンク。

例:

{
  "privacy_policy_url": "https://rp.example/clientmetadata/privacy_policy.html",
  "terms_of_service_url": "https://rp.example/clientmetadata/terms_of_service.html"
}

3.5. IDアサーションエンドポイント

IDアサーションエンドポイントは、ユーザーに関する署名付きアサーションを含む新しいトークンを生成します。

IDアサーションエンドポイントIDアサーション取得アルゴリズムで取得されます:

(a) POSTリクエストとして、 (b) IDP Cookieありで、 (c) RPのオリジンをOriginヘッダーに入れ、 (d) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (e) HTTPリダイレクトを追従しない。

リクエストボディ(application/x-www-form-urlencoded)には以下のパラメータが含まれます:

client_id

RPの一意識別子(IDPから提供)

nonce

リクエストnonce

account_id

選択されたアカウント識別子。

disclosure_text_shown

ユーザーエージェントがユーザーに、IDPRPへどんな情報(例:"idp.exampleはあなたの氏名・メールアドレス...をrp.exampleに共有します"など)を共有するか明示したかどうか(新規ユーザー用サインアップ許可リクエストで利用)。利用規約・プライバシーポリシー表示保証としてIDPへ通知されます。

例:

POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true
IDPは、悪意のあるRPに他のRPのIDトークンが渡らないよう、Originヘッダー値がclientIdで表されていることを必ず確認しなければなりません。 clientId はIDP固有なので、ユーザーエージェントではこの確認はできません。

レスポンスボディは、例外なくIdentityProviderToken型へ変換できるJSONオブジェクトでなければなりません。

IdentityProviderToken のメンバー意味:

token, 型: USVString

生成されたトークン。

token の内容はユーザーエージェントにとって不透明であり、IDPがログイン促進のためにRPへ渡したい任意の情報を含めることができます。したがって、RPがトークン検証アルゴリズムに従い検証責任を持ちます。例としてはOIDC Connect Core § IDTokenValidation参照。

注: IDPにとっては、ポータブルなアカウントの扱いも検討事項です。ポータビリティはIDPに一任され、IDPは様々な手段(例:OIDC Account Porting)から選択できます。

例:

{
  "token" : "eyJC...J9.eyJzdWTE2...MjM5MDIyfQ.SflV_adQssw....5c"
}

3.6. 切断エンドポイント

切断エンドポイントは、RPIDPアカウント間で作成されたフェデレーションログイン接続を切断し、アカウントのid を返すことで、ユーザーエージェント接続済みアカウントセットから削除できるようにします。

切断エンドポイントdisconnect メソッド呼び出し時に取得されます:

(a) POSTリクエストとして、 (b) IDP Cookieありで、 (c) RPのオリジンをOriginヘッダーに入れ、 (d) Sec-Fetch-Destヘッダーがwebidentityにセットされ、 (e) HTTPリダイレクトを追従しない、 (f) "cors"モードで。

リクエストボディ(application/x-www-form-urlencoded)には以下が含まれます:

client_id

RPの一意識別子(IDPから提供)

account_hint

IDPアカウントの切断対象となるアカウントヒント(RP用)。

例:

POST /fedcm_disconnect_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
client_id=client1234&account_hint=hint12

切断が失敗した場合、IDPはエラー応答可能です。成功時は、レスポンスボディが例外なくDisconnectedAccount型へ変換できるJSONオブジェクトでなければなりません。

account_id, 型: USVString

切断が成功したアカウントのid

IDPaccount_id を必ず返さなければなりません。これはaccount_hint と異なる場合があり、IDはユーザーエージェント接続済みアカウントセットからアカウントを切断するために必要です。IDPがエラーを返す場合や、ユーザーエージェントがIDPの返したIDのアカウントを見つけられない場合、関連する(RP, IDP)に紐付くすべてのアカウントが接続済みアカウントセットから削除されます。

4. Permissions Policy統合

FedCMは、文字列"identity-credentials-get"で識別されるポリシー制御機能を定義します。 そのデフォルト許可リスト"self"です。

Documentpermissions policyは、その文書でBrowser APIを使ってクレデンシャルオブジェクトを取得できるかどうかを決定します。 navigator.credentials.get({identity:..., ...}) を、その文書がidentity-credentials-get 機能の利用を許可されていない場合に呼び出すと、 promise rejected with "NotAllowedError" DOMExceptionになります。

この制限は、Permissions Policyで説明されている仕組みで制御できます。

注: Credential Management Level 1で規定されるアルゴリズムが、実際のpermissions policy評価を行います。これは評価がcurrent settings objectへのアクセス時に必要だからです。本仕様が拡張する内部メソッドは並列で呼び出されるため、こうしたアクセス権を持ちません。並列呼び出しは CredentialsContainerRequest a Credential抽象操作によります。

5. ユーザーエージェント自動化

ユーザーエージェントの自動化やウェブサイトのテストのために、本ドキュメントはFedCMダイアログ操作用のWebDriver拡張コマンドを定義します。

5.1. 拡張機能

下記の拡張コマンドの利用可能性を通知するため、新しい拡張機能が定義されます。

機能 キー 値型 説明
Federated Credential Management Support "fedcm:accounts" boolean エンドポイントノードが、全てのFederated Credential Managementコマンドをサポートしているか示す。

機能検証時に、拡張固有のサブステップとして"fedcm:accounts"valueを検証する手順:

  1. valuebooleanでなければ、WebDriverエラーerror codeinvalid argument)を返す。

  2. それ以外の場合はdeserializedvalueをセット。

機能マッチング時に、"fedcm:accounts"valueをマッチさせる拡張手順:

  1. valuetrueで、エンドポイントノードがFederated Credential Managementコマンドを一つもサポートしていなければ、マッチは失敗。

  2. それ以外はマッチ成功。

5.2. ダイアログキャンセル

HTTPメソッド URIテンプレート
POST /session/{session id}/fedcm/canceldialog

リモートエンド手順

  1. FedCMダイアログが現在開いていなければ、WebDriverエラーerror codeno such alert)を返す。

  2. ダイアログを閉じ、ユーザーがアカウント選択せずキャンセルしたものとしてIdentityCredential作成アルゴリズムを継続。

  3. success(データnull)を返す。

5.3. アカウント選択

HTTPメソッド URIテンプレート
POST /session/{session id}/fedcm/selectaccount

リモートエンド手順

  1. parametersがJSONObjectでなければ、WebDriverエラーerror codeinvalid argument)を返す。

  2. FedCMダイアログが現在開いていなければ、WebDriverエラーerror codeno such alert)を返す。

  3. accountIndexparametersから"accountIndex"プロパティ取得で得る。

  4. accountIndexundefined または0未満、またはユーザーが選択可能なアカウント数以上なら、WebDriverエラーerror codeinvalid argument)を返す。

  5. ダイアログを閉じ、accountIndexで指定されたアカウントをユーザーが選択し、必要に応じてサインアップ許可したものとしてIdentityCredential作成アルゴリズムを継続。

  6. success(データnull)を返す。

5.4. ダイアログボタンをクリック

HTTPメソッド URIテンプレート
POST /session/{session id}/fedcm/clickdialogbutton

リモートエンド手順

  1. parametersがJSONObjectでなければ、WebDriverエラーerror codeinvalid argument)を返す。

  2. dialogButtonparametersから"dialogButton"プロパティ取得で得る。

  3. dialogButtonが文字列"ConfirmIdpLoginContinue"でなければ、WebDriverエラーerror codeinvalid argument)を返す。

  4. FedCMダイアログが現在開いていないか、ダイアログがIDPログイン確認ダイアログでなければ、WebDriverエラーerror codeno such alert)を返す。

  5. ユーザーがIDPログイン確認ダイアログで「続行」ボタンをクリックしたものとしてログインフローを開始する。

  6. success(データnull)を返す。

5.5. アカウントリスト

HTTPメソッド URIテンプレート
GET /session/{session id}/fedcm/accountlist

以下はリモートエンド手順です:

  1. FedCMダイアログが現在開いていない場合、WebDriverエラーerror code: no such alert)を返す。

  2. accountsを、現在のフローでユーザーが選択できる(またはできた)アカウントのリストとする。

  3. listを空リストとする。

  4. accounts内の各accountについて:

    1. accountStateを、accountとそのIDPのIdentityProviderRequestOptionsを使って接続状態算出アルゴリズムで得る。

    2. appendで、以下のプロパティを持つ辞書listに追加:

      1. accountIdにはアカウントのidをセット

      2. emailにはアカウントのemailをセット

      3. nameにはアカウントのnameをセット

      4. givenNameにはアカウントのgiven_name(あれば)をセット

      5. pictureUrlにはアカウントのpicture(あれば)をセット

      6. idpConfigUrlにはこのアカウントが所属するIDPのconfigURLをセット

      7. loginStateaccountStatedisconnectedなら"SignUp"、それ以外は"SignIn"

      8. termsOfServiceUrlloginState"SignUp"かつ値があればterms_of_service_url、そうでなければundefined

      9. privacyPolicyUrlloginState"SignUp"かつ値があればprivacy_policy_url、そうでなければundefined

  5. データlistsuccessを返す。

5.6. タイトル取得

HTTPメソッド URIテンプレート
GET /session/{session id}/fedcm/gettitle

注: このコマンドは自動化でcontext apiが正しく適用されたか検証できます。

リモートエンド手順

  1. FedCMダイアログが現在開いていない場合、WebDriverエラーerror code: no such alert)を返す。

  2. dataを、以下のプロパティを持つオブジェクトの辞書とする:

    1. title:開いているダイアログのタイトル

    2. subtitle:開いているダイアログのサブタイトル(あれば)

  3. データdatasuccessを返す。

5.7. ダイアログ種別取得

HTTPメソッド URIテンプレート
GET /session/{session id}/fedcm/getdialogtype

リモートエンド手順

  1. FedCMダイアログが現在開いていない場合、WebDriverエラーerror code: no such alert)を返す。

  2. typeを以下の値でセット:ユーザーが自動再認証されている場合は"AutoReauthn"、アカウント選択ダイアログなら"AccountChooser"、IDPログイン確認ダイアログなら"ConfirmIdpLogin"。

  3. データtypesuccessを返す。

5.8. 遅延有効化設定

HTTPメソッド URIテンプレート
POST /session/{session id}/fedcm/setdelayenabled

リモートエンド手順

  1. parametersがJSONObjectでなければ、WebDriverエラーerror code: invalid argument)を返す。

  2. enabledparametersから"enabled"プロパティ取得で得る。

  3. enabledundefinedまたはbooleanでなければ、WebDriverエラーerror code: invalid argument)を返す。

  4. enabledがfalseならpromise拒否遅延を無効化、それ以外は再有効化。

  5. success(データnull)を返す。

5.9. クールダウンリセット

HTTPメソッド URIテンプレート
POST /session/{session id}/fedcm/resetcooldown

リモートエンド手順

  1. ユーザーエージェントがクールダウン遅延(ダイアログを閉じた後APIが一定時間無効化される)を用いている場合、このコマンドでクールダウンをリセットし、次のFedCM呼び出しを成功可能にする。

  2. success(データnull)を返す。

6. セキュリティ

このセクションではFedCM APIのセキュリティ考慮事項をいくつか説明します。プライバシーに関する考慮事項は§ 7 Privacyに別途記載しています。

6.1. Content Security Policy

FedCM APIによる最初のfetchは公開マニフェストリストと設定ファイルです。悪意あるスクリプトがRPで実行され、FedCM APIを使って悪意あるIDPへAPI呼び出しを行うことを考えます(このIDPはRPが信頼しないもの)。もし呼び出しが成功すれば、RP上に悪意あるIDPのサインインUIが表示され、ユーザーを騙す可能性があります。これを防ぐ仕組みがContent Security Policy Level 3チェックです。悪意あるIDPのマニフェストのオリジンがRPのContent Security Policy Level 3のallowlistに含まれなければ、FedCM UIは表示されません。その後のfetchはすべて設定ファイルの同一オリジン、または内容に依存するため追加のチェックは不要です。

非同一オリジンfetch(例:ブランドアイコン)にはCSPチェックはありません。これはmanifestから直接指定され、ユーザーエージェントが画像を描画するため、RPサイトに影響したりRPが画像内容を検査することはできません。

6.2. Sec-Fetch-Destヘッダー

FedCM APIはIDP上に複数の非静的エンドポイントを導入するため、XSS攻撃から守る必要があります。FedCM APIはSec-Fetch-Destヘッダー(禁止リクエストヘッダー)に新しい値webidentityを導入します。この値はウェブサイトが勝手にセットできないため、IDPはFedCMブラウザからのリクエストであることを確認できます。IDPはこのヘッダー値をcredentialedリクエストで必ずチェックし、FedCM APIによる正当なリクエストか確かめます。悪意あるサイトはFedCM APIを乱用できず、新エンドポイントの保護は十分です。

6.3. CORSヘッダー

FedCM APIはIDアサーションエンドポイントのレスポンスをRPに共有できるため、IDPはこの共有に明示的同意する必要があります。これはこのエンドポイントfetch時に"cors"モードを使うことで実現されます。Sec-Fetch-Destを無視するサーバーでもCORSは無視できず、CORSなしならfetchは失敗します。

6.4. ブラウザUIなりすまし

FedCM APIは新たな(信頼された)ユーザーエージェントUIを導入し、ユーザーエージェントはこのUIをページ内容の上に全面表示する場合があります(このUI表示はページがFedCM呼び出しを行った結果)。悪意あるサイトがFedCM UIを模倣し、ユーザーに信頼されたブラウザUIと誤認させて、ユーザーが本来ブラウザにだけ入力する情報(他サイトのユーザー名・パスワードなど)を盗む懸念があります。ですがFedCM UIはIDPのユーザーアカウント情報等サイトが取得できないメタデータを使うため、悪意サイトはアカウント情報を知ることができません(既にユーザーが侵害されていない限り)。推測はできるかもしれませんが、ブラウザは模倣困難なUIや関係するドメイン表示を推奨します。iframe等だけでFedCM UIを模倣し情報収集する攻撃は明らかに本物UIと異なります。さらにFedCM UIはトップレベルフレーム(または明示許可されたiframe)からのみ表示可能なので、特権UIはトップレベルフレームの意思でのみ表示され、悪意iframeが重要なページ内容を勝手に隠すことはできません。

7. プライバシー

本セクションはウェブにおけるフェデレーションIDのプライバシーリスク全体像を説明し、ブラウザ仲介設計のプライバシーリスクとメリット測定のための基礎とするものです。

7.1. 主体

このセクションではAPI呼び出しに関与する4つの主体とその振る舞いの期待を説明します。

  1. ユーザーエージェント§ 2 ブラウザAPIを実装し、RPIDPコンテンツの実行コンテキストを管理します。ユーザーエージェントはユーザーから信頼され、RP・IDPからも間接的に信頼されている前提です。

  2. RPはFedCM APIを呼び出してユーザー認証や情報取得を行うウェブサイトです。全てのサイトがAPIを呼び出せるため、RPがユーザー情報収集や利用を適切に制限するとは限りません。

  3. IDPはFedCM呼び出しの対象となる第三者ウェブサイトで、トークン取得のために呼び出されます。通常IDPはRPより信頼度が高いですが、IDPがユーザー情報を不適切に利用する可能性もあります。またAPIで指定されたIDPがユーザーの知るIDPでない場合は、事前にユーザー情報を持たない可能性が高いです。

  4. トラッカーはIDPでない第三者ウェブサイトで、FedCM APIを乱用してユーザーのウェブ横断追跡を試みる場合があります。トラッカーはRPによって意図的/非意図的に埋め込まれることがあり(例えば動的に読み込まれるスクリプトタグ等)、通常ウェブサイトのUIを変更せず検出困難です。複数サイトでトラッキングスクリプト追加に成功した場合、ユーザー情報を販売等に利用される可能性があります。FedCM APIがトラッカーによるウェブ横断追跡に使われてはなりません。

以上に基づき、プライバシー議論は以下の前提を置きます:

  1. RPIDPトラッカーが、ユーザーの許可なしに特定ユーザーが特定サイトを訪れたことを知るのは許容されません。つまりユーザーエージェントは、特定ユーザーIDが特定サイトを訪問した知識をRP・IDP・トラッカーから隠す必要があります。ユーザーが許可すればRP・IDPへこの知識を共有できます。特にRPはユーザーIDを知ってはならず、IDPはユーザーがサイトを訪問したことをFedCMフローで許可取得前には知ってはなりません。

  2. ユーザーエージェントは、ユーザーがIDPとRPが通信してユーザー識別を行う許可をいつ与えたか判断する責任があります。

  3. 一度ユーザーエージェントがユーザーの許可取得を認めた場合、RPとIDPは必要なユーザーアカウント情報を知ってもよいですが、RPは他のユーザーアカウント情報を知ってはなりません。

7.2. ネットワークリクエスト

本仕様は、FedCMによるfetchがRP指定のプロバイダーと同一オリジンになることを保証します。fetchでCookieを使う場合、指定オリジンのCookieが使われるため、任意オリジンを許すとCookie共有の混乱やプライバシー問題が生じます。fetchを同一オリジン化するにはリダイレクト無効化・URLのオリジン確認が有効です。

7.3. 攻撃シナリオ

このセクションでは、さまざまな主体がユーザー情報の取得を試みるシナリオについて説明します。考慮する可能性は:

本セクションにおいて、ある主体が情報収集に参加していると見なすのは、直接または間接的に上記の脅威実現を目的とする行動をとった場合です。

注: 間接的な共謀の例として、RPIDP提供のスクリプトをインポートし、そのIDPがユーザー追跡を意図するケースが挙げられます。

議論の便宜上、本書ではサードパーティCookieがデフォルトで無効であり、トラッキング手段として機能しなくなっていることを前提とします。またリンクデコレーションやpostMessageによる「バウンストラッキング」への緩和策も何らか実装されているとします。これらのシナリオの多くは、これらが使えない場合にユーザー追跡がどう行われるかを検討します。詳細はPervasive Monitoring Is an Attackも参照。

7.3.1. マニフェストによるフィンガープリンティング

もしFedCM APIが2段階のマニフェスト(IdentityCredential作成アルゴリズム参照)を持たず、直接単一のマニフェストだけだった場合、以下のフィンガープリンティング攻撃が可能になります:

// 以下のコードはmanifest JSONファイルをfetchし、RPのオリジンを知ることができてしまう :(
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: \`https://idp.example/${window.location.href}\`
    }]
  }
});

注: この攻撃の詳細はこちらで読めます。

ここでRPは、マニフェストをIDPから取得する際に自身を識別しています。これとFedCM APIが行う認証付きfetchが組み合わさることで、IDPはユーザーがどのウェブサイトを訪問しているか簡単に追跡できるようになり、ユーザーの許可も不要となります。これへの対策は§ 3.1 well-knownファイルの導入です。IDPドメインのルートにファイルがあることを強制することで、ファイル名からRP情報のフィンガープリントが生じないようにしています。

この場所に全マニフェストを置くこともできますが、実際にはそこから本マニフェストへの参照だけを置きます。これにより、IDPが将来的に複数マニフェストを必要とする場合にも柔軟に対応でき、単一ファイルだけに縛られません。またIDPの実装上、マニフェストの変更がドメインルート以外の任意ファイルに対して行えるため、更新の容易さにも寄与します。

7.3.2. タイミング攻撃

タイミング攻撃では、RPIDPが共謀し、IDPが(RPのオリジン, IDPのユーザーID)のペアをユーザーの許可なく算出できるようにします。この攻撃は決定的ではなく、統計誤差の余地があります。なぜなら追跡には2つの断片的情報を突き合わせる必要があるためですが、それでもこの攻撃を困難にすることが重要です。ここではネットワークリクエストに大きなフィンガープリンティング要素(例:IPアドレス)がない場合を仮定します。これらはユーザーエージェントごとに異なり完全排除は困難ですが、ユーザーエージェントは今後これらへの対策が期待されます。ネットワークリクエストに結びつく情報はタイミング攻撃を容易にするため、特に対策の重要性が増します。

注: この攻撃の詳細はこちらで議論されています。

攻撃の流れ:

  1. RPはAPI呼び出し時刻(A)を記録し、IDPに送信して、IDP側でRPのクライアントメタデータfetch到着時刻を記録します(Aはサイトと紐付く)。

  2. 認証付きリクエストがIDPに送信されるが、RPは明示的に識別されない。ただし上記リクエストに近い時刻に送信されるため、IDPは到着時刻(B)を記録(BはユーザーIDと紐付く)。

  3. IDPはAとBを突き合わせて(サイト, ユーザーID)ペアを高確率で割り出す。フィンガープリンティングがあれば精度はさらに上がる。

この種の相関はFedCM無しでもクロスオリジントップレベルナビゲーション等で可能ですが、FedCMでタイミング分解能が上がったりユーザーへの可視性が下がった場合(例:IDPが空アカウントを返してブラウザUI非表示にする等)、問題は悪化します。

ユーザーエージェントは、ユーザー保護のため、この攻撃への対策を相互運用可能な形で講じるべきです。

7.3.3. IDPによる侵入

Target Privacy Threat Model § hl-intrusionより

プライバシー被害はサイトが何かを知ることからだけ起きるとは限らない。

RFC6973: Intrusionより

侵入とは、個人の生活や活動を妨害・中断する侵襲的行為である。個人が放っておかれたい願望を妨げたり、時間や注意力を奪ったり、活動を中断したりする。

フェデレーションの文脈での侵入は、RPIDPが共謀し、ユーザーの意図に比して過剰にログインを勧める場合に発生します。望ましくない通知同様、RPIDPと共謀し、ユーザーのログインを執拗に促すケースです。

ユーザーエージェントはユーザー操作を仲介し、ユーザー意図やプライバシーリスクに応じて適切なUIを提供することで、このような侵入を緩和できます。例えば、ユーザー意図の確信度が高い場合は目立つ/強いモーダルダイアログを表示し、確信度が低い場合は控えめなUIヒントを表示するなどです。

ユーザーエージェントは、リスクに応じてユーザー体験の妨害度合いを調整することも可能です。例えば、指示付き識別子を交換する場合は意図しない結果に自信が持てるため、より強い体験を提供し、グローバル識別子交換の場合はより控えめな体験にするなどです。

7.3.4. クロスサイト相関

この攻撃は、複数のRPが共謀し、ユーザーデータを使ってユーザーを相関付け、より詳細なプロフィールを構築する場合に発生します。ユーザーが氏名、メールアドレス、電話番号などを複数のリライングパーティに自発的に提供した場合、それらのRPは協力して、そのユーザーやユーザーの複数サイトでの活動のプロフィールを作成できます。これは複数RPのアカウントデータベース間でユーザー情報を「結合」することに相当し、「ジョイン」と呼ばれる場合もあります。このような相関やプロフィール構築はユーザーの管理外であり、ユーザーエージェントIDPの監視範囲外です。

  1. ユーザーはIDPを使ってRP1(宝石を販売する)にサインインし、RP1にメールアドレス user@email.example を提供する。

  2. ユーザーはIDPを使ってRP2(住宅を販売する)にサインインし、RP2にメールアドレス user@email.example を提供する。

  3. ユーザーはRP1で結婚指輪のコレクションを閲覧する。

  4. RP1はユーザーが結婚指輪を探していることを、帯域外でRP2に伝える(メールアドレス user@email.example を共有)。

  5. ユーザーはRP2で住宅の在庫を閲覧する。

  6. RP2は、ユーザーがRP1で結婚指輪を探している事実を利用して、広告や住宅の在庫検索を調整する。

  7. ユーザーは、RP2が自分が結婚指輪を探していることを知っていることに驚く。

RP間でユーザーデータをバックチャネルで結合する問題は、識別可能なユーザーデータが広がることに起因しています。これを解決するためには、特定のIDPごとにユーザー固有で、他のRPと相関できない有効な識別子(directed identifier)を発行する方法があります。過去には、ユーザー名やIDPRPなどを一方向ハッシュして実現するスキームも存在しました。こうした識別子は一意であり、他のRPと相関させることはできません。

7.3.5. 無許可のデータ利用

もう一つの攻撃は、RPIDPがユーザーの情報をユーザーが許可していない目的で利用する場合です。ユーザーがIDPによるRPへの情報提供を許可した場合、その許可はサインインやパーソナライズなど特定の目的に限定されています。例えば、RPがそのデータをユーザーが予期しない、かつ許可していない目的(スパムリストへのメールアドレス販売など)に利用する可能性があります。スパムリスクはdirected identifierを使っていても存在します。

7.3.6. RPによるフィンガープリンティング

この攻撃は、RPがクライアント状態ベースのトラッキングを使ってユーザーを識別する場合に発生します。ウェブにクライアント状態を何らか公開するAPIは、フィンガープリンティングのベクターになるリスクがあります。このAPIの目的は、ユーザーがRPに自身を識別させることです。そして、ユーザーはその識別へのアクセスを取り消す(例:ログアウトする)ことができなければなりません。しかし、トラッキング目的のRPは、過去にログインしたユーザーを検出するために状態を保持し続けることがあります:

7.3.7. 二次利用

二次利用とは、個人から収集した情報を、本人の許可なく収集時と異なる目的で利用することです。この攻撃は、IDPがサインイン用に収集した情報を他の目的で悪用する場合に発生します。

既存のフェデレーションプロトコルでは、IDPがどのサービスがトークンを要求しているかを知る必要があります。IDプロバイダーはこの事実を利用し、同じアカウントでフェデレーションを利用したユーザーのサイト横断プロフィールを構築できます。例えば、このプロフィールはIDPが管理するサイトでユーザーが閲覧している際にターゲット広告を表示する目的で使われる可能性があります。

このリスクは、IDPが事前にユーザーアカウント情報を持たない場合(例えば正規のIDPでない場合)でも存在し得ます。なぜならFedCMリクエストがIDPにcredentialedで送信されるからです。特に、RPIDPと共謀し、§ 7.3.2 タイミング攻撃による追跡を可能にしている場合は、その可能性が高まります。

  1. ユーザーはIDPを使ってRP1(宝石を販売する)にサインインする。

  2. ユーザーは同じIDPを使ってRP2(住宅を販売する)にサインインする。

  3. ユーザーはIDPにアクセスする。

  4. IDPがユーザーがRP1およびRP2にアカウントを持っていることを知っているため、IDPは新婚旅行用のバケーション広告を表示できる。

  5. ユーザーは、自分のIDPが結婚の予定を知っていることに驚く。

IDPによるユーザー追跡の防止は難しい:RPはセキュリティ(トークン再利用・不正防止)のため、IDトークンに記載される必要がある。IDPRPを秘匿しつつ、トークン再利用防止を実現する暗号技術も開発されている(Mozillaのpersonasなど)。しかし、これらの手法は本仕様には採用されていない。

8. 拡張性

注: 拡張メカニズムについて説明します。

9. 謝辞

注: 謝辞セクションを記載します。

10. FPWD課題

注: WGは以下の課題をクリティカルなオープン課題としてラベル付けしており、Candidate Recommendation公開前に正式に対応する必要があります。

適合性

ドキュメント慣例

適合要件は、記述的なアサーションとRFC 2119用語の組み合わせで表現されます。 仕様書の規範的部分における「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」はRFC 2119の記述に従って解釈されます。 ただし、可読性のため、これらの語句は本仕様書ではすべて大文字では記載されていません。

この仕様書のすべてのテキストは、非規範的と明示されたセクション、例、および注記を除き規範的です。 RFCにおける要求レベルを示すキーワード

本仕様の例は「for example」で始まるか、class="example"で規範文から区別されます。 例:

これは情報提供用の例です。

情報提供用の注記は「Note」で始まり、class="note"で規範文から区別されます。 例:

注: これは情報提供用の注記です。

適合アルゴリズム

アルゴリズムの一部として命令形で表現された要件(「先頭の空白文字を取り除く」「falseを返してこの手順を中止する」など)は、アルゴリズムの導入に使われたキーワード(「must」「should」「may」等)の意味で解釈されます。

アルゴリズムや特定のステップとして表現された適合要件は、最終結果が同等であればどのように実装しても構いません。 本仕様のアルゴリズムは理解しやすさを重視しており、パフォーマンス重視ではありません。 実装者は最適化を推奨します。

索引

この仕様で定義された用語

他仕様で定義された用語

参考文献

規範的参考文献

[CLEAR-SITE-DATA]
Mike West. Clear Site Data. 2017年11月30日. WD. URL: https://www.w3.org/TR/clear-site-data/
[CREDENTIAL-MANAGEMENT-1]
Nina Satragno; Marcos Caceres. Credential Management Level 1. 2024年8月13日. WD. URL: https://www.w3.org/TR/credential-management-1/
[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. 2024年6月18日. WD. URL: https://www.w3.org/TR/CSP3/
[CSS-COLOR-4]
Chris Lilley; Tab Atkins Jr.; Lea Verou. CSS Color Module Level 4. 2024年2月13日. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-COLOR-5]
Chris Lilley; 他. CSS Color Module Level 5. 2024年2月29日. WD. URL: https://www.w3.org/TR/css-color-5/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016年3月17日. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FETCH-METADATA]
Mike West. Fetch Metadata Request Headers. 2023年10月31日. WD. URL: https://www.w3.org/TR/fetch-metadata/
[HTML]
Anne van Kesteren; 他. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[OIDC-Connect-Core]
OIDC Connect Core. URL: https://openid.net/specs/openid-connect-core-1_0.html
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy. 2024年7月24日. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[PRIVACY-THREAT-MODEL]
Target Privacy Threat Model. URL: https://w3cping.github.io/privacy-threat-model/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC6973]
A. Cooper; 他. Privacy Considerations for Internet Protocols. 2013年7月. Informational. URL: https://www.rfc-editor.org/rfc/rfc6973
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Semantics. 2022年6月. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[SECURE-CONTEXTS]
Mike West. Secure Contexts. 2023年11月10日. CR. URL: https://www.w3.org/TR/secure-contexts/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBDRIVER1]
Simon Stewart; David Burns. WebDriver. 2018年6月5日. REC. URL: https://www.w3.org/TR/webdriver1/
[WebDriver2]
Simon Stewart; David Burns. WebDriver. 2024年7月23日. WD. URL: https://www.w3.org/TR/webdriver2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

参考情報

[CM]
Credential Management. URL: https://w3c.github.io/webappsec-credential-management/
[PERMISSIONS-POLICY]
Permissions Policy. URL: https://w3c.github.io/webappsec-permissions-policy
[PRIVACY-MODEL]
Privacy Model. URL: https://github.com/michaelkleber/privacy-model
[RFC7258]
Pervasive Monitoring Is an Attack. URL: https://datatracker.ietf.org/doc/html/rfc7258

IDL索引

enum LoginStatus {
  "logged-in",
  "logged-out",
};

[Exposed=Window, SecureContext] 
interface NavigatorLogin {
  Promise<undefined> setStatus(LoginStatus status);
};

partial interface Navigator {
  [SecureContext] readonly attribute NavigatorLogin login;
};

dictionary IdentityCredentialDisconnectOptions : IdentityProviderConfig {
  required USVString accountHint;
};

[Exposed=Window, SecureContext]
interface IdentityCredential : Credential {
  static Promise<undefined> disconnect(optional IdentityCredentialDisconnectOptions options = {});
  readonly attribute USVString? token;
  readonly attribute boolean isAutoSelected;
};

dictionary DisconnectedAccount {
  required USVString account_id;
};

partial dictionary CredentialRequestOptions {
  IdentityCredentialRequestOptions identity;
};

enum IdentityCredentialRequestOptionsContext {
  "signin",
  "signup",
  "use",
  "continue"
};

dictionary IdentityCredentialRequestOptions {
  required sequence<IdentityProviderRequestOptions> providers;
  IdentityCredentialRequestOptionsContext context = "signin";
};

dictionary IdentityProviderConfig {
  required USVString configURL;
  required USVString clientId;
};

dictionary IdentityProviderRequestOptions : IdentityProviderConfig {
  USVString nonce;
  DOMString loginHint;
  DOMString domainHint;
};

dictionary IdentityProviderWellKnown {
  required sequence<USVString> provider_urls;
};

dictionary IdentityProviderIcon {
  required USVString url;
  unsigned long size;
};

dictionary IdentityProviderBranding {
  USVString background_color;
  USVString color;
  sequence<IdentityProviderIcon> icons;
  USVString name;
};

dictionary IdentityProviderAPIConfig {
  required USVString accounts_endpoint;
  required USVString client_metadata_endpoint;
  required USVString id_assertion_endpoint;
  required USVString login_url;
  USVString disconnect_endpoint;
  IdentityProviderBranding branding;
};

dictionary IdentityProviderAccount {
  required USVString id;
  required USVString name;
  required USVString email;
  USVString given_name;
  USVString picture;
  sequence<USVString> approved_clients;
  sequence<DOMString> login_hints;
  sequence<DOMString> domain_hints;
};
dictionary IdentityProviderAccountList {
  sequence<IdentityProviderAccount> accounts;
};

dictionary IdentityProviderToken {
  required USVString token;
};

dictionary IdentityProviderClientMetadata {
  USVString privacy_policy_url;
  USVString terms_of_service_url;
};

dictionary IdentityUserInfo {
  USVString email;
  USVString name;
  USVString givenName;
  USVString picture;
};

[Exposed=Window, SecureContext] interface IdentityProvider {
    static undefined close();
    static Promise<sequence<IdentityUserInfo>> getUserInfo(IdentityProviderConfig config);
};

課題一覧

HTTPヘッダーのチェックはFetch仕様に移すべきです。すべてのリソースロードに影響するためです。
Clear-Site-DataがパーティションCookie対応したら、この記述も更新すべきです。
接続済みアカウントセットRPで二重キー化すべきです(つまりリクエスターと埋め込み元両方、またはiframeとトップレベル両方を含む)。そうしないとトップレベルの状態が埋め込み元で使われたり変更されたりし、漏洩や不要なクロスオリジン通信が生じます。
IDPを複数選択可能にする対応が必要です。詳細はこちら
RPが第二のオプションを要求できる方法も提供すべきかも知れません(ユーザー操作に基づいてゲートする等)。議論はこの課題参照。
仕様はまだすべてのリクエストmode="user-agent-no-cors"で生成するように更新されていません。詳細はプルリク参照。
provider_urls配列のサイズ緩和
仕様はまだすべてのリクエストmode="user-agent-no-cors"で生成するように更新されていません。詳細はプルリク参照。
このアルゴリズムの認証付きfetchは、ユーザーが許可する前にユーザーIDがタイミング攻撃で漏洩する可能性があります。調査中であり、詳細はこちら
仕様はまだすべてのリクエストmode="user-agent-no-cors"で生成するように更新されていません。詳細はプルリク参照。
アカウントリスト返却時、ID重複を検証すべきです。詳細はこちら
仕様はまだすべてのリクエストmode="user-agent-no-cors"で生成するように更新されていません。詳細はプルリク参照。
仕様はまだすべてのリクエストmode="user-agent-no-cors"で生成するように更新されていません。詳細はプルリク参照。
検討IdentityProvidergetUserInfo()メソッドの正しい場所かどうか。
明確化:ユーザーが未ログインの場合のIDP APIレスポンス。