1. 導入
このセクションは規範的ではありません。
ユーザーエージェントは時々、特定の
iframe
内のコンテンツがクッキーなどのクライアントサイドストレージメカニズムに保存されたデータへアクセスするのを防ぐことがあります。これにより、クライアントサイドストレージへのアクセスに依存している埋め込みコンテンツが動作しなくなる場合があります。
ストレージアクセスAPIは、
iframe
内のコンテンツが自分のクライアントサイドストレージへのアクセスを要求・許可されるようにし、ストレージへのアクセスに依存する埋め込みコンテンツがそのようなユーザーエージェント内でも動作できるようにします。[STORAGE-ACCESS-INTRO]
2. インフラストラクチャ
この仕様はInfra標準に依存します。[INFRA]
3. ストレージアクセスAPI
この仕様は、Document
が現在非分割データにアクセスできるかどうかを問い合わせるメソッド(hasStorageAccess())
と、非分割データへのアクセスを要求するためのメソッド(requestStorageAccess())
を定義します。
Alexがhttps://social.example/を訪れます。このページはクッキーを設定します。このクッキーは
ファーストパーティサイトコンテキスト
で設定されました。
後で、Alexはhttps://video.example/を訪れます。そこには
iframe
があり、https://social.example/heart-buttonを読み込みます。この場合、
social.exampleのDocument
docはサードパーティコンテキストとなり、以前に設定されたクッキーがdoc.cookie
から見えるかどうかは、ユーザーエージェントのストレージアクセス方針によって決まります。
iframe
内のスクリプトは、doc.hasStorageAccess()を呼び出すことでクッキーへのアクセス可否を確認できます。もしアクセスできない場合は、doc.requestStorageAccess()を呼び出してアクセスを要求できます。
非分割データ とは、そのサイト がファーストパーティサイトコンテキスト で読み込まれた場合に利用可能なクライアントサイドストレージです。
Document
は、アクティブドキュメント
であり、
トップレベル閲覧コンテキスト
の場合はファーストパーティサイトコンテキストとなります。
そうでない場合、 origin と top-level origin が同一サイトであれば、
ファーストパーティサイトコンテキストとなります。
Document
がファーストパーティサイトコンテキストでない場合、そのサードパーティコンテキストにあるとみなします。
ユーザーエージェントが非分割クッキーアクセスを明示的に許可するかどうか判定するには、タプル
tuple
(2つのサイトを含む)を与えられた場合、次の手順を実行します。このアルゴリズムは
"none"、"allow"、"disallow" を返します。
注: ユーザーエージェントの設定は、サイトごとの許可リストやグローバル設定の変更、その他の独自オーバーライドなどにより、非分割クッキーアクセスの明示的な許可または禁止を行うことがあります。
-
ユーザーエージェントがtupleに関して非分割クッキーアクセスに関する明示的な設定を持たない場合、"
none" を返す。 -
ユーザーエージェントの設定がtupleに対して非分割クッキーアクセスを明示的に許可している場合、"
allow" を返す。 -
アサート: ユーザーエージェントの設定がtupleに対して非分割クッキーアクセスを明示的に禁止している。
-
"
disallow" を返す。
FedCMサイトの接続状態を判定するには、 origin embedder と origin identityProvider を与えて次の手順を実行します。このアルゴリズムはbooleanを返します。
-
すべての item(connected accounts set) について:
-
false を返す。
有効なFedCM接続状態を判定するには、
origin embedder、
origin identityProvider、
Document
doc を与えて次の手順を実行します。このアルゴリズムはbooleanを返します。
-
policyStatus を、docが"
identity-credentials-get"を 使用可能かどうかで定める。 -
policyStatus が "Disabled" の場合は false を返す。
-
connected をembedderとidentityProviderで サイト接続状態を判定した結果とする。
-
connected が false の場合は false を返す。
-
preventSilentAccess を ユーザーエージェント のクレデンシャルストアにおける prevent silent access flag (embedder に対するもの)とする。
-
preventSilentAccess が立っている場合は false を返す。
-
true を返す。
3.1. ストレージアクセスに関するユーザーエージェントの状態の変更
environment の定義を次のように変更します:
-
has storage accessという新しいメンバー(型はboolean)を追加する。
source snapshot params の定義を次のように変更します:
ストレージアクセス適格性は "unset"、"ineligible"、または"eligible"のいずれかです。
request
にはストレージアクセス適格性
eligible for storage-accessがある。初期値は
"unset"。
注:
request
の ストレージアクセス適格性
は、どのクッキーをstorage-access権限を考慮して含めるべきかを評価する際に使われます。特に、requestStorageAccess
が解決し、そのenvironmentのhas storage accessがtrueになっても、その
request のすべてが非分割クッキーを送るとは限りません。
例: ユーザーが https://top.com のページを訪れ、そこに https://embed.com からの
iframe
が埋め込まれ、iframe 内スクリプトが requestStorageAccess
を呼んでpromiseが解決されたとします。そのiframeが続けて https://3p.com へリソースをfetchしても、そのリクエストはStorage Access API経由ではクッキーを含みません。
"ancestry" の概念は https://github.com/whatwg/html/pull/11133 でHTMLに追加中です。
-
requestのclientのhas storage accessがfalseなら、 "
ineligible" を返す。 -
requestのoriginが、requestの url の origin と同一オリジンでないなら "
ineligible" を返す。 -
allowed を Should request be allowed to use feature? を "
storage-access" と request で実行した結果とする。 -
allowed がfalseなら "
ineligible" を返す。 -
"
eligible" を返す。
3.2. Documentの変更点
partial interface Document {Promise <boolean >hasStorageAccess ();Promise <undefined >requestStorageAccess (); };
Document
docで呼び出されたとき、hasStorageAccess()メソッドは以下の手順を実施すること:
-
pに新しいpromiseを設定する。
-
もしdocが完全にアクティブでなければ、reject p "
InvalidStateError"DOMExceptionでrejectし、pを返す。 -
globalをdocの関連グローバルオブジェクトとする。
-
もしglobalがセキュアコンテキストでなければ、resolve p をfalseで解決し、pを返す。
-
もしdocのトップレベルoriginが不透明originなら、resolve p をfalseで解決し、pを返す。
-
browsingContextをdocのブラウジングコンテキストとする。
-
topLevelSiteをサイト取得の結果(docのトップレベルoriginから)とする。
-
次の手順を並列で実行:
-
explicitSettingをユーザーエージェントが非分割クッキーアクセスを明示的に許可するかどうか判定する結果((topLevelSite, embeddedSite))とする。
-
permissionStateを現在の権限状態の取得の結果("
storage-access", global)とする。 -
グローバルタスクキューをnetworkingタスクソース(global指定)で:
-
explicitSettingが"
disallow"なら、resolve pをfalseで解決。 -
explicitSettingが"
allow"なら、resolve pをtrueで解決。 -
アサート:explicitSettingは"
none"。 -
browsingContextがトップレベルブラウジングコンテキストなら、resolve pをtrueで解決。
-
browsingContextがbrowsingContextのトップレベルブラウジングコンテキストのアクティブドキュメントと"same authority"なら、resolve pをtrueで解決。
"same authority"は今後の概念のプレースホルダーで、ユーザーエージェントが同一サイトチェックを追加のセキュリティ観点とともに実行可能にするものです。詳細はwhatwg/storage#142参照。 実際はsite for cookiesを比較したり、トップレベルドキュメントと同一サイトチェックを行うかもしれません。
-
permissionStateがgrantedなら、resolve pをglobalのhas storage accessとする。
注: ユーザー設定による権限の取り消しを即反映させるため、グローバルなストレージアクセス権限状態がローカルフラグより優先されます。
-
resolve pをfalseで解決。
-
-
-
pを返す。
Document
docで呼び出されたとき、requestStorageAccess()メソッドは以下の手順を実施すること:
-
pに新しいpromiseを設定する。
-
もしdocが完全にアクティブでなければ、reject p "
InvalidStateError"DOMExceptionでrejectし、pを返す。 -
globalをdocの関連グローバルオブジェクトとする。
-
settingsをdocの関連設定オブジェクトとする。
-
もしglobalがセキュアコンテキストでなければ、reject p "
NotAllowedError"DOMExceptionでrejectし、pを返す。 -
もしdocが"storage-access"の使用を許可されないなら、reject p "
NotAllowedError"DOMExceptionでrejectし、pを返す。 -
もしdocのoriginが不透明originなら、reject p "
NotAllowedError"DOMExceptionでrejectし、pを返す。 -
もしsettingsのトップレベルoriginが不透明originなら、reject p "
NotAllowedError"DOMExceptionでrejectし、pを返す。 -
もしdocのアクティブサンドボックスフラグセットがsandbox storage access by user activation flagを持つなら、reject p "
NotAllowedError"DOMExceptionでrejectし、pを返す。 -
browsingContextをdocのブラウジングコンテキストとする。
-
topLevelOriginをdocのトップレベルorigin とする(関連設定オブジェクトの)
-
topLevelSiteをサイト取得の結果(topLevelOriginから)とする。
-
embeddedOriginをdocのoriginとする。
-
embeddedSiteをサイト取得の結果(embeddedOriginから)とする。
-
has transient activationをdocの
Windowオブジェクトが一時的アクティベーションを有するかどうかで判定する。 -
以下の手順を並列で実行:
-
process permission stateアルゴリズムを用意。permission state stateを与え、以下を実行:
-
グローバルタスクキューnetworkingタスクソース(global指定)で:
-
stateがgrantedなら:
-
globalのhas storage accessをtrueにする。
-
-
それ以外:
-
ユーザーアクティベーションの消費 (globalで)。
-
-
-
-
explicitSettingをユーザーエージェントが非分割クッキーアクセスを明示的に許可するかどうか判定する結果((topLevelSite, embeddedSite))とする。
-
explicitSettingが"
disallow"の場合:-
process permission stateをdeniedで実行。
-
これ以降中止。
-
-
explicitSettingが"
allow"の場合:-
process permission stateをgrantedで実行。
-
これ以降中止。
-
-
アサート:explicitSettingは"
none"。 -
browsingContextがトップレベルブラウジングコンテキストの場合:
-
process permission stateをgrantedで実行。
-
これ以降中止。
-
-
もしembeddedSiteが同一サイトでtopLevelSiteと同じ場合:
注: このチェックは意図的に同一サイトです。セキュリティ上の理由でストレージアクセスが制限されているシナリオで、エンドユーザーの関与なしに埋め込みサイトが
requestStorageAccess()でストレージアクセスを明示的に有効化できるようにします。-
process permission stateをgrantedで実行。
-
これ以降中止。
-
-
previous permission stateを現在の権限状態の取得の結果("
storage-access", global)とする。 -
もしprevious permission stateがpromptでなければ:
-
process permission stateをprevious permission stateで実行。
-
これ以降中止。
-
-
connectedを有効なFedCM接続状態判定の結果(topLevelOrigin, embeddedOrigin, doc)とする。
-
もしconnected:
注: ユーザーエージェントは、FedCM接続によりストレージアクセスが許可された(サイト,サイト)タプルを管理し、cookieアクセス時にもチェックし、攻撃者による不正を防止することを推奨します。
-
process permission stateをgrantedで実行。
-
これ以降中止。
-
-
もしhas transient activationがfalse:
-
process permission stateをdeniedで実行。
-
これ以降中止。
-
-
permissionStateを権限リクエスト("
storage-access")の結果とする。注: 権限付与/プロンプト表示の際、ユーザーエージェント独自の実装定義挙動が働き、プロンプトなしで許可/拒否することがあります。
-
process permission stateをpermissionStateで実行。
-
-
pを返す。
注: このアルゴリズムの意図は、常にユーザーアクティベーションが必要な場合のみstorage-access権限を設定することです。ユーザーエージェントがヒューリスティックでアクティベーションなしで権限付与する実装も可能ですが、この仕様はそのような動作を強く非推奨とします。相互運用問題につながるためです。
3.3. ナビゲーションの変更
source snapshot paramsのスナップショット時:
-
has storage accessを sourceDocumentのhas storage accessに設定する。
-
environment idを sourceDocumentのrelevant settings objectのidに設定する。
create navigation params by fetchingアルゴリズムの手順3として、次を挿入:
-
originalURLをentryのURLとする。
requestのreserved clientをcreate navigation params by fetching内で作成する際:
-
以下すべてを満たすときは、sourceSnapshotParamsのhas storage accessをreserved clientのhas storage accessに設定する:
-
sourceSnapshotParamsのenvironment idが navigableのactive documentのrelevant settings objectのid と等しい。
-
responseがnullまたはresponseのhas-cross-origin-redirectsが false。
-
-
それ以外の場合、requestのreserved clientのhas storage accessをfalseに設定する。
window environment settings objectのセットアップ時:
-
settings objectのhas storage accessをreserved environmentのhas storage accessに設定する。
3.4. Fetchとの統合
3.4.1. 取得(Fetching)
fetch の手順14の後に新しいステップを挿入:
-
requestのeligible for storage-accessを、 初期ストレージアクセス適格性の決定結果(request) に設定する。
3.4.2. HTTP-リダイレクト取得
HTTP-redirect fetch の手順17の後に新しいステップを挿入:
-
もしrequestのeligible for storage-accessが "
unset" でなく、かつlocationURLのoriginがrequestのcurrent URLのoriginと同一オリジンでなければ、 requestのeligible for storage-access を"ineligible"に設定する。
3.5. さまざまなクライアントサイドストレージメカニズムの変更
このAPIはHTTPクッキーのみに影響します。将来のリビジョンで他のクライアントサイドステートにも影響する可能性があります。[RFC6265]
3.5.1. クッキー
このAPIは、サードパーティコンテキストで非分割クッキーへのアクセスをブロックする環境およびユーザーエージェント構成との併用を意図しています。執筆時点では、この概念はまだHTTP-network-or-cache fetchやcookie
アルゴリズムに統合されていません。そのような統合のためには、cookie store
に、リクエストのトップレベルおよび埋め込みサイト(クロスサイト・分割・非添付クッキーの判断用)と、そのリクエストがstorage accessを持つドキュメントのためになされたかどうか(本仕様で定義されたeligible for storage-access
を参照)、の情報が渡るようにする必要があります。
cookie storeがストレージアクセス情報の受け取りに対応したら、HTTP-network-or-cache fetchやcookie
も、クッキー取得時にrequestのeligible
for storage-accessをcookie store
に渡すよう更新されます。
ストレージアクセスのあるcookie storeから非分割クッキーを取得する際、ユーザーエージェントは引き続きSameSite制約(サードパーティコンテキストでSameSite=StrictやSameSite=Laxを添付しないなど)に従います。
注:
ユーザーエージェントによってはSameSiteクッキー属性のデフォルト値が違う場合があります。そのため、SameSite=NoneがデフォルトのユーザーエージェントではSameSite属性のない非分割クッキーがリクエストに添付される場合がありますが、SameSite=Laxがデフォルトのユーザーエージェントでは添付されません。Web開発者はクッキーにSameSite属性を設定することを推奨します。
3.6. ストレージアクセスのサンドボックス化
sandboxing flag setにはsandbox storage access by user activation flagがあります。このフラグはコンテンツがストレージアクセスを要求するのを防止します。
sandboxingディレクティブのパースアルゴリズムの手順3の下に以下を追加:
- sandbox storage access by user
activation flag(ただしtokensに
allow-storage-access-by-user-activationキーワードが含まれる場合は除く)
4. 権限統合
Storage Access APIは powerful feature として name
"storage-access" で識別されます。次の権限関連アルゴリズムを定義します:
- permission query algorithm
-
"
storage-access"権限のクエリは、PermissionDescriptorpermissionDescとPermissionStatusstatusに対して: - permission key type
-
"
storage-access" のpermission keyは、タプル (site top-levelと、site requester)です。(("https", "news.example"), ("https", "social.example"))は、"storage-access"のpermission keyであり top-levelは("https", "news.example")、requesterは("https", "social.example")です。 - permission key generation algorithm
-
"
storage-access" のpermission key生成は、origin originとorigin embeddedOriginを与え:-
topLevelSiteをobtain a siteでoriginから取得。
-
embeddedSiteをobtain a siteでembeddedOriginから取得。
-
(topLevelSite, embeddedSite)を返す。
-
- permission key comparison algorithm
-
"
storage-access"用のpermission key key1とkey2 を比較するには:
5. 権限ポリシー統合
Storage Access APIは policy-controlled feature
として"storage-access"という文字列で識別されます。そのデフォルト許可リストは"*"です。
注: Document
の権限ポリシーは、そのドキュメント内のコンテンツがrequestStorageAccess()
でストレージアクセスを要求できるかどうかを決定します。どれかのドキュメントで無効なら、そのドキュメントでrequestStorageAccess()
を呼ぶとrejectされます。
6. プライバシーに関する考慮事項
Storage Access APIによってクロスサイトクッキーを削除できるようになります。特に、認証埋め込みのユースケースが動作し続けます。したがって、APIは開発者が制約下ながらクロスサイトクッキーへの再アクセスを可能にします。
入れ子になったDocument
は、active document
のトップレベル閲覧コンテキストのときに持つのと同じクッキーに、requestStorageAccess()
を呼び、そのpromiseが解決されたときアクセスできます。これらクッキーでサーバーに認証したりユーザー固有情報を取得できます。
この機能には第三者によるトラッキングの悪用リスクがありますが、API設計の目的はクロスサイトクッキー廃止の効果を損なわせないことであり、プラットフォーム固有情報に依存せず、追加される状態は埋め込み/埋め込まれサイトsite間の権限だけで、廃止前環境以下にはプライバシー性が劣化しません。
デフォルトでクロスサイトクッキーがすでに廃止されている場合はより困難です。Storage Access APIでクッキーなし(または分割クッキー)の入れ子Document
を廃止前状態に戻し、非分割データ
にアクセスさせる際の許可タイミング・方法の課題が生じます。
理想的には、入れ子Document
が非分割データにアクセスできるのは:
-
ユーザーがその入れ子
Documentを操作した場合 -
入れ子
Documentが埋め込み元によってAPI使用を許可された場合 -
入れ子
Documentがセキュアコンテキストである場合 -
ユーザーがペアごと明示的に埋め込まれ側のクッキー利用権限を埋め込み元に付与した場合
-
「storage-access」許可のリクエストにユーザーが過剰にさらされず、その明示許可が疲労により実質無効にならない場合
この仕様は最初の3点だけ実装者に必須とします。これでユーザーが入れ子Document
内容を把握し、埋め込み元は認証を拒否していないことと、クロスサイトクッキーがネットワーク攻撃者に漏れないことを保証します。
最後の2点はトレードオフです。理想的にはrequestStorageAccess()
毎回プロンプトを表示するのが理想ですが、それだとページが頻繁にプロンプトでき5番目の要件が形骸化してしまいます。ユーザーエージェントは過剰なプロンプトを防ぐべきです。
document.requestStorageAccess()
を呼んだ際にユーザーに表示されるプロンプト例。
このため、最後の2点は妥協点です。他要件を満たす限りはユーザー選択なしに非分割データ許可/拒否タイミングの 実装依存を許容します。この妥協は提案のプライバシー保障(特に4点目)を一部実装依存で弱めますが、5点目実現には必要でした。
ユーザーエージェント間で実装依存の差異が大きいと開発者体験が損なわれるため、ユーザーエージェントはサイレント許可・拒否の標準化や縮小を目指すべきです。
6.1. 権限の範囲
API設計におけるもう一つの緊張点は、「storage-access」権限のキーとしてオリジンかサイトのどちらを使うべきかということです。私たちはサイトを選びました。なぜなら、これによってプライバシーの境界を適切に保ちながら、既存の同一サイトや、同一ページ内のクロスオリジン入れ子Document
でも、ユーザーによるプロンプトが1回で済むからです。
7. セキュリティに関する考慮事項
この仕様は、クロスサイトクッキー廃止後と比べてもウェブプラットフォームのセキュリティ特性が低下しないようにすることが重要です。サードパーティクッキーの廃止は、特に認証済みリクエストに依存する攻撃(例:CSRF)対策においてセキュリティ上有益な可能性があります。Storage Access APIがそのような攻撃を利用する足掛かりとなることは望んでいません。
このため、「storage-access」権限付与の効果は、非分割データ
へのアクセスが、そのDocument
でrequestStorageAccess()
を呼び出した時点と、入れ子Document
がオリジン境界をナビゲートするまでの期間のみに限定されます。これにより、オリジンがページでrequestStorageAccess()
を呼び出す場合のみ認証付きリクエストが送信されること、また埋め込みページ側はContent Security
Policyの「frame-ancestors」ディレクティブを利用して許可する埋め込み元を制御できることになります。これにより、埋め込み側のセキュリティ目的のオリジン単位制御が維持されます。
7.1. 風評攻撃
この設計は、埋め込み側の風評被害を防ぐもう一つの攻撃にも有効です。ユーザーがよりプライバシーを意識する中、クロスサイト認証付きリクエストは評判上のリスクをともないます。したがって、ファーストパーティまたは兄弟クロスサイトがユーザー認証クッキー付きでリソースを埋め込みリクエストさせるのは、クロスサイト所有者への攻撃として見なされます。またこれが、本APIがセキュアコンテキストでなければならない理由でもあります。これによりネットワーク上の攻撃者が埋め込みページにAPIを使わせることができなくなります。
埋め込み元は、どの入れ子Document
が認証可能になったり、ユーザーへの権限要求表示(Permission PolicyやDocument
のサンドボックス等)を許すか、コントロールできます。
7.2. 通知の乱用
通知の乱用についてもStorage Access APIの仕様策定時に考慮されました。具体的には、ユーザー操作が入れ子Document
で必要であり、拒否時にはその拒否を消費して許可プロンプトの表示条件を制限します。これにより、ユーザーが拒否した直後に再び許可を求めてくるような攻撃を緩和できます。
8. 自動化
ユーザーエージェントの自動化やアプリケーションテストの目的のために、この文書は拡張コマンドを[WebDriver]仕様に定義します。
8.1. ストレージアクセスの設定
| HTTPメソッド | URIテンプレート |
|---|---|
| POST | /session/{session id}/storageaccess |
Set Storage Access 拡張コマンドは、現在のブラウジングコンテキストのストレージアクセス方針を変更します。
-
blockedをparametersから
blockedでプロパティ取得した結果にする。 -
もしblockedがbooleanでなければ、WebDriverエラー(WebDriver error code invalid argument)を返す。
-
embedded originをparametersから
originでプロパティ取得した結果にする。 -
もしembedded originがU+002A ASTERISK(*)1文字でなければ:
-
parsedURLをembedded originに対しURLパーサを実行した結果とする。
-
もしparsedURLが失敗なら、WebDriverエラー(WebDriver error code invalid argument)を返す。
-
embedded originをparsedURLのオリジンに設定する。
-
-
もし現在のブラウジングコンテキストがトップレベル閲覧コンテキストでなければ、WebDriverエラー(WebDriver error code unsupported operation)を返す。
-
docを現在のブラウジングコンテキストのactive documentとする。
-
settingsをdocのrelevant settings objectとする。
-
もしembedded originがU+002A ASTERISK(*)1文字の場合:
-
もしblockedが
trueなら:-
実装依存手順により、任意のサイトが、そのtop-level siteのサードパーティコンテキスト で読み込まれるときに非分割データにアクセスできなくすること。
-
-
一方、blockedが
falseなら:-
実装依存手順により、 任意のサイトが、そのtop-level siteのサードパーティコンテキスト で読み込まれるときに非分割データにアクセスできるようにすること。
-
-
-
それ以外の場合:
-
もしembedded originがsettingsのオリジンと同一サイトなら、WebDriverエラー (WebDriver error code unsupported operation)を返す。
-
もしblockedが
trueなら:-
実装依存手順により、 top-level siteのサードパーティコンテキスト でembedded originが非分割データにアクセスできなくすること。
-
-
一方、blockedが
falseなら:-
実装依存手順により、 top-level siteのサードパーティコンテキスト でembedded originが非分割データにアクセスできるようにすること。
-
-
-
上記実装依存手順で失敗した場合は、WebDriverエラー(WebDriver error code unknown error)を返す。
-
successを
nullデータで返す。
謝辞
本仕様は、Storage Access APIを発明したJohn Wilander氏、初期テキストの多くを執筆したTheresa O’Connor氏という前任編集者の基盤に基づいています。彼らのアイデアと貢献に心から感謝します。
また以下の方々に多大なる感謝を表します。 Anne van Kesteren、 Ben Kelly、 Brad Girardeau、 Brad Hill、 Brady Eidson、 Brandon Maslen、 Chris Mills、 Dave Longley、 Domenic Denicola、 Ehsan Akhgari、 Geoffrey Garen、 Jack Frankland、 James Coleman、 James Hartig、 Jeffrey Yasskin、 Kushal Dave、 Luís Rudge、 Maciej Stachowiak、 Matias Woloski、 Mike O’Neill、 Mike West、 Pete Snyder、 Rob Stone、 Stefan Leyhane、 Steven Englehardt、 Travis Leithead、 Yan Zhu、 Zach Edwards、 およびwhatwg/html#3338, privacycg/proposals#2, privacycg/storage-access/issues で本提案にコメントいただいた全ての皆様。
WebKit Open Source Projectに、Storage Access APIプロンプト画像(元はwebkit.orgで公開)の使用を許可いただき感謝します。