認証情報管理レベル1

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2024/WD-credential-management-1-20240813/
最新の公開バージョン:
https://www.w3.org/TR/credential-management-1/
編集者草案:
https://w3c.github.io/webappsec-credential-management/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/credential-management-1/
フィードバック:
public-webappsec@w3.org 件名「[credential-management] … メッセージトピック …」 (アーカイブ)
GitHub
編集者:
(Google Inc.)
(Apple Inc.)
以前の編集者:
(Google Inc.)
(Google Inc.)
参加方法:
Issueを提出 (オープン中のIssue)

概要

本仕様は、ウェブサイトがユーザーエージェントに対してユーザーの認証情報を要求できる命令型APIと、ユーザーエージェントが将来の利用のためにユーザーの認証情報を正しく保存するのを支援する方法について記述しています。

この文書のステータス

このセクションは、公開時点におけるこの文書のステータスについて説明します。 現在のW3C出版物一覧とこの技術報告書の最新改訂は、W3C技術報告書インデックス https://www.w3.org/TR/で確認できます。

この文書は、Webアプリケーションセキュリティ作業部会によって、勧告トラックを用いて作業草案として公開されました。本文書はW3C勧告となることを意図しています。

(アーカイブ) 公開メーリングリスト public-webappsec@w3.org (手順参照) は、本仕様の議論に推奨されます。 メール送信時は、件名に「credential-management」を含めてください (例:「[credential-management] …コメント要約…」のように)。

作業草案としての公開は、W3Cおよびその会員による承認を意味するものではありません。この文書は草案であり、今後随時更新、置換、廃止される可能性があります。本文書を進行中の作業以外のものとして引用するのは不適切です。

この文書は、Webアプリケーションセキュリティ作業部会によって作成されました。

この文書は、W3C特許ポリシーの下で運営されるグループによって作成されました。 W3Cは、グループの成果物に関連して行われた特許開示の公開リストを管理しています。 また、特許開示の方法についてもそのページに記載されています。 特許の本質的権利を含むと考えられる特許について実際に知っている場合は、W3C特許ポリシー第6節に従い開示してください。

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

1. はじめに

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

ウェブサイトへのサインインは、理想よりも難しいものです。ユーザーエージェントは、ユーザー体験を様々な方法で向上させる独自の立場にあり、ほとんどの現代的なユーザーエージェントは、ブラウザでネイティブに認証情報管理機能をある程度備えています。例えば、ユーザーはウェブサイトのユーザー名やパスワードを保存でき、後でそれらの認証情報がサインインフォームに自動入力されますが、その成功度は様々です。

autocomplete 属性は、ウェブサイトがユーザーエージェントと協力してサインインフォームの検出・自動入力機能を向上させる宣言的な仕組みを提供します。特定のフィールドを「ユーザー名」や「パスワード」としてマークすることで、ユーザーエージェントは、こうした詳細をマークアップで提供していないウェブサイトにも対応するため、さまざまな検出ヒューリスティックを実装しています。

このヒューリスティックと宣言的検出の組み合わせは比較的うまく機能しますが、現状には検出が困難な大きなギャップが残っています。例えば、一般的でないサインインの仕組み(XMLHttpRequest [XMLHTTPREQUEST]で認証情報を送信する場合など)は、確実な検出が困難です。また、ユーザーがフェデレーテッドIDプロバイダーを用いて認証したいという、近年増加しているケースも同様です。ウェブサイトがユーザーエージェントの認証情報マネージャーとより直接的にやり取りできれば、認証情報マネージャーの精度が向上し、フェデレーテッドサインインの支援も可能になります。

これらのユースケースについては、§ 1.1 ユースケースおよび認証情報管理:ユースケースと要件で詳しく説明されています。本仕様は、ウェブサイトが認証情報をユーザーのために要求したり、サインインが成功した際にユーザーエージェントへ認証情報の保存を依頼できる「Credential Manager API」を定義し、その要件の多くに対応することを目的としています。

注: ここで定義するAPIは意図的に小さくシンプルです。認証自体を提供するものではなく、既存ユーザーエージェントが実装する認証情報管理機能へのインターフェースのみに限定しています。この機能は、ベンダーや著者の大きな負担なしに今すぐ役立つものです。もちろん、今後さらに多くのことが可能です。今後の課題は§ 9 今後の課題をご覧ください。

1.1. ユースケース

現代のユーザーエージェントは、ウェブサイトへのサインイン時にパスワードを保存できる機能や、ユーザーが再訪した際にサインインフォームへ自動または半自動でパスワードを入力する機能を備えています。ウェブサイト側から見ると、この動作は完全に不可視です:パスワードが保存されたことも、フォームに入力されたこともサイトは知りません。これは良い面も悪い面もあります。一方では、ユーザーエージェントのパスワードマネージャーはサイトの協力がなくても機能し、ユーザーにとって有益です。もう一方では、パスワードマネージャーの動作は、サインインフォームやパスワード変更フォームの検出などを目的とした脆弱で独自のヒューリスティックの寄せ集めになっています。

現状の課題として、特に以下の点が挙げられます:

2. コアAPI

開発者視点では、認証情報とは、特定の操作に対して認証判断を行うためのオブジェクトです。本セクションでは、Credential インターフェースをベースクラスとして定義します。これは本仕様や他の仕様書で定義される認証情報の基盤となり、navigator.credentials.* にぶら下がるAPI群から取得できます。

各種認証情報タイプは、それぞれJavaScript上で、継承によって、直接的または間接的にCredential インターフェースを基盤としています。本仕様書では、PasswordCredentialFederatedCredential の2つを定義しています。その他、例えば[WEBAUTHN]では他の認証情報タイプが定義されています。

認証情報が特定のオリジン有効であるとは、そのオリジンで認証として受理されることを指します。認証情報がある時点で有効であっても、UAは同じ認証情報が将来的にも有効だと仮定できない理由がいくつかあります:

  1. パスワード認証情報は、アカウント保有者がパスワードを変更した場合、有効でなくなる可能性があります。

  2. SMSで受け取ったトークンで作成された認証情報は、1回限りの利用のみ有効な場合が多いです。

使い捨て認証情報は、認証情報ソースによって生成されます。これは秘密鍵、フェデレーテッドアカウントへのアクセス、特定の電話番号でSMS受信できる能力などであり、JavaScriptで直接扱うことはできず、本仕様でも明示的に表現されません。モデルを統一するため、パスワード自体も認証情報ソースと見なし、これをコピーしてパスワード認証情報を作成します。

UAは、有効な認証情報が再度有効であるとは限らない、あるいは有効な認証情報を生成した認証情報ソースが将来も有効な認証情報を生成できるとは限らないものの、後者の方が可能性として高いです。過去に有効だった認証情報をstore() で記録すれば、UAは今後ユーザーに提示する際、より有効な認証情報ソースを提供できる可能性が高まります。

2.1. インフラストラクチャ

ユーザーエージェントは、ベンダー固有かつ不透明なストレージメカニズムである認証情報ストアを内部的に必ず提供しなければなりません。これは、どの認証情報有効だったかを記録します。以下の認証情報アクセスおよび永続化機能を備えています:

  1. 認証情報の保存(後で取得可能)。認証情報を受け取り、認証情報ストアに登録します。

  2. 認証情報リストの取得。任意のフィルターを受け取り、該当する認証情報セットを返します。

  3. 認証情報の変更認証情報を受け取り、既存の認証情報の状態を認証情報ストア内で上書きします。

さらに、認証情報ストアは、サイレントアクセス防止フラグオリジンごとに管理すべきです(特に指定がない限りtrueに設定)。オリジンのフラグがtrueなら、そのオリジンはユーザー操作が必要となります。

注: ユーザー操作の重要性は§ 5 ユーザーメディエーションで詳述されています。

注: 認証情報ストアは本仕様のAPI実装におけるユーザーエージェントの内部実装詳細であり、ウェブに直接公開されません。特定の認証情報タイプをサポートするため、他の文書でさらに機能が指定される場合があります。

本仕様はアルゴリズムや記述に用いる基盤概念としてInfra現行標準に依存しています [INFRA]

環境設定オブジェクトは、関連付けられたアクティブ認証情報タイプ(初期状態は空の集合)を持ちます。

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

2.1.1.1. 祖先も同一オリジンであること

環境設定オブジェクトsettings)が祖先も同一オリジンであるかどうかは、以下のアルゴリズムがtrueを返す場合です:

  1. settings関連グローバルオブジェクト関連付けられたDocumentがなければ、 falseを返す。

  2. documentsettings関連グローバルオブジェクト関連付けられたDocumentとする。

  3. documentブラウジングコンテキストがなければ、falseを返す。

  4. originsettingsオリジンとする。

  5. navigabledocumentノードナビゲーブルとする。

  6. navigableが非nullのを持つ間:

    1. navigablenavigableにする。

    2. navigableアクティブドキュメントオリジンorigin同一オリジンでなければ、 falseを返す。

  7. trueを返す。

2.1.2. 認証情報タイプレジストリ

このレジストリは認証情報タイプ(例:[[type]]値)を、指定された認証情報タイプに関連する様々な値へマッピングします。例えば、オプションメンバー識別子(正式には辞書メンバー識別子)は、CredentialCreationOptionsCredentialRequestOptions(すなわち「オプション辞書」)で仕様ごとに使われます。

注: このレジストリは関連する認証情報インターフェースオブジェクトアルゴリズムで利用されます。

認証情報タイプ
(アルファベット順)
オプションメンバー識別子 適切なインターフェースオブジェクト 取得パーミッションポリシー 作成パーミッションポリシー 仕様 申請者連絡先
digital-credential digital DigitalCredential digital-credentials-get null [DIGITAL-CREDENTIALS] WICG
federated federated FederatedCredential null null 本仕様:§ 4 フェデレーテッド認証情報 W3C
identity identity IdentityCredential identity-credentials-get null [FEDCM] W3C
otp otp OTPCredential otp-credentials null [WEB-OTP] WICG
password password PasswordCredential null null 本仕様:§ 3 パスワード認証情報 W3C
public-key publicKey PublicKeyCredential publickey-credentials-get publickey-credentials-create [WEBAUTHN] W3C
2.1.2.1. 登録エントリ要件および更新プロセス

このレジストリの更新は、認証情報タイプのレジストリエントリの追加・変更・削除です。誰でもwebappsec-credential-managementリポジトリへのプルリクエストで更新を申請できます。 Webアプリケーションセキュリティ作業部会が次回会議の議題に載せ申請者に通知します。 審議と決定はW3C Webアプリケーションセキュリティ作業部会の合意によります。 議長が申請者に結果を通知し、レジストリを更新します。

2.2. Credentialインターフェース

[Exposed=Window, SecureContext]
interface Credential {
  readonly attribute USVString id;
  readonly attribute DOMString type;
  static Promise<boolean> isConditionalMediationAvailable();
  static Promise<undefined> willRequestConditionalCreation();
};
id, USVString, 読み取り専用

認証情報の識別子です。識別子の要件は各認証情報タイプごとに異なります。例えば、ユーザー名/パスワードの組み合わせの場合はユーザー名を表すことがあります。

type, DOMString, 読み取り専用

この属性のgetterはオブジェクトのインターフェースオブジェクト[[type]]スロットの値を返します。これはこのオブジェクトが表す認証情報タイプを指定します。

isConditionalMediationAvailable()

ユーザーエージェントがクレデンシャル要求の仲介に対してconditional方式をサポートしている場合に限り、true解決されるPromiseを返します。そうでなければfalseで解決されます。この判定はクレデンシャルタイプごとに行われます。

CredentialisConditionalMediationAvailable()のデフォルト実装:

  1. resolveされたpromisefalseを返す。

条件付きメディエーションをサポートする認証情報タイプの仕様は、この関数をtrueresolveするよう明示的にオーバーライドする必要があります。

注: この関数が存在しなければ、conditional メディエーションは認証情報タイプでサポートされません。

willRequestConditionalCreation()

ユーザーエージェントがconditional アプローチによる認証情報生成のメディエーションで認証情報を生成する意図を登録した後にresolveされるPromiseを返します。

CredentialwillRequestConditionalCreation()のデフォルト実装:

  1. resolveされたpromiseundefinedを返す。

注: このメソッドが存在しなければ、conditional メディエーションによる認証情報生成は認証情報タイプでサポートされません。

[[type]]

Credentialインターフェースオブジェクトには[[type]]という内部スロットがあり、 これは認証情報タイプを示す文字列です。特に指定がない限り値は空文字列です。§ 2.1.2 認証情報タイプレジストリ認証情報タイプ一覧を参照できます。

注: [[type]] スロットの値は特定のインターフェースを実装するすべての認証情報で同じなので、開発者はobj.typeの返す文字列が そのCredentialの種別を明確に判別できることを信頼できます。

[[discovery]]

Credentialインターフェースオブジェクトには[[discovery]]という内部スロットがあり、 ユーザーエージェントが指定型の認証情報を収集する仕組みを表します。値は "credential store" または "remote"です。前者は利用可能な認証情報すべてがユーザーエージェントの認証情報ストアに保存されていることを意味し、 後者は外部デバイスやサービスとのやり取りによって認証情報ストアに明示的に表現されていない認証情報も発見できることを意味します。

TobieやDominicとインターフェースオブジェクトについて相談してください。ここや§ 2.5.1 認証情報の要求など、用語が正しいか不明です。インターフェースプロトタイプオブジェクトかもしれません?

一部のCredential オブジェクトはオリジンに束縛される型です。これらは[[origin]]という内部スロットを持ち、オリジンを格納します。これは当該Credential有効となり得るオリジンです。

2.2.1. Credentialの内部メソッド

Credentialインターフェースオブジェクトは、認証情報オブジェクトの取得・保存を補助するいくつかの内部メソッドを備えています。これらのデフォルトは本節で示す「no-op」です。

特に指定がない限り、Credentialを継承するインターフェースごとに作成されるインターフェースオブジェクトは、少なくとも1つの内部メソッドの実装を提供し、該当する認証情報タイプに合わせてCredentialのデフォルト実装をオーバーライドしなければなりません。例:§ 3.2 PasswordCredentialインターフェース§ 4.1 FederatedCredentialインターフェース[WEBAUTHN]

2.2.1.1. [[CollectFromCredentialStore]]内部メソッド
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)originCredentialRequestOptions、 呼び出し元の環境設定オブジェクト祖先も同一オリジンである場合にtrueとなるboolean値を受け取ります。 このアルゴリズムは、ユーザーエージェントの認証情報ストアから、指定したオプションに一致するCredentialオブジェクトの集合を返します。一致するCredentialがなければ、空集合を返します。

Credential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)のデフォルト実装:

  1. 空集合を返す。

2.2.1.2. [[DiscoverFromExternalSource]]内部メソッド
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)並行してoriginCredentialRequestOptions、 呼び出し元の環境設定オブジェクト祖先も同一オリジンである場合にtrueとなるboolean値を受け取ります。 オプションに応じて返せる場合はCredentialを返し、 利用可能な認証情報がなければnull、発見に失敗すれば(例:オプション不正の場合はTypeError)エラーを投げます。 単回利用や有効期間限定の場合は、このメソッドが認証情報ソースを使って新たに認証情報を生成します。

Credential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)のデフォルト実装:

  1. nullを返す。

2.2.1.3. [[Store]]内部メソッド
[[Store]](credential, sameOriginWithAncestors)並行してCredential、 呼び出し元の環境設定オブジェクト祖先も同一オリジンである場合にtrueとなるboolean値を受け取ります。 このアルゴリズムは、Credential認証情報ストアに永続化したら終了します。

Credential[[Store]](credential, sameOriginWithAncestors)のデフォルト実装:

  1. NotSupportedErrorを投げる。

2.2.1.4. [[Create]]内部メソッド
[[Create]](origin, options, sameOriginWithAncestors)並行してoriginCredentialCreationOptions、 呼び出し元の環境設定オブジェクト祖先も同一オリジンである場合にtrueとなるboolean値を受け取ります。 アルゴリズムは以下のいずれかを行います:

認証情報を作成する場合は、グローバルオブジェクトを受け取り、Credentialを継承するインターフェースオブジェクトを返すアルゴリズムを返します。このアルゴリズムはタスクから呼び出されなければなりません。

注: このアルゴリズムの手順は各認証情報タイプごとに定義されます。

Credential[[Create]](origin, options, sameOriginWithAncestors)のデフォルト実装:

  1. nullを返す。

2.2.2. CredentialUserDataミックスイン

一部のCredentialオブジェクトは、認証情報選択画面でユーザーに分かりやすい名称やアイコンを表示するためのデータを持ちます:

[SecureContext]
interface mixin CredentialUserData {
  readonly attribute USVString name;
  readonly attribute USVString iconURL;
};
name, USVString, 読み取り専用

認証情報に関連する名称で、認証情報選択画面で表示する人間が理解できる公開名を意図します。

iconURL, USVString, 読み取り専用

認証情報用アイコン画像のURLで、認証情報選択画面で表示されることを意図しています。このURLは潜在的に信頼できるURLでなければなりません。

2.3. navigator.credentials

開発者はCredentialを取得し、ユーザーエージェントの認証情報ストアとやり取りするために、CredentialsContainerインターフェースのメソッドを利用します。これはNavigatorオブジェクトのnavigator.credentialsとして提供されます。

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute CredentialsContainer credentials;
};

credentials属性は、アクティブドキュメントブラウジングコンテキストに関連付けられたCredentialsContainerを必ず返さなければなりません。

注: § 6.3 安全でないサイトで述べている通り、認証情報管理APIはセキュアコンテキストでのみ公開されます。

[Exposed=Window, SecureContext]
interface CredentialsContainer {
  Promise<Credential?> get(optional CredentialRequestOptions options = {});
  Promise<undefined> store(Credential credential);
  Promise<Credential?> create(optional CredentialCreationOptions options = {});
  Promise<undefined> preventSilentAccess();
};

dictionary CredentialData {
  required USVString id;
};
get(options)

get()が呼び出されると、ユーザーエージェントは 認証情報の要求optionsに対して実行した結果を返さなければなりません。

CredentialsContainer.get(options)メソッドの引数。
パラメーター Nullable Optional 説明
options CredentialRequestOptions リクエスト範囲を管理するプロパティセット。
store(credential)

store()が呼び出されると、ユーザーエージェントは 認証情報の保存credentialに対して実行した結果を返さなければなりません。

CredentialsContainer.store(credential)メソッドの引数。
パラメーター Nullable Optional 説明
credential Credential 保存する認証情報。
create(options)

create()が呼び出されると、ユーザーエージェントは 認証情報の作成optionsに対して実行した結果を返さなければなりません。

CredentialsContainer.create(options)メソッドの引数。
パラメーター Nullable Optional 説明
options CredentialCreationOptions Credential作成に利用するオプション。
preventSilentAccess()

preventSilentAccess()が呼び出されると、 ユーザーエージェントはサイレントアクセス防止現在の設定オブジェクトに対して実行した結果を返さなければなりません。

注: これはオリジン側がユーザーのサインアウトを示すシグナルです。つまり、「サインアウト」ボタンのクリック後、サイトがユーザーのセッション情報を更新し、navigator.credentials.preventSilentAccess()を呼び出します。これによりサイレントアクセス防止フラグが設定され、次回ユーザーが訪問した際に認証情報が自動で返されなくなります。

注: この関数は以前requireUserMediation()と呼ばれていましたが、非推奨と考えてください。

Navigator オブジェクト(navigator)が作成される際、ユーザーエージェントはnavigator関連Realmを用いて新しいCredentialsContainerオブジェクトを作成し、 navigatorに関連付けなければなりません。

2.3.1. CredentialRequestOptions辞書

get()Credentialを取得するには、 呼び出し側がCredentialRequestOptionsオブジェクトでいくつかのパラメーターを指定します。

注: CredentialRequestOptions辞書は拡張ポイントです。新しい認証情報タイプで追加オプションが必要になった場合、その辞書型を拡張してリクエストに渡すことができます。§ 8.2 拡張ポイント参照。

dictionary CredentialRequestOptions {
  CredentialMediationRequirement mediation = "optional";
  AbortSignal signal;
};
mediation, CredentialMediationRequirement、デフォルト値は"optional"

このプロパティは認証情報リクエストのメディエーション要件を指定します。各enum値の意味は下記CredentialMediationRequirementで説明されています。 処理詳細は§ 2.5.1 認証情報の要求を参照してください。

signal, AbortSignal

このプロパティは開発者が進行中のget()操作を中断するために利用します。 中断された操作は通常通り完了する場合もあり(一般的に中断が操作完了後に受信された場合)、また中断理由でrejectされる場合もあります。

以前の仕様ではboolean型unmediatedメンバーが定義されていました。これをtrueに設定すると、mediation が "silent"、 falseに設定すると mediation が"optional"となる効果がありました。

unmediatedは非推奨と考え、新しいコードではmediationを利用してください。

CredentialCreationOptionsまたはCredentialRequestOptionsoptions)に対する関連する認証情報インターフェースオブジェクトは、以下の手順で収集される インターフェースオブジェクトの集合です:

注: このアルゴリズムは認証情報タイプレジストリを利用します。

  1. settings現在の設定オブジェクトとする。

  2. relevant interface objects集合とする。

  3. optionsの各optionKeyoptionValueについて:

    1. credentialInterfaceObjectを、settingsグローバルオブジェクト上で オプションメンバー識別子optionKeyである適切なインターフェースオブジェクトとする。

    2. Assert: credentialInterfaceObject[[type]]スロットは、 オプションメンバー識別子optionKeyである 認証情報タイプに等しい。

    3. credentialInterfaceObjectrelevant interface objectsに追加する。

  4. relevant interface objectsを返す。

CredentialRequestOptionsoptions)が事前に一致可能(matchable a prioriかどうかは、以下のステップがtrueを返す場合です:
  1. options関連する認証情報インターフェースオブジェクトの各interfaceについて:

    1. interface[[discovery]]スロットの値が "credential store" でなければfalseを返す。

  2. trueを返す。

注: get(options) を実行する際、ユーザー仲介なしでクレデンシャルを返すのは、 指定されたCredentialRequestOptions事前にマッチ可能(a prioriな場合のみです。OAuthトークンやセキュリティキー認証器など、外部サービスからの発見が必要となるクレデンシャルタイプがリクエストされた場合は、発見処理を導くため(フェデレーテッドアイデンティティプロバイダー、BTLEデバイス等の選択)、ユーザー仲介が必須となります。

2.3.2. メディエーション要件

get(options)create(options) のリクエスト時、開発者はCredentialMediationRequirement列挙型の値を選択することで、個別にユーザー操作の要件を設定できます。

注: § 5 ユーザーメディエーションで、この概念の詳細や、ユーザーエージェントが特定のオリジンに対する個々のリクエストをどのように扱うかについて説明しています。

enum CredentialMediationRequirement {
  "silent",
  "optional",
  "conditional",
  "required"
};
silent

この操作ではユーザー操作が抑制されます。ユーザー操作なしで処理できる場合はそのまま実行されます。ユーザー操作が必要な場合は、ユーザーを介さずにnullを返します。

注: 主な用途は「このサイトにサインインしたままにする」シナリオです。自動サインインが可能な場合は認証情報を静かに取得し、ユーザーが能動的にサインインを選択するまでサインインプロンプトで邪魔しないようにします。

optional

ユーザー操作なしで認証情報を渡せる場合は渡します。ユーザー操作が必要な場合は、ユーザーエージェントがユーザーに判断を委ねます。

注: これはget()のデフォルト動作です。ユーザーが「サインイン」ボタンを押した直後など、サインイン操作を期待している場合に最適です。必要なら認証情報選択画面が出ても、ユーザーは戸惑いません。

conditional

get()の場合、発見された認証情報は非モーダルダイアログでユーザーに表示され、認証情報要求元のオリジンも示されます。ユーザーがダイアログ外で操作すると、Promiseはresolve/rejectせず、ユーザー向けエラーも発生しません。認証情報を選択すると、その認証情報が返されます。サイレントアクセス防止フラグは実際の値にかかわらずtrueとして扱われます:conditional動作では、該当認証情報が見つかった場合は必ずユーザー操作が発生します。

認証情報が見つからない場合、ユーザーエージェントは認証情報タイプに応じて何らかのアクション(例:デバイス挿入)を促すことができます。いずれにせよ、get()は即座にnullでresolveして、認証情報がないことをサイトに知らせてはなりません。

Webサイトは、参照するすべての認証情報インターフェースisConditionalMediationAvailable()trueでresolveするようオーバーライドしている場合のみconditionalget()に渡せます。

create()の場合、ユーザーが以前認証情報の生成に同意していて、直近にユーザーエージェントが認証を媒介したことが分かっていれば、追加のモーダル操作なしでresolveできます。最近ユーザー認証を媒介していないか、認証情報生成の同意がなければ"NotAllowedError"DOMExceptionを投げなければなりません。

required

たとえオリジンのサイレントアクセス防止フラグが未設定でも、ユーザー操作なしで認証情報は渡されません。

注: これは再認証ユーザー切り替えのケースに適しています。この要件は特定の操作にのみ適用され、オリジンのサイレントアクセス防止フラグには影響しません。フラグを設定するにはpreventSilentAccess()を呼び出してください。

2.3.2.1.
MegaCorp, Inc.は可能な限りシームレスにユーザーをサインインさせたいと考えています。未サインインユーザーに対して、ランディングページの読み込み時など都合の良いタイミングでget()を呼び出し、mediationプロパティに "silent"をセットして渡すことでこれを実現できます。 これにより、§ 5.2 ユーザーメディエーションの要求で説明されているように、ユーザー操作不要に同意したユーザーは自動サインインされ、同意していない場合は不意な認証情報選択画面で戸惑うことがありません。
window.addEventListener('load', async () => {
  const credentials = await navigator.credentials.get({
    ...,
    mediation: 'silent'
  });
  if (credentials) {
    // 認証情報でユーザーをサインイン!
  }
});
ユーザーが「サインイン」ボタンをクリックしたとき、MegaCorp, Inc.はできるだけスムーズな体験を提供したいと考えています。ユーザー操作不要に同意していて、ユーザーエージェントが認証情報を一意に選択できればそのままOK。できなければ認証情報選択画面を表示します。
document.querySelector('#sign-in').addEventListener('click', async () => {
  const credentials = await navigator.credentials.get({
    ...,
    mediation: 'optional'
  });
  if (credentials) {
    // 認証情報でユーザーをサインイン!
  }
});

注: mediation プロパティ自体を省略しても、デフォルトは"optional"です。

MegaCorp, Inc.は重要な操作を守るため、ユーザーに再認証を要求したいと考えています。ユーザーがユーザー操作不要に同意していても、get()mediationプロパティを "required"にセットすれば、 ユーザーエージェントが必ずユーザー操作を介するようにできます。

注: ブラウザや認証情報タイプのセキュリティモデルによっては、認証情報をサイトに渡す前に、マスターパスワード入力や指紋認証などが要求される場合があります。

document.querySelector('#important-form').addEventListener('submit', async () => {
  const credentials = await navigator.credentials.get({
    ...,
    mediation: 'required'
  });
  if (credentials) {
    // |credentials|でアクセス可能か確認し、不正なら送信をキャンセル
  } else {
    e.preventDefault();
  }
});
MegaCorp, Inc.は複数ユーザーアカウントへの同時サインインをサポートしたいと考えています。ユーザーが別の認証情報を選択できるようにするため、get()mediationプロパティを "required"にセットし、 「アカウント追加」ボタンのクリック時に認証情報が自動で返らないようにできます:
document.querySelector('#switch-button').addEventListener('click', e => {
  var c = await navigator.credentials.get({
    ...,
    mediation: 'required'
  });
  if (c) {
    // |c|でユーザーをサインイン
  }
});

2.4. CredentialCreationOptions辞書

create()Credentialを作成するには、 呼び出し側がCredentialCreationOptionsオブジェクトでいくつかのパラメーターを指定します。

注: CredentialCreationOptions辞書は拡張ポイントです。新しい認証情報タイプが導入される際には、この辞書に追加され、作成メソッドに渡せます。§ 8.2 拡張ポイント、本仕様で導入されている拡張(§ 3.2 PasswordCredentialインターフェース§ 4.1 FederatedCredentialインターフェース)も参照してください。

dictionary CredentialCreationOptions {
  CredentialMediationRequirement mediation = "optional";
  AbortSignal signal;
};
signal, AbortSignal

このプロパティは開発者が進行中のcreate()操作を中断するために利用します。中断された操作は通常通り完了する場合もあり(一般的に中断が操作完了後に受信された場合)、また中断理由でrejectされる場合もあります。

2.5. アルゴリズム

2.5.1. Credentialの要求

Credentialの要求アルゴリズムはCredentialRequestOptionsoptions)を受け取り、一意に取得できる場合はCredentialでresolve、そうでなければnullでresolveするPromiseを返します。

  1. settings現在の設定オブジェクトとする。

  2. Assert: settingsセキュアコンテキストである。

  3. documentsettings関連グローバルオブジェクト関連付けられたDocumentとする。

  4. document完全にアクティブでなければ、"InvalidStateError" DOMExceptionpromiseをrejectして返す。

  5. options.signal中断済みなら、 options.signal中断理由promiseをrejectして返す。

  6. interfacesoptions関連する認証情報インターフェースオブジェクトとする。

  7. interfacesなら、 "NotSupportedError" DOMExceptionpromiseをrejectして返す。

  8. interfacesの各interfaceについて:

    1. options.mediationconditionalで、 interfaceconditionalユーザー操作をサポートしないなら、"TypeError" DOMExceptionpromiseをrejectして返す。

    2. settingsアクティブ認証情報タイプinterface[[type]]含んでいれば、 "NotAllowedError" DOMExceptionpromiseをrejectして返す。

    3. settingsアクティブ認証情報タイプinterface[[type]]を追加する。

  9. originsettingsoriginとする。

  10. sameOriginWithAncestorsを、settings祖先も同一オリジンならtrue、それ以外はfalseとする。

  11. options関連する認証情報インターフェースオブジェクトの各interfaceについて:

    1. permissioninterface[[type]]取得パーミッションポリシーとする。

    2. permissionがnullなら、次へ。

    3. documentpermission利用許可がないなら、"NotAllowedError" DOMExceptionpromiseをrejectして返す。

  12. p新しいpromiseとする。

  13. 以下の手順を並行して実行:

    1. credentials認証情報ストアからCredentialを収集originoptionssameOriginWithAncestors)の結果とする。

    2. credentials例外なら、pをrejectして返す。

    3. 以下すべてがtrueなら、pcredentials[0]でresolveし、残り手順をスキップ:

      1. credentialsサイズが1

      2. originユーザー操作不要

      3. options事前に一致可能

      4. options.mediation が "required"でない

      5. options.mediation が "conditional"でない

      このモデルは誤っているかもしれません。WebAuthn型認証情報でも、ユーザー名/パスワードを使うユーザーには選択画面を表示しないままサインインできるようにしたい。

    4. options.mediation が "silent"なら、pをnullでresolveし、残り手順をスキップ。

    5. resultユーザーにCredential選択を依頼optionscredentials)の結果とする。

    6. resultインターフェースオブジェクトなら:

      1. resultを、result[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)originoptionssameOriginWithAncestors)の結果にする。

        例外が発生した場合:

        1. 発生した例外をeとする。

        2. globalDOM操作タスクソースタスクをキューし、以下を実行:

          1. pをeでrejectする。

        3. 以降の手順を終了。

    7. Assert: resultnullまたはCredential

    8. resultCredentialなら、pをresultでresolveする。

    9. resultnullかつoptions.mediationconditionalでない場合、pをresultでresolveする。

      注: options.mediationconditionalであり、nullな認証情報が発見された場合、promise pはresolveされません。

  14. pがsettleしたら反応:

    1. interfacesの各interfaceについて:

      1. interface[[type]]settingsアクティブ認証情報タイプから削除する。

  15. pを返す。

2.5.2. 認証情報ストアからCredentialを収集

originorigin)、 CredentialRequestOptionsoptions)、および呼び出しコンテキストが祖先も同一オリジンsameOriginWithAncestors)の場合のみtrueとなるboolean値が与えられたとき、ユーザーエージェントは認証情報ストアからCredentialを収集できる。 これは、ユーザーエージェントがローカルに保存しているoptionsのフィルターに一致するCredentialオブジェクトの集合を返す。該当するCredentialオブジェクトがなければ、空集合を返す:

  1. possible matchesを空集合とする。

  2. options関連する認証情報インターフェースオブジェクトの各interfaceについて:

    1. rinterface[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) 内部メソッド(引数はoriginoptionssameOriginWithAncestors)の実行結果とする。例外が発生した場合は、その例外を再スローする。

    2. Assert: rインターフェースオブジェクトのリストである。

    3. rの各cについて:

      1. possible matchescを追加する。

  3. possible matchesを返す。

2.5.3. Credentialの保存

Credentialの保存アルゴリズムは Credentialcredential)を受け取り、オブジェクトが認証情報ストアに永続化されるとresolveする Promise を返す。

  1. settings現在の設定オブジェクトとする。

  2. Assert: settingsセキュアコンテキストである。

  3. settings関連グローバルオブジェクト関連付けられたDocument完全にアクティブでなければ、 "InvalidStateError" DOMExceptionpromiseをrejectして返す。

  4. 現在の設定オブジェクト祖先も同一オリジンならtrue、それ以外はfalseとしたsameOriginWithAncestorsを定める。

  5. p新しいpromiseとする。

  6. settingsアクティブ認証情報タイプcredential[[type]]含んでいれば、 "NotAllowedError" DOMExceptionpromiseをrejectして返す。

  7. settingsアクティブ認証情報タイプcredential[[type]]を追加する。

  8. 以下の手順を並行して実行:

    1. credentialインターフェースオブジェクト[[Store]](credential, sameOriginWithAncestors) 内部メソッド(引数はcredentialsameOriginWithAncestors)を実行する。

      例外が発生した場合:

      1. 発生した例外をeとする。

      2. globalDOM操作タスクソースタスクをキューし、以下を実行:

        1. pをeでrejectする。

      例外が発生しない場合は、pをundefinedでresolveする。

  9. pがsettleしたら反応

    1. credential[[type]]settingsアクティブ認証情報タイプから削除する。

  10. pを返す。

2.5.4. Credentialの作成

Credentialの作成アルゴリズムは CredentialCreationOptions (options)を受け取り、指定されたオプションで作成できる場合はCredentialでresolveし、作成できない場合はnullでresolveする Promise を返します。例外的な状況では、Promiseは適切な例外でrejectされる場合があります。

  1. settings現在の設定オブジェクトとする。

  2. Assert: settingsセキュアコンテキストである。

  3. globalsettingsグローバルオブジェクトとする。

  4. document関連グローバルオブジェクト関連付けられたDocumentとする。

  5. document完全にアクティブでなければ、"InvalidStateError" DOMExceptionpromiseをrejectして返す。

  6. 現在の設定オブジェクト祖先も同一オリジンならtrue、それ以外はfalseとしたsameOriginWithAncestorsを定める。

  7. interfacesoptions関連する認証情報インターフェースオブジェクト集合とする。

  8. 次のいずれかがtrueならNotSupportedErrorpromiseをrejectして返す:

    1. global関連付けられたDocumentがない。

    2. interfacesサイズが1より大きい。

      注: 今後この制限を緩和し、ユーザーエージェントが複数の認証情報タイプから選択できる「サインアップ」ユースケースをサポートする可能性はありますが、現時点では辞書は1エントリに制限されています。

  9. interfacesの各interfaceについて:

    1. permissioninterface[[type]]作成パーミッションポリシーとする。

    2. permissionがnullなら次へ。

    3. documentpermission利用許可がない場合、"NotAllowedError" DOMExceptionpromiseをrejectして返す。

  10. options.signal中断済みなら、 options.signal中断理由promiseをrejectして返す。

  11. typeinterfaces[0]の[[type]]とする。

  12. settingsアクティブ認証情報タイプtype含んでいれば、 "NotAllowedError" DOMExceptionpromiseをrejectして返す。

  13. settingsアクティブ認証情報タイプtypeを追加する。

  14. originsettingsoriginとする。

  15. p新しいpromiseとする。

  16. 以下の手順を並行して実行:

    1. rinterfaces[0]の[[Create]](origin, options, sameOriginWithAncestors)内部メソッド(引数はoriginoptionssameOriginWithAncestors)の実行結果とする。

      例外が発生した場合:

      1. 発生した例外をeとする。

      2. globalDOM操作タスクソースタスクをキューし、以下を実行:

        1. pをeでrejectする。

      3. 以降の手順を終了。

    2. rCredentialまたはnullなら、pをrでresolveし、以降の手順を終了。

    3. Assert: rは(§ 2.2.1.4 [[Create]]内部メソッドで定義される)アルゴリズムである。

    4. globalDOM操作タスクソースタスクをキューし、以下を実行:

      1. pをglobalでpromise-callingしたrの結果でresolveする。

  17. pがsettleしたら反応

    1. settingsアクティブ認証情報タイプからtypeを削除する。

  18. pを返す。

2.5.5. サイレントアクセスの防止

サイレントアクセスの防止アルゴリズムは環境設定オブジェクトsettings)を受け取り、認証情報ストアサイレントアクセス防止フラグが永続化されるとresolveするPromiseを返します。

  1. originsettingsoriginとする。

  2. settings関連グローバルオブジェクト関連付けられたDocument完全にアクティブでなければ、 "InvalidStateError" DOMExceptionpromiseをrejectして返す。

  3. p新しいpromiseとする。

  4. 以下の手順を並行して実行:

    1. originサイレントアクセス防止フラグ認証情報ストアに設定する。

    2. pをundefinedでresolveする。

  5. pを返す。

3. パスワード認証情報

良いか悪いかは別として、多くのウェブサイトは認証手段としてユーザー名/パスワードの組み合わせに依存しています。 PasswordCredential インターフェースは、このユースケースを実現するための認証情報であり、ユーザー名とパスワード両方を保存し、 認証情報選択画面でユーザーが正しいアカウントを選びやすくするメタデータも保持します。

3.1.

3.1.1. パスワードによるサインイン

MegaCorp社はパスワード認証をサポートしており、navigator.credentials.get() を使って ユーザーの認証情報ストアからユーザー名/パスワードの組み合わせを取得できます:
navigator.credentials
  .get({ 'password': true })
  .then(credential => {
    if (!credential) {
      // ユーザーがこのサイト用の認証情報を持っていない、または
      // 共有を拒否した場合。ここで通常のログインフォームへのフォールバック処理を実装。
      return;
    }
    if (credential.type == 'password') {
      var form = new FormData();
      form.append('username_field', credential.id);
      form.append('password_field', credential.password);
      var opt = {
        method: 'POST',
        body: form,
        credentials: 'include'  // クッキー送信
      };
      fetch('https://example.com/loginEndpoint', opt)
        .then(function (response) {
          if (/* |response| がログイン成功を示す場合 */) {
            // 認証情報が有効だったことを記録(下記注参照)
            navigator.credentials.store(credential);
            // サインイン成功を通知して、サインイン後の処理を実行!
            // location.href = '/signed-in-experience' なども可能
          } else {
            // 通常のログインフォームへのフォールバック処理
          }
        });
    }
  });

また、ウェブサイトは認証情報データを form にコピーして、submit() を呼び出すこともできます:

navigator.credentials
  .get({ 'password': true })
  .then(credential => {
    if (!credential) {
      return; // 上記と同様...
    }
    if (credential.type === 'password') {
      document.querySelector('input[name=username_field]').value =
        credential.id;
      document.querySelector('input[name=password_field]').value =
        credential.password;
      document.getElementById('myform').submit();
    }
  });

前者の方法(fetch後にstore()を明示的に呼ぶ)が推奨されます。 form ベースの方法はフォーム送信に依存し、ブラウジングコンテキストが遷移するため、サインイン成功後に確実にstore()を呼ぶのが難しくなります。

注: ユーザーエージェントが提示する認証情報選択画面では、現在のオリジンに保存されていない認証情報も選択できる場合があります。例えば、https://m.example.comの認証情報が https://www.example.comで利用可能として表示されることがあります(§ 6.1 クロスドメイン認証情報アクセス参照)。 または、ユーザーが新しい認証情報を即時作成できる場合もあります。開発者は、store()を認証情報が利用されるたび(get()直後でも)呼ぶことで、未保存なら保存の機会が提示され、すでに保存済みならユーザーへのプロンプトも表示されません。

3.1.2. サインイン後の確認

サインイン成功後に新しい認証情報の保存をユーザーに提案するには、その認証情報をstore() に渡します。

ユーザーが fetch()でサインインエンドポイントに認証情報を送信した場合、レスポンスでサインイン成功を確認し、ユーザーエージェントに通知できます。例えば次のようなサインインフォームの場合:
<form action="https://example.com/login" method="POST" id="theForm">
  <label for="username">ユーザー名</label>
  <input type="text" id="username" name="username" autocomplete="username">
  <label for="password">パスワード</label>
  <input type="password" id="password" name="password" autocomplete="current-password">
  <input type="submit">
</form>

フォーム送信は次のようなハンドラで処理できます:

document.querySelector('#theForm').addEventListener('submit', e => {
    if (window.PasswordCredential) {
      e.preventDefault();

      // "submit"イベント発火元のPasswordCredentialを
      // HTMLFormElementから生成
      // "username"や"current-password"のautocomplete属性値を吸い上げる
      var c = new PasswordCredential(e.target);

      // フォームのaction URLに新しい認証情報オブジェクト(FormData)を送信。成功ならユーザーエージェントに通知してパスワード保存を提案:
      var opt = {
        method: 'POST',
        body: new FormData(e.target),
        credentials: 'include'  // クッキー送信
      };
      fetch(e.target.action, opt).then(r => {
        if (/* |r| が"成功した" Response */)
          navigator.credentials.store(c);
      });
    }
});

3.1.3. パスワード変更

この保存機構は「パスワード変更」にもそのまま利用できます。ユーザーが認証情報を変更した場合、ウェブサイトは新しい認証情報でサインイン成功を通知できます。ユーザーエージェントは保存済み認証情報を更新します:

MegaCorp社は、ユーザーがパスワード変更データを非同期POSTできるようにしています。成功後は新しい情報でstore()を呼ぶことで認証情報更新可能です。

パスワード変更フォーム例:

<form action="https://example.com/changePassword" method="POST" id="theForm">
  <input type="hidden" name="username" autocomplete="username" value="user">
  <label for="password">新しいパスワード</label>
  <input type="password" id="password" name="password" autocomplete="new-password">
  <input type="submit">
</form>

フォーム送信は次のように処理できます:

document.querySelector('#theForm').addEventListener('submit', e => {
  if (window.PasswordCredential) {
    e.preventDefault();

    // "submit"イベント発火元のPasswordCredentialを
    // HTMLFormElementから生成
    // "username"や"new-password"のautocomplete属性値を吸い上げる
    var c = new PasswordCredential(e.target);

    // フォームのaction URLに新しい認証情報オブジェクト(FormData)を送信。成功ならユーザーエージェントに通知してパスワード保存を提案:
    var opt = {
      method: 'POST',
      body: new FormData(e.target),
      credentials: 'include'  // クッキー送信
    };
    fetch(e.target.action, opt).then(r => {
      if (/* |r| が"成功した" Response */)
        navigator.credentials.store(c);
    });
  }
});

3.2. PasswordCredentialインターフェース

[Exposed=Window,
 SecureContext]
interface PasswordCredential : Credential {
  constructor(HTMLFormElement form);
  constructor(PasswordCredentialData data);
  readonly attribute USVString password;
};
PasswordCredential includes CredentialUserData;

partial dictionary CredentialRequestOptions {
  boolean password = false;
};
password, USVString, 読み取り専用

認証情報のパスワードを表します。

[[type]]

PasswordCredentialインターフェースオブジェクト[[type]]という内部スロットを持ち、その値は"password"です。

[[discovery]]

PasswordCredentialインターフェースオブジェクト[[discovery]]という内部スロットを持ち、その値は"credential store"です。

PasswordCredential(form)

このコンストラクターはHTMLFormElement (form)を受け取り、以下の手順を実行します:

  1. origin現在の設定オブジェクトoriginとする。

  2. rHTMLFormElementから PasswordCredentialを作成formorigin)の結果とする。

  3. r例外なら、その例外を投げる。それ以外はrを返す。

PasswordCredential(data)

このコンストラクターはPasswordCredentialData (data)を受け取り、以下の手順を実行します:

  1. rPasswordCredentialDataから PasswordCredentialを作成data)の結果とする。

  2. r例外なら、その例外を投げる。それ以外はrを返す。

PasswordCredential オブジェクトはPasswordCredentialData 辞書を明示的に渡すか、HTMLFormElement送信可能要素の内容に基づいて navigator.credentials.create() で作成できます。

dictionary PasswordCredentialData : CredentialData {
  USVString name;
  USVString iconURL;
  required USVString origin;
  required USVString password;
};

typedef (PasswordCredentialData or HTMLFormElement) PasswordCredentialInit;

partial dictionary CredentialCreationOptions {
  PasswordCredentialInit password;
};

PasswordCredential オブジェクトはオリジンに束縛されます

PasswordCredentialインターフェースオブジェクトCredential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) の実装を継承し、 [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)[[Create]](origin, options, sameOriginWithAncestors)[[Store]](credential, sameOriginWithAncestors) を独自実装します。

3.3. アルゴリズム

3.3.1. PasswordCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)

[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) は、originorigin)、CredentialRequestOptions (options)、 および呼び出しコンテキストが祖先も同一オリジン (sameOriginWithAncestors)の場合のみtrueとなるboolean値を受け取ります。 このアルゴリズムは認証情報ストアからCredentialオブジェクトの集合を返します。一致するCredentialがなければ空集合を返します。

sameOriginWithAncestorsがtrueでない場合、NotAllowedErrorを投げます。

  1. Assert: options["password"] 存在する

  2. sameOriginWithAncestorsがfalseなら、"NotAllowedError" DOMExceptionを投げる。

    注: この制限は§ 6.4 オリジン混同の懸念に対応しています。

  3. options["password"] がtrueでなければ空集合を返す。

  4. 認証情報ストアから取得によって 以下のフィルタに一致する認証情報を返す:

    1. 認証情報がPasswordCredentialである

    2. 認証情報の[[origin]]origin同一オリジンである

3.3.2. PasswordCredential[[Create]](origin, options, sameOriginWithAncestors)

[[Create]](origin, options, sameOriginWithAncestors) は、originorigin)、CredentialCreationOptions (options)、および呼び出しコンテキストが祖先も同一オリジンsameOriginWithAncestors)の場合のみtrueとなるboolean値を受け取ります。 このアルゴリズムは、作成できる場合はPasswordCredentialを、そうでなければnullを返します。CredentialCreationOptions 辞書は必ずpasswordメンバーを持ち、その値はHTMLFormElement またはPasswordCredentialData でなければなりません。 その値からPasswordCredentialを作成できない場合、このアルゴリズムはTypeError 例外を投げます。

  1. Assert: options["password"] 存在する、かつsameOriginWithAncestorsは未使用。

  2. options["password"] がHTMLFormElementなら、 HTMLFormElementから PasswordCredentialを作成options["password"]、origin)の結果を返す。 例外は再スローすること。

  3. options["password"] がPasswordCredentialDataなら、 PasswordCredentialDataから PasswordCredentialを作成options["password"])の結果を返す。 例外は再スローすること。

  4. TypeError 例外を投げる。

3.3.3. PasswordCredential[[Store]](credential, sameOriginWithAncestors)

[[Store]](credential, sameOriginWithAncestors)PasswordCredential (credential)と、呼び出しコンテキストが祖先も同一オリジンの場合のみtrueとなるboolean値を受け取ります。アルゴリズムはcredential認証情報ストアに永続化されるとundefinedを返します。

sameOriginWithAncestorsがtrueでない場合、NotAllowedErrorを返します。

  1. sameOriginWithAncestorsがfalseの場合、"NotAllowedError" DOMException を投げ、ユーザーエージェントの認証情報ストアは変更しない。

    注: この制限は§ 6.4 オリジン混同の懸念に対応しています。

  2. ユーザーエージェントの認証情報ストアに、PasswordCredential (stored) があり、そのid 属性がcredentialidで、 [[origin]] スロットがcredential[[origin]]同一オリジンなら:

    1. ユーザーが認証情報の更新を許可した場合(ユーザー操作定義時参照)、

      1. storedpasswordcredentialpasswordに設定する。

      2. storednamecredentialnameに設定する。

      3. storediconURLcredentialiconURLに設定する。

    それ以外の場合、ユーザーが認証情報保存を許可した場合(ユーザー操作定義時参照):

    1. 以下のプロパティを持つPasswordCredential認証情報ストアに保存する:

      id

      credentialid

      name

      credentialname

      iconURL

      credentialiconURL

      [[origin]]

      credential[[origin]]

      password

      credentialpassword

3.3.4. HTMLFormElementからPasswordCredentialを作成

HTMLFormElementから PasswordCredentialを作成するには、HTMLFormElementform)とオリジンorigin)を受け取り、以下の手順を実行します。

注: § 3.1.2 サインイン後の確認§ 3.1.3 パスワード変更が主な利用例です。

  1. dataを新しいPasswordCredentialData辞書とする。

  2. dataoriginメンバー値をorigin値に設定する。

  3. formDataFormDataコンストラクターでformから生成する。

  4. elements を、送信可能な要素のうち、form ownerform であるものを 木構造順で並べたリストとする。

  5. newPasswordObservedfalseとする。

  6. elementsの各fieldについて以下を実行:

    1. fieldautocomplete属性を持たない場合は以降をスキップ。

    2. namefieldname属性値とする。

    3. formDatahas()nameに対して実行し、結果がfalseなら以降をスキップ。

    4. fieldautocomplete値に1つ以上のautofill詳細トークンtokens)が含まれている場合:

      1. tokensの各tokenについて:

        1. tokenが以下のいずれか文字列(ASCII大文字小文字無視)と一致する場合は該当手順を実行:

          "new-password"

          datapassword メンバー値をformDataget()name取得結果に設定し、newPasswordObservedtrueにする。

          "current-password"

          newPasswordObservedfalseなら、datapasswordメンバー値をformDataget()name取得結果に設定。

          注: newPasswordObservedfalseか判定することでnew-passwordフィールドがcurrent-passwordより優先されます。

          "photo"

          dataiconURLメンバー値をformDataget()name取得結果に設定。

          "name"
          "nickname"

          datanameメンバー値をformDataget()name取得結果に設定。

          "username"

          dataidメンバー値をformDataget()name取得結果に設定。

  7. cPasswordCredentialDataからPasswordCredentialを作成data)の結果とする。例外発生時は再スロー。

  8. Assert: cPasswordCredentialである。

  9. cを返す。

3.3.5. PasswordCredentialDataからPasswordCredentialを作成

PasswordCredentialDataから PasswordCredentialを作成するには、PasswordCredentialDatadata)を受け取り、以下の手順を実行します。

  1. cを新しいPasswordCredentialオブジェクトとする。

  2. 以下いずれかが空文字列なら、TypeError 例外を投げる:

  3. cの各プロパティを以下のように設定:

    password

    datapassword

    id

    dataid

    iconURL

    dataiconURL

    name

    dataname

    [[origin]]

    dataorigin

  4. cを返す。

3.3.6. CredentialRequestOptionsによるPasswordCredential一致判定

CredentialRequestOptions (options)が与えられたとき、以下のアルゴリズムはMatchesPasswordCredentialget()リクエスト応答として利用可能)またはDoes Not Match(そうでない場合)を返します。

  1. optionspasswordメンバーがあり、値がtrueならMatchesを返す。

  2. Does Not Matchを返す。

4. フェデレーテッドクレデンシャル

4.1. FederatedCredential インターフェース

[Exposed=Window,
 SecureContext]
interface FederatedCredential : Credential {
  constructor(FederatedCredentialInit data);
  readonly attribute USVString provider;
  readonly attribute DOMString? protocol;
};
FederatedCredential includes CredentialUserData;

dictionary FederatedCredentialRequestOptions {
  sequence<USVString> providers;
  sequence<DOMString> protocols;
};

partial dictionary CredentialRequestOptions {
  FederatedCredentialRequestOptions federated;
};
provider, USVString, 読み取り専用

クレデンシャルのフェデレーテッドアイデンティティプロバイダー。詳細なフォーマットについては § 4.1.1 プロバイダーの識別 を参照してください。

protocol, DOMString, 読み取り専用、nullable

クレデンシャルのフェデレーテッドアイデンティティプロバイダーのプロトコル(例: "openidconnect")。 値が null の場合は、プロトコルは provider から推測できます。

[[type]]

FederatedCredential インターフェースオブジェクト[[type]] という名前の内部スロットを持ち、 値は "federated" です。

[[discovery]]

FederatedCredential インターフェースオブジェクト[[discovery]] という名前の内部スロットを持ち、 値は "credential store" です。

FederatedCredential(data)

このコンストラクターは FederatedCredentialInit (data) を受け取り、以下の手順を実行します:

  1. rFederatedCredentialInit から FederatedCredential を作成するdata に対して実行した結果とする。それが 例外 を投げた場合は、その例外を再スローする。

  2. r を返す。

FederatedCredential オブジェクトは FederatedCredentialInit 辞書を navigator.credentials.create() に渡すことで作成できます。

dictionary FederatedCredentialInit : CredentialData {
  USVString name;
  USVString iconURL;
  required USVString origin;
  required USVString provider;
  DOMString protocol;
};

partial dictionary CredentialCreationOptions {
  FederatedCredentialInit federated;
};

FederatedCredential オブジェクトは オリジンに紐付けられています

FederatedCredentialインターフェースオブジェクトCredential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) の実装を継承し、 [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)[[Create]](origin, options, sameOriginWithAncestors)[[Store]](credential, sameOriginWithAncestors) の独自実装を定義します。

注記: 将来的にユーザーエージェントがユーザーのために認証トークンを取得できるようになった場合、 [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) の実装を追加することで実現できます。

4.1.1. プロバイダーの識別

すべてのサイトは、特定のフェデレーテッドアイデンティティプロバイダーを参照する際に同じ識別子を使用するべきです。例えば Facebook Login は "Facebook" や "Facebook Login" や "FB" や "FBL" や "Facebook.com" などと呼ばず、誰もが利用できる正規の識別子を持つべきです。識別が一貫していれば、ユーザーエージェントが役立つことが可能になります。

一貫性のため、本書で定義されたAPIに渡されるフェデレーション(例: FederatedCredentialRequestOptionsproviders 配列や FederatedCredentialprovider プロパティ)は、プロバイダーがサインインに使用する origin のASCIIシリアライゼーション で識別されなければなりません。 つまり、Facebookは https://www.facebook.com、Googleは https://accounts.google.com で表されます。

この origin のシリアライゼーションには、末尾の U+002F SOLIDUS ("/") は含まれませんが、ユーザーエージェントはそれを黙って受け入れるべきです: https://accounts.google.com/ は明らかに https://accounts.google.com と同じ意味です。

4.2. アルゴリズム

4.2.1. FederatedCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)

[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)originorigin)、CredentialRequestOptionsoptions)、および呼び出し元コンテキストが 祖先と同一オリジン である場合に限り true となるブール値(sameOriginWithAncestors)を受け取ります。 このアルゴリズムは credential store から Credential オブジェクトの集合を返します。該当する Credential オブジェクトが存在しない場合、返却される集合は空になります。

  1. Assert: options["federated"] 存在する

  2. もし sameOriginWithAncestorsfalse なら、"NotAllowedError" DOMException を投げる。

    注記: この制限は § 6.4 オリジン混同 で提起された懸念に対応するためのものです。

  3. もし options["federated"] が true でなければ、空集合を返す。

  4. credential store からクレデンシャルのリストを取得する の結果を、以下のフィルターに一致するもののみ返す:

    1. クレデンシャルが FederatedCredential であること

    2. クレデンシャルの [[origin]]origin同一オリジンであること。

    3. もし options["federated"]["providers"] 存在する場合、その値がクレデンシャルの provider含むこと。

    4. もし options["federated"]["protocols"] 存在する場合、その値がクレデンシャルの protocol含むこと。

4.2.2. FederatedCredential[[Create]](origin, options, sameOriginWithAncestors)

[[Create]](origin, options, sameOriginWithAncestors)originorigin)、CredentialCreationOptionsoptions)、および呼び出し元コンテキストが 祖先と同一オリジンの場合のみ true となるブール値(sameOriginWithAncestors)を受け取ります。 このアルゴリズムは FederatedCredential が作成できればそれを返し、できなければ null を返します。また、例外的な場合は 例外 を投げます:

  1. Assert: options["federated"] 存在すること、および sameOriginWithAncestors は未使用であること。

  2. options["federated"] の origin メンバーの値を origin の値に設定する。

  3. FederatedCredentialInit から FederatedCredential を作成するoptions["federated"] に対して実行した結果を返す。 それが 例外 を投げた場合は、その例外を再スローする。

4.2.3. FederatedCredential[[Store]](credential, sameOriginWithAncestors)

[[Store]](credential, sameOriginWithAncestors)FederatedCredentialcredential)、および呼び出し元コンテキストが 祖先と同一オリジン の場合のみ true となるブール値(sameOriginWithAncestors)を受け取ります。 このアルゴリズムは credentialcredential store に保存したら undefined を返します。

もし sameOriginWithAncestorstrue でなければ、NotAllowedError を返します。

  1. "NotAllowedError" DOMException を投げ、ユーザーエージェントの credential store を変更しない。 sameOriginWithAncestorsfalse の場合。

    注記: この制限は § 6.4 オリジン混同 で提起された懸念に対応するためのものです。

  2. もしユーザーエージェントの credential storeFederatedCredential が存在し、その id 属性が credentialid であり、 [[origin]] スロットが credential[[origin]]providercredentialprovider である場合は、返す。

  3. ユーザーがクレデンシャルの保存を許可した場合(ユーザー操作を定義するときに議論)、FederatedCredentialcredential store に以下のプロパティで保存する:

    id

    credentialid

    name,

    credentialname

    iconURL

    credentialiconURL

    [[origin]]

    credential[[origin]]

    provider

    credentialprovider

    protocol

    credentialprotocol

4.2.4. FederatedCredentialInit から FederatedCredential を作成する

FederatedCredentialInit から FederatedCredential を作成する ためには、FederatedCredentialInit (init) を受け取り、次の手順を実行します。

  1. c を新しい FederatedCredential オブジェクトとする。

  2. 以下のいずれかが空文字列の場合、TypeError 例外 を投げる:

  3. c のプロパティを以下のように設定する:

    id

    init.id の値

    provider

    init.provider の値

    iconURL

    init.iconURL の値

    name

    init.name の値

    [[origin]]

    init.origin の値。

  4. c を返す。

5. ユーザー仲介

APIを通じてウェブにクレデンシャル情報を公開することは、ユーザーのプライバシーに関してさまざまな影響を及ぼす可能性があります。したがって、ユーザーエージェントはユーザーが何が起こっているか、誰と自分のクレデンシャルが共有されるのかを明確に理解できるように、いくつかの場合においてユーザーを関与させなければなりません。

あるアクションがユーザーの明示的な同意を得た後に行われる場合、それを ユーザー仲介 と呼びます。同意は、クレデンシャル選択インターフェースとの直接的な操作によって示される場合があります。一般的に、ユーザー仲介アクションは、ユーザーに何らかのUIを提示し、意思決定を求めることが含まれます。

アクションがユーザーの明示的な同意なしに静かに行われる場合、それは非仲介型です。例えば、ユーザーが特定のオリジンに永続的なクレデンシャルアクセスを許可するようブラウザを設定した場合、ユーザーに意思決定を求めるUIを表示せずにクレデンシャルが提供されることがあります。

ここでは、すべてのクレデンシャルタイプに共通するいくつかの要件を示しますが、ユーザーエージェント側の裁量に委ねられている部分も多くあります(ユーザーを支援できる特権的な立場にあるため)。また、特定のクレデンシャルタイプには、ここで一般的に記載されている要件を超える独自の要件がある場合もあります。

5.1. クレデンシャルの保存と更新

クレデンシャル情報は機微なデータであり、ユーザーがその情報の保存を常に管理できる必要があります。意図しないクレデンシャルの保存は、特定のデバイス上のローカルプロファイルとオンライン上の特定の人物が予期せず紐付けられる可能性があります。このような驚きのリスクを軽減するために:

  1. クレデンシャル情報はユーザー仲介なしに保存や更新すべきではありません。例えば、ユーザーエージェントは store() の呼び出しごとに「このクレデンシャルを保存しますか?」というダイアログを表示できます。

    ユーザーの同意は、ユーザーエージェントが「常にパスワードを保存する」などの永続的な同意オプションを提供する場合に推測されることもあります(ただし、より範囲の狭い「常に生成されたパスワードのみ保存する」や「このサイトのパスワードのみ保存する」といった選択肢が望ましいでしょう)。

  2. ユーザーエージェントはクレデンシャルが保存されたとき、ユーザーに通知すべきです。これはアドレスバーのアイコン表示などで実現できます。

  3. ユーザーエージェントはユーザーが保存済みクレデンシャルを手動で削除できるようにしなければなりません。この機能は設定ページや上記の通知とのインタラクションなどで実装できます。

5.2. ユーザー仲介の要求

デフォルトでは、すべてのユーザー仲介オリジンに対して要求されます。これは対応するサイレントアクセス防止フラグクレデンシャルストア内で true に設定されているためです。ユーザーはオリジンへのクレデンシャルへの永続的なアクセスを許可することもでき(例えば「このサイトに常にログインした状態にする」オプションなど)、このフラグが false になります。この場合、ユーザーは常にそのサイトにログインした状態になりますが、利便性の観点では望ましいものの、場合によっては驚きの結果を招くこともあります(例えば、ユーザーエージェントがこのフラグの状態を複数のデバイス間で同期する場合など)。

驚きのリスクを軽減するために:

  1. ユーザーエージェントは、特定のオリジンやすべてのオリジンに対してユーザー仲介を要求できるようユーザーに許可しなければなりません。この機能は、各オリジンのサイレントアクセス防止フラグfalse にするグローバル切替や、特定オリジンや特定クレデンシャルに対する個別設定などで実現できます。

  2. ユーザーエージェントは、オリジンサイレントアクセス防止フラグユーザー仲介なしに falseにしてはなりません。例えば、クレデンシャル選択でチェックボックスを設け、ユーザーがそのオリジンに対して仲介なしでクレデンシャルを利用できるように指定できたり、クレデンシャルマネージャーの初期設定でデフォルト設定を尋ねることもできます。

  3. ユーザーエージェントは、クレデンシャルがオリジンに提供された際にユーザーに通知しなければなりません。これはアドレスバーのアイコン表示などで実現できます。

  4. ユーザーがオリジンの閲覧データ(Cookie、localStorageなど)をクリアした場合、ユーザーエージェントはそのオリジンのサイレントアクセス防止フラグtrue に設定しなければなりません。

5.3. クレデンシャルの選択

get() の呼び出しに対し、ユーザー仲介が必要なオリジンの場合、ユーザーエージェントはクレデンシャル情報の共有についてユーザーの許可を求めなければなりません。 これは、ユーザーに利用可能なクレデンシャルの一覧を提示し、どれをウェブサイトに提供するか選択したり、リクエスト自体を中止できる クレデンシャル選択UIの形態で実装するべきです。

選択UIは、ウェブサイトが生成できるUIとは区別できるように実装されるべきです。例えば、選択UIがユーザーエージェントのUIと重なり、偽装できない方法で実装することが考えられます。

選択UIには、クレデンシャルを要求しているオリジンの表示が含まれていなければなりません。

選択UIには、要求元オリジンに関連付けられたすべてのCredentialオブジェクトが含まれているべきです。

ユーザーエージェントは、Credentialオブジェクトごとに、本書で規定されている属性以外の情報を内部的に持つことができます。例えば、ファビコンを使ってIDプロバイダーを区別するなどです。追加情報はウェブには直接公開されてはなりません。

選択UIの挙動は本書では定義しません。ユーザーエージェントは認証オプションについてユーザーを教育し、適切なクレデンシャル選択を促すUIの工夫を推奨します。ただし、選択UIのインターフェースは以下の通りです:

ユーザーエージェントは ユーザーにCredentialを選択させることができます。これは CredentialRequestOptions (options) と、クレデンシャルストアから取得したCredentialオブジェクトの集合(locally discovered credentials)を受け取ります。

このアルゴリズムは、ユーザーがクレデンシャルの共有を拒否した場合は null、特定のクレデンシャルを選択した場合は Credentialオブジェクト、クレデンシャルのタイプのみ選択した場合はCredentialインターフェースオブジェクトを返します。

選択UIでlocally discovered credentialsのリストを表示するのが合理的でしょう。例えば、以下の非常に非規範的なモックのようなUIです:

A mockup of what a chooser might look like.

もし options事前にマッチ可能でない場合、選択UIには明示的なクレデンシャルリスト以外に、関連するクレデンシャルインターフェースオブジェクトも表示するのが適切かもしれません。 例えば、サイトがWebAuthn形式の認証器を受け入れる場合、「セキュリティキー」が適切なアイコン付きで選択リストに表示されることがあります。

また、場合によってはユーザーエージェントが選択UI自体を省略することもあります。たとえば、唯一の関連するインターフェースオブジェクトがユーザー操作を必須とする場合は、ユーザーエージェントがそのインターフェースを直接返し、内部の仲介フローでユーザー同意を取得することができます。

6. セキュリティに関する考慮事項

以下の各節は、セキュリティおよびプライバシーに関するガイドラインを示しています。個々のクレデンシャルタイプは、これらのガイドラインより厳格または緩和されたバージョンを適用することがあります。

6.1. クロスドメインでのクレデンシャルアクセス

クレデンシャルは機微な情報であり、ユーザーエージェントはそれをウェブサイトと安全に共有できるタイミングについて慎重である必要があります。最も安全な選択肢は、クレデンシャルの共有を保存した正確なオリジンに限定することです。しかし、それはウェブにとって制約が厳しすぎる場合があります。たとえば、example.comadmin.example.comのように機能をサブドメインに分割するサイトを考えてみてください。

ユーザーへの煩わしさとセキュリティのバランスを取るため、ユーザーエージェントは以下のようにします:

  1. スキーム要素がセキュリティを低下させるオリジン間でクレデンシャルを共有してはなりません。つまり、http://example.com/で保存したクレデンシャルをhttps://example.com/で利用できるようにするのは(開発者の安全な通信への移行を促すため)許容されますが、その逆は危険です。

  2. ユーザーエージェントはPublic Suffix List [PSL]を使用して、クレデンシャルの有効範囲を決定してもよいです。これはクレデンシャルの登録可能ドメイン[[origin]]、およびget()が呼ばれるオリジンの比較によって判断します。つまり、https://admin.example.com/https://example.com/で保存されたクレデンシャルは、https://www.example.com/からget()が呼ばれた際に提示されてもよく、逆も同様です。

  3. クレデンシャルのオリジンが呼び出し元オリジンと完全一致しない場合、get()への応答でクレデンシャルを直接提示してはなりません。必ずユーザー仲介を伴う必要があります。つまり、Credentialオブジェクトはhttps://example.comから直接https://www.example.comに返されることはなく、選択UIを経由してユーザーに提示する必要があります。

6.2. クレデンシャル漏洩

開発者は、クロスサイトスクリプティング攻撃がユーザーアカウントへの持続的なアクセスに繋がるリスクを軽減するため、送信先を制限する適切なContent Security Policy [CSP]を設定することが推奨されます。特に、ページのポリシーには以下のディレクティブを明示的または暗黙的に設定すべきです:

もちろん、開発者は入力と出力の適切なエスケープ処理や、Subresource Integrity [SRI]など、他の防御策も検討すべきです。

特定のクレデンシャルタイプを定義する際には、クレデンシャルデータの送信方法にも十分な配慮を行うべきです。例えば、同一オリジンのエンドポイントのみ送信を許可する伝送方式を定義するのが妥当かもしれません。

6.3. 安全でないサイト

ユーザーエージェントは、現行標準で定義されたAPIをセキュアコンテキストでない環境に公開してはなりません。ユーザーエージェントは、潜在的に信頼できないURL上でサインインフォームを自動入力する機能を持つことはありますが、そうしたサイトはクレデンシャルマネージャーと直接やりとりする信頼はできず、セキュアコンテキストで保存されたクレデンシャルへのアクセスは許可されません。

6.4. オリジン混同

フレーム化されたページが現行標準で定義されたAPIにアクセスできる場合、ユーザーがトップレベル閲覧コンテキスト以外のオリジンに対してクレデンシャルへのアクセス権を誤って与えてしまう可能性があります。トップレベル閲覧コンテキストこそが、ユーザーが理解できる唯一のセキュリティオリジンです。

本書では、ユーザーエージェントがUI設計に十分配慮すれば、いくつかのクレデンシャルタイプはそうしたコンテキストにも安全に公開可能と考え、Credential Management APIをそれらのコンテキストにも公開しています。

しかしながら、特定のクレデンシャルタイプはリスクなしでこうしたコンテキストに公開するのが困難です。これらのタイプは、[[Create]](origin, options, sameOriginWithAncestors)[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)[[Store]](credential, sameOriginWithAncestors) の各メソッドにおいて適切に制限されています。

例えば、PasswordCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) メソッドは、Workerや非トップレベル閲覧コンテキストから呼ばれた場合、即座に空集合を返します。

6.5. サインアウト

ユーザーが§5.2 ユーザー仲介の要求で述べたように、ウェブサイトへの自動サインインを選択している場合、ユーザーエージェントは要求に応じてオリジンにクレデンシャルを提供します。ウェブサイトは、CredentialsContainerpreventSilentAccess() メソッドを呼び出すことで、この動作を抑制できます。これにより特定のオリジンで自動サインインを停止できます。

ユーザーエージェントはウェブサイトが適切に振る舞うことに依存しています。不注意または悪意のあるウェブサイトがこのメソッドを呼ばなければ、ユーザーエージェントはユーザーの意図に反してクレデンシャルを提供し続けることになります。これは、サイトがユーザーが「サインアウト」をクリックしてもクレデンシャルを消去しない現状よりも若干悪化します。なぜなら、ユーザーエージェントが認証に加担することになるからです。

ユーザーはこの動作を制御できなければなりません。§5.2 ユーザー仲介の要求で述べた通り、オリジンのCookieを消去すると、そのオリジンのサイレントアクセス防止フラグクレデンシャルストア内でtrueにリセットされます。加えて、ユーザーエージェントは特定オリジンの自動サインインを無効化できるUI(例えばクレデンシャルが提供された通知に連動したUIなど)も提供すべきです。

7. プライバシーに関する考慮事項

7.1. タイミング攻撃

ユーザーがあるオリジンに対してクレデンシャルを持っていない場合、get() の呼び出しは非常に素早く解決されます。悪意のあるウェブサイトは、クレデンシャルを持っていないユーザーと、クレデンシャルは持っているが共有しないユーザーとを区別することができます。

ユーザーエージェントはクレデンシャル要求にレート制限を設けるべきです。短時間に何度もクレデンシャルを要求するページはほぼ確実に悪質です。

7.2. 選択UIの漏洩

ユーザーエージェントのクレデンシャル選択UIがオリジンから提供された画像(例えばCredential がサイトのファビコンを表示する場合)を表示する場合、これらの画像のリクエストは選択UIの生成に直接紐付けてはなりません。選択UIの利用状況が漏れるのを防ぐためです。ひとつの方法は、クレデンシャルの保存や更新時に画像をバックグラウンドで取得し、クレデンシャルの有効期間中キャッシュしておくことです。

これらの画像はcredentials modeを"omit"、 service-workers modeを"none"、 clientnullinitiatorを空文字列、 destinationを"subresource"に設定して取得しなければなりません。

さらに、ユーザーエージェントがクレデンシャルに関連付けられた名前やアイコンをユーザーが変更できる場合、その変更内容はウェブサイトに公開されるべきではありません(例えば、ユーザーが同じオリジンの2つのクレデンシャルに「偽のアカウント」と「本物のアカウント」と名付けた場合など)。

7.3. ローカル保存データ

このAPIは、オリジンに対し、ユーザープロファイルとともにデータを永続的に保存する機能を提供します。 多くのユーザーエージェントはクレデンシャルデータを「閲覧データ」(Cookieなど)とは区別して扱うため、ユーザーがCookieを消去してオリジンの痕跡がすべて消えたと思っても、クレデンシャルが残っていて驚く可能性があります。

ユーザーエージェントは、オリジンごとにクレデンシャルデータが保存されていることをユーザーに明示するUIを提供し、不要になったデータを容易に削除できるようにすべきです。

8. 実装に関する考慮事項

この節は規範的ではありません。

8.1. ウェブサイト制作者向け

このAPIをいつ・どのように使うべきか、特にmediation について考察を追加してください。 [Issue #w3c/webappsec#290]

fetch()FormData bodyを使ってクレデンシャルを送信する場合のエンコーディング制約も記述してください。

特定のクレデンシャルタイプの機能検出を行う際は、Credential の存在ではなく、必要な特化型が存在することを確認するのが推奨されます。前者はAPI自体の存在確認ですが、サイトで必要なクレデンシャルタイプのサポートを保証しません。例えば、パスワードが必要なサイトの場合はif (window.PasswordCredential)で確認するのが最も効果的です。

8.2. 拡張ポイント

この文書は、特定の認証ニーズに応じたクレデンシャル タイプで拡張されることを前提とした、汎用的かつ高水準なAPIを提供しています。拡張は、以下のように行うのが望ましいです:

  1. Credentialを継承した新しいインターフェースを定義します:

    [Exposed=Window,
     SecureContext]
    interface ExampleCredential : Credential {
      // Definition goes here.
    };
    
  2. [[Create]](origin, options, sameOriginWithAncestors)[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)[[Store]](credential, sameOriginWithAncestors) を新しいExampleCredentialインターフェースオブジェクトで定義します。[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) は、永続的に有効なクレデンシャルに適しており、単純にクレデンシャルストアからコピーすればよいです。一方[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) は、再生成が必要なクレデンシャルに適しています。

    例えば、PublicKeyCredential[[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) のような長時間の処理では、options.signalで開発者が処理を中断できるようにすることが推奨されます。詳細はDOM §3.3 AbortControllerとAbortSignalオブジェクトのAPI統合を参照してください。

    ExampleCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) 内部メソッドは、 originorigin)、CredentialRequestOptionsオブジェクト(options)、呼び出し元が祖先と同一オリジンの場合のみtrueとなるブール値を受け取ります。アルゴリズムは指定されたオプションに一致するCredentialオブジェクトの集合を返します。一致するCredentialがなければ空集合を返します。
    1. Assert: options[example]が存在する。

    2. options[example]がtruthyでなければ空集合を返す。

    3. クレデンシャルストア内の各credentialについて:

      1. ...

  3. ExampleCredentialインターフェースオブジェクト[[type]]スロットの値を定義します:

    ExampleCredentialインターフェースオブジェクト[[type]]という名前の内部スロットを持ち、値は"example"です。
  4. ExampleCredentialインターフェースオブジェクト[[discovery]]スロットの値を定義します:

    ExampleCredentialインターフェースオブジェクト[[discovery]]という名前の内部スロットを持ち、値は"credential store"です。
  5. 新しいクレデンシャルタイプに必要なオプションでCredentialRequestOptionsを拡張し、 get()に適切に対応できるようにします:

    dictionary ExampleCredentialRequestOptions {
      // Definition goes here.
    };
    
    partial dictionary CredentialRequestOptions {
      ExampleCredentialRequestOptions example;
    };
    
  6. 新しいクレデンシャルタイプで必要なデータを使ってCredentialCreationOptionsを拡張し、 create()でクレデンシャルオブジェクトを作成できるようにします:

    dictionary ExampleCredentialInit {
      // Definition goes here.
    };
    
    partial dictionary CredentialCreationOptions {
      ExampleCredentialInit example;
    };
    
  7. 新しいクレデンシャルタイプがconditionalユーザー仲介をサポートする場合は、ExampleCredential/isConditionalMediationAvailable()を定義し、trueで解決されるPromiseを返すようにします。

  8. §2.1.2.1 登録項目要件と更新手続きに従い、新しい"example"クレデンシャルタイプと対応する以下の項目をクレデンシャルタイプレジストリに追加します:

    注記: クレデンシャルタイプのオプション辞書のOptions Member Identifierは、 CredentialCreationOptionsCredentialRequestOptionsの両方で同じでなければならず、Credentialインターフェースオブジェクト[[type]]スロット値とも一致すべきです。

新しいプリミティブが必要になる場合もあります。例えば、複雑な多要素認証プロセスで複数のCredentialオブジェクトを返したい場合などです。この場合は、getAll()メソッドをCredentialsContainerに追加し、sequence<Credential>を返すようにし、異なるタイプのクレデンシャルを要求する合理的な仕組みを定義することで対応可能です。

そのような拡張の場合は、public-webappsec@へ相談・レビューを依頼することを推奨します。

8.3. ブラウザー拡張

理想的には、拡張機能システムを実装するユーザーエージェントは、第三者がこれらAPIエンドポイントにフックして、サードパーティのクレデンシャル管理ソフトの動作をユーザーエージェント自身と同じ形で改善できるようにするべきです。

これは、ユーザーエージェントが仲介する複雑な新APIを用意する場合から、拡張機能が自分自身の目的でget()store()のエンドポイントを上書きできるようにする場合まで、幅広く考えられます。

9. 今後の課題

この節は規範的ではありません。

ここで定義したAPIは、ユーザーエージェントのクレデンシャルマネージャーをウェブに公開するための最低限の機能を提供し、ウェブがフェデレーテッドアイデンティティプロバイダーの利用状況をクレデンシャルマネージャーに伝えるのに役立ちます。次の論理的なステップは、[WEB-LOGIN] や、ある程度は Mozilla の BrowserID [BROWSERID] のような文書で概略されている方向性になるでしょう。

ユーザーエージェントは、ユーザー・アイデンティティプロバイダー・ウェブサイト間の関係を効果的に仲介できる唯一の立場にあります。ユーザーエージェントが一般的な認証フローに伴うリスクや混乱を軽減できれば、ユーザーは現在よりもはるかに良い状況になるでしょう。

この情報を公開する自然な方法としては、FederatedCredential インターフェースを認証トークンなどのプロパティで拡張したり、プロバイダーがサポートする認証タイプを宣言するプロパティを持つマニフェスト形式を追加することが考えられます。

ここで説明したAPIは、ユーザー操作を必要とするユースケースや、クレデンシャルを要求したウェブサイト以外のサイトとのやり取りを含むユースケースにも対応できるよう十分に拡張可能となるよう設計されています。Promiseベースのシステムは、複数の閲覧コンテキスト間(例:idp.com での仲介活動によって rp.com にPromiseが返される場合)や、将来デバイス・ユーザーエージェント間(例:[WEBAUTHN])での非同期フローをAPI自体の再設計なしにサポートできる拡張性を持つことを期待しています。

少しずつ前進していきます。

索引

この仕様で定義されている用語

参照によって定義された用語

参考文献

規範的参考文献

[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. 2024年6月18日. WD. URL: https://www.w3.org/TR/CSP3/
[DIGITAL-IDENTITIES]
Digital Credentials. Draft Community Group Report. URL: https://wicg.github.io/digital-identities/
[DOM]
Anne van Kesteren. DOM Standard. 現行標準. URL: https://dom.spec.whatwg.org/
[FEDCM]
Federated Credential Management API. Draft Community Group Report. URL: https://fedidcg.github.io/FedCM/
[FETCH]
Anne van Kesteren. Fetch Standard. 現行標準. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; 他. HTML Standard. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 現行標準. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2024年3月19日. WD. URL: https://www.w3.org/TR/permissions/
[PROMISES-GUIDE]
Domenic Denicola. Writing Promise-Using Specifications. 2018年11月9日. TAG Finding. URL: https://www.w3.org/2001/tag/doc/promises-guide
[PSL]
Public Suffix List. Mozilla Foundation.
[SECURE-CONTEXTS]
Mike West. Secure Contexts. 2023年11月10日. CR. URL: https://www.w3.org/TR/secure-contexts/
[WEB-OTP]
WebOTP API. Draft Community Group Report. URL: https://wicg.github.io/web-otp/
[WEBAUTHN-3]
Michael Jones; Akshay Kumar; Emil Lundberg. Web Authentication: An API for accessing Public Key Credentials - Level 3. 2023年9月27日. WD. URL: https://www.w3.org/TR/webauthn-3/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 現行標準. URL: https://webidl.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. 現行標準. URL: https://xhr.spec.whatwg.org/

参考情報

[BROWSERID]
Ben Adida; 他. BrowserID. 2013年2月26日. URL: https://github.com/mozilla/id-specs/blob/prod/browserid/index.md
[DIGITAL-CREDENTIALS]
Marcos Cáceres; Sam Goto. Digital Credentials. URL: https://wicg.github.io/digital-credentials/
[SRI]
Devdatta Akhawe; 他. Subresource Integrity. 2016年6月23日. REC. URL: https://www.w3.org/TR/SRI/
[WEB-LOGIN]
Jason Denizac; Robin Berjon; Anne van Kesteren. web-login. URL: https://github.com/jden/web-login
[WEBAUTHN]
Dirk Balfanz; 他. Web Authentication:An API for accessing Public Key Credentials Level 1. 2019年3月4日. REC. URL: https://www.w3.org/TR/webauthn-1/
[XMLHTTPREQUEST]
Anne van Kesteren; 他. XMLHttpRequest Level 1. 2016年10月6日. NOTE. URL: https://www.w3.org/TR/XMLHttpRequest/

IDL一覧

[Exposed=Window, SecureContext]
interface Credential {
  readonly attribute USVString id;
  readonly attribute DOMString type;
  static Promise<boolean> isConditionalMediationAvailable();
  static Promise<undefined> willRequestConditionalCreation();
};

[SecureContext]
interface mixin CredentialUserData {
  readonly attribute USVString name;
  readonly attribute USVString iconURL;
};

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute CredentialsContainer credentials;
};

[Exposed=Window, SecureContext]
interface CredentialsContainer {
  Promise<Credential?> get(optional CredentialRequestOptions options = {});
  Promise<undefined> store(Credential credential);
  Promise<Credential?> create(optional CredentialCreationOptions options = {});
  Promise<undefined> preventSilentAccess();
};

dictionary CredentialData {
  required USVString id;
};

dictionary CredentialRequestOptions {
  CredentialMediationRequirement mediation = "optional";
  AbortSignal signal;
};

enum CredentialMediationRequirement {
  "silent",
  "optional",
  "conditional",
  "required"
};

dictionary CredentialCreationOptions {
  CredentialMediationRequirement mediation = "optional";
  AbortSignal signal;
};

[Exposed=Window,
 SecureContext]
interface PasswordCredential : Credential {
  constructor(HTMLFormElement form);
  constructor(PasswordCredentialData data);
  readonly attribute USVString password;
};
PasswordCredential includes CredentialUserData;

partial dictionary CredentialRequestOptions {
  boolean password = false;
};

dictionary PasswordCredentialData : CredentialData {
  USVString name;
  USVString iconURL;
  required USVString origin;
  required USVString password;
};

typedef (PasswordCredentialData or HTMLFormElement) PasswordCredentialInit;

partial dictionary CredentialCreationOptions {
  PasswordCredentialInit password;
};

[Exposed=Window,
 SecureContext]
interface FederatedCredential : Credential {
  constructor(FederatedCredentialInit data);
  readonly attribute USVString provider;
  readonly attribute DOMString? protocol;
};
FederatedCredential includes CredentialUserData;

dictionary FederatedCredentialRequestOptions {
  sequence<USVString> providers;
  sequence<DOMString> protocols;
};

partial dictionary CredentialRequestOptions {
  FederatedCredentialRequestOptions federated;
};

dictionary FederatedCredentialInit : CredentialData {
  USVString name;
  USVString iconURL;
  required USVString origin;
  required USVString provider;
  DOMString protocol;
};

partial dictionary CredentialCreationOptions {
  FederatedCredentialInit federated;
};

課題一覧

ここやインターフェースオブジェクトの箇所、および§ 2.5.1 クレデンシャルの要求などについて、Tobie/Dominicに相談してください。用語の使い方が正しいか自信がありません。インターフェースプロトタイプオブジェクトかもしれません。
このモデルは間違っているかもしれません。ユーザー名/パスワードまたはWebAuthn型のクレデンシャルのいずれかを受け入れたいサイトをサポートできれば便利ですが、前者を使っていて、常にサインインしていたいユーザーに対して選択UIを強制するのは避けたいところです。
このAPIをいつ・どのように使うべきか、特にmediationに関して、考察を追加してください。 [Issue #w3c/webappsec#290]
fetch()FormDataボディとしてクレデンシャルを送信する場合のエンコーディング制約も記述してください。
MDN

Credential/id

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Credential/type

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Credential

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CredentialsContainer/create

In all current engines.

Firefox60+Safari13+Chrome60+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CredentialsContainer/get

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CredentialsContainer/preventSilentAccess

In all current engines.

Firefox60+Safari13+Chrome60+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CredentialsContainer/store

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CredentialsContainer

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FederatedCredential/FederatedCredential

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FederatedCredential/protocol

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FederatedCredential/provider

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FederatedCredential

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Navigator/credentials

In all current engines.

Firefox60+Safari13+Chrome51+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PasswordCredential/PasswordCredential

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PasswordCredential/iconURL

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PasswordCredential/name

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PasswordCredential/password

In only one current engine.

FirefoxNoneSafariNoneChrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PasswordCredential

In only one current engine.

FirefoxNoneSafariNoneChrome51+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?