関連ウェブサイト セット: デベロッパー ガイド

関連ウェブサイト セット(RWS)は、ブラウザがドメインのコレクション間の関係を理解するのに役立つウェブ プラットフォーム メカニズムです。これにより、ブラウザは特定のサイト機能を有効にするための重要な判断(クロスサイト Cookie へのアクセスを許可するかどうかなど)を行い、その情報をユーザーに提示できます。

Chrome ではサードパーティ Cookie を廃止しますが、その目的は、ユーザーのプライバシーを強化しながら、ウェブ上の主要なユースケースを維持することです。たとえば、多くのサイトでは、複数のドメインを使用して単一のユーザー エクスペリエンスを提供しています。組織は、国固有のドメインや、画像や動画をホストするためのサービス ドメインなど、複数のユースケースに異なるトップレベル ドメインを維持することが必要になる場合があります。関連ウェブサイト セットを使用すると、サイトは特定のコントロールを使用して、ドメイン間でデータを共有できます。

大まかに言うと、関連ウェブサイト セットはドメインの集合であり、1 つの「セットのプライマリ」と複数の「セットのメンバー」が存在する場合があります。

次の例では、primary はプライマリ ドメインを一覧表示し、associatedSites関連するサブセットの要件を満たすドメインを一覧表示します。

{
  "primary": "https://primary.com",
  "associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}

正規の関連ウェブサイト セットのリストは、関連ウェブサイト セットの GitHub リポジトリでホストされている JSON ファイル形式の公開リストです。これは、すべてのセットの信頼できる情報源として機能します。Chrome はこのファイルを使用して動作に適用します。

ドメインの管理者権限を持つユーザーのみが、そのドメインを含むセットを作成できます。送信者は、各「セット メンバー」とその「セット プライマリ」の関係を宣言する必要があります。セットのメンバーにはさまざまなドメインタイプを含めることができ、ユースケースに基づくサブセットの一部にする必要があります。

アプリケーションが、同じ関連ウェブサイト セット内のサイト間でのクロスサイト Cookie(サードパーティ Cookie とも呼ばれます)へのアクセスに依存している場合は、Storage Access API(SAA)requestStorageAccessFor API を使用して、これらの Cookie へのアクセスをリクエストできます。各サイトが属するサブセットによっては、ブラウザがリクエストを異なる方法で処理する場合があります。

セットの送信プロセスと要件について詳しくは、送信ガイドラインをご覧ください。送信されたセットは、さまざまな技術的なチェックを受け、送信内容が検証されます。

関連ウェブサイト セットは、組織がさまざまなトップレベル サイト間で共有 ID の形式を必要とする場合に適しています。

関連ウェブサイト セットのユースケースには、次のようなものがあります。

  • 国別のカスタマイズ。ローカライズされたサイトを活用しながら、共有インフラストラクチャを利用している(example.co.uk が example.ca でホストされているサービスに依存している場合)。
  • サービス ドメインの統合。ユーザーが直接操作することはないが、同じ組織のサイト全体でサービスを提供するサービスドメイン(example-cdn.com)を利用する。
  • ユーザー コンテンツの分離。セキュリティ上の理由から、ユーザーがアップロードしたコンテンツを他のサイトのコンテンツから分離し、サンドボックス化されたドメインが認証(およびその他の)Cookie にアクセスできるように、異なるドメインのデータにアクセスする。ユーザーがアップロードした非アクティブなコンテンツを配信している場合は、ベスト プラクティスに沿って、同じドメインで安全にホストすることもできます。
  • 埋め込まれた認証済みコンテンツ。関連プロパティ全体の埋め込みコンテンツ(トップレベル サイトにログインしたユーザーに限定された動画、ドキュメント、リソース)をサポートする。
  • ログインします。関連プロパティ間でのログインをサポート。ユースケースによっては、FedCM API も適している場合があります。
  • 分析。関連プロパティ全体でユーザー ジャーニーの分析と測定を実施し、サービスの品質を向上させる。

Storage Access API

Browser Support

  • Chrome: 119.
  • Edge: 85.
  • Firefox: 65.
  • Safari: 11.1.

Source

Storage Access API(SAA)は、埋め込まれたクロスオリジン コンテンツが、通常はファーストパーティ コンテキストでのみアクセスできるストレージにアクセスできるようにする方法を提供します。

埋め込みリソースは SAA メソッドを使用して、現在ストレージにアクセスできるかどうかを確認し、ユーザー エージェントからアクセスをリクエストできます。

サードパーティ Cookie がブロックされていても、関連するウェブサイト セット(RWS)が有効になっている場合、Chrome は RWS 内のコンテキストで権限を自動的に付与します。それ以外の場合は、ユーザーにプロンプトを表示します。(「RWS 内のコンテキスト」とは、埋め込みサイトと最上位サイトが同じ RWS にある iframe などのコンテキストです)。

ストレージ アクセスを確認してリクエストする

埋め込みサイトは、現在ストレージにアクセスできるかどうかを確認するために Document.hasStorageAccess() メソッドを使用できます。

このメソッドは、ドキュメントが Cookie にすでにアクセスしているかどうかを示すブール値で解決される Promise を返します。iframe がトップフレームと同じオリジンの場合も、Promise は true を返します。

埋め込みサイトがクロスサイト コンテキストで Cookie へのアクセスをリクエストするには、Document.requestStorageAccess()(rSA)を使用します。

requestStorageAccess() API は iframe 内から呼び出すことを目的としています。その iframe は、ユーザー操作(すべてのブラウザで必須のユーザー操作)を受け取ったばかりである必要がありますが、Chrome ではさらに、過去 30 日間にユーザーがその iframe を所有するサイトにアクセスし、そのサイトを iframe ではなく最上位ドキュメントとして操作したことも必要です。

requestStorageAccess() は、ストレージへのアクセスが許可されたかどうかを解決する Promise を返します。なんらかの理由でアクセスが拒否された場合、理由を明記して Promise が拒否されます。

Chrome の requestStorageAccessFor

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.

Source

Storage Access API では、埋め込みサイトがユーザー操作を受けた <iframe> 要素内からストレージへのアクセスをリクエストすることのみが許可されます。

これにより、Cookie を必要とするクロスサイト画像やスクリプトタグを使用するトップレベルのサイトに Storage Access API を導入することが難しくなります。

この問題に対処するため、Chrome では、トップレベル サイトが Document.requestStorageAccessFor()(rSAFor)を使用して特定のオリジンに代わってストレージ アクセスをリクエストする方法を実装しています。

 document.requestStorageAccessFor('https://target.site')

requestStorageAccessFor() API は、トップレベルのドキュメントから呼び出されることになっています。また、そのドキュメントはユーザー操作を受けた直後でなければなりません。ただし、requestStorageAccess() とは異なり、ユーザーがすでにページ上にいるため、Chrome は過去 30 日間のトップレベル ドキュメントでの操作をチェックしません。

ストレージへのアクセス権限を確認する

カメラや位置情報などの一部のブラウザ機能へのアクセスは、ユーザーが付与した権限に基づいています。Permissions API を使用すると、API へのアクセス権限のステータス(権限が付与されているか、拒否されているか、プロンプトのクリックやページの操作など、なんらかのユーザー操作が必要な場合)を確認できます。

権限のステータスは navigator.permissions.query() を使用してクエリできます。

現在のコンテキストのストレージ アクセス権限を確認するには、'storage-access' 文字列を渡す必要があります。

navigator.permissions.query({name: 'storage-access'})

指定したオリジンのストレージ アクセス権限を確認するには、'top-level-storage-access' 文字列を渡す必要があります。

navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})

埋め込まれたオリジンの完全性を保護するため、ここでは document.requestStorageAccessFor を使用して最上位ドキュメントによって付与された権限のみがチェックされます。

権限を自動的に付与できるかどうか、またはユーザー操作が必要なかどうかに応じて、prompt または granted が返されます。

フレームごとのモデル

rSA の付与はフレームごとに適用されます。rSA と rSAFor の付与は、個別の権限として扱われます。

新しいフレームはそれぞれ個別にストレージへのアクセスをリクエストする必要があります。アクセス権は自動的に付与されます。最初のリクエストにのみユーザー操作が必要です。iframe によって開始される後続のリクエスト(ナビゲーションやサブリソースなど)では、最初のリクエストによってブラウジング セッションに許可されているため、ユーザー操作を待つ必要はありません。

iframe を更新、再読み込み、再作成する場合は、アクセス権を再度リクエストする必要があります。

Cookie には SameSite=None 属性と Secure 属性の両方を指定する必要があります。これは、rSA がクロスサイト コンテキストでの使用がすでにマークされている Cookie へのアクセスのみを許可するためです。

SameSite=Lax または SameSite=Strict 属性が設定されている Cookie、または SameSite 属性が設定されていない Cookie は、ファーストパーティ専用であり、rSA に関係なく、クロスサイト コンテキストで共有されることはありません。

セキュリティ

rSAFor の場合、サブリソース リクエストにはクロスオリジン リソース シェアリング(CORS)ヘッダーまたはリソースの crossorigin 属性が必要であり、明示的なオプトインが保証されます。

実装の例

埋め込まれたクロスオリジン iframe からストレージへのアクセスをリクエストする

トップレベルのサイトに埋め込まれたサイトを示す図
別のサイトの埋め込みで requestStorageAccess() を使用する。

ストレージへのアクセス権があるかどうかを確認する

ストレージへのアクセス権がすでに付与されているかどうかを確認するには、document.hasStorageAccess() を使用します。

プロミスが true に解決した場合は、クロスサイト コンテキストでストレージにアクセスできます。解決が false の場合、ストレージへのアクセスをリクエストする必要があります。

document.hasStorageAccess().then((hasAccess) => {
    if (hasAccess) {
      // You can access storage in this context
    } else {
      // You have to request storage access
    }
});

ストレージへのアクセスをリクエストする

ストレージへのアクセスをリクエストする必要がある場合は、まずストレージへのアクセス権 navigator.permissions.query({name: 'storage-access'}) をチェックして、ユーザー操作が必要な場合と自動的に付与される場合を判断します。

権限が granted の場合は、document.requestStorageAccess() を呼び出すことができます。ユーザー操作なしで成功します。

権限のステータスが prompt の場合は、ユーザーの操作(ボタンのクリックなど)後に document.requestStorageAccess() 呼び出しを開始する必要があります。

例:

navigator.permissions.query({name: 'storage-access'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSA();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSA();
    });
    document.body.appendChild(btn);
  }
});

function rSA() {
  if ('requestStorageAccess' in document) {
    document.requestStorageAccess().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

フレーム内、ナビゲーション、サブリソースからの後続のリクエストには、クロスサイト Cookie にアクセスする権限が自動的に付与されます。hasStorageAccess() が true を返すと、追加の JavaScript 呼び出しなしで、同じ関連ウェブサイト セットのクロスサイト Cookie がリクエストに送信されます。

埋め込みではなく、最上位サイト内で requestStorageAccessFor() が使用されていることを示す図
別のオリジンのトップレベル サイトで requestStorageAccessFor() を使用する

最上位サイトは requestStorageAccessFor() を使用して、特定のオリジンに代わってストレージ アクセスをリクエストできます。

hasStorageAccess() は、呼び出し元のサイトにストレージ アクセス権があるかどうかのみをチェックするため、トップレベルのサイトは別のオリジンの権限を確認できます。

ユーザーにプロンプトが表示されるかどうか、または指定されたオリジンにストレージ アクセス権がすでに付与されているかどうかを確認するには、navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'}) を呼び出します。

権限が granted の場合は、document.requestStorageAccessFor('https://target.site') を呼び出すことができます。ユーザー操作なしで成功する必要があります。

権限が prompt の場合は、ボタンのクリックなどのユーザー ジェスチャーの背後で document.requestStorageAccessFor('https://target.site') 呼び出しをフックする必要があります。

例:

navigator.permissions.query({name:'top-level-storage-access',requestedOrigin: 'https://target.site'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSAFor();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSAFor();
    });
    document.body.appendChild(btn);
  }
});

function rSAFor() {
  if ('requestStorageAccessFor' in document) {
    document.requestStorageAccessFor().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

requestStorageAccessFor() の呼び出しが成功すると、CORS または crossorigin 属性が含まれている場合、クロスサイト リクエストに Cookie が含まれるため、リクエストをトリガーする前に待機することをおすすめします。

リクエストで credentials: 'include' オプションを使用し、リソースに crossorigin="use-credentials" 属性を含める必要があります。

function checkCookie() {
    fetch('https://related-website-sets.glitch.me/getcookies.json', {
        method: 'GET',
        credentials: 'include'
      })
      .then((response) => response.json())
      .then((json) => {
      // Do something
      });
  }

ローカルでテストする方法

前提条件

関連ウェブサイト セットをローカルでテストするには、コマンドラインから起動した Chrome 119 以降を使用して、test-third-party-cookie-phaseout Chrome フラグを有効にします。

Chrome フラグを有効にする

必要な Chrome フラグを有効にするには、アドレスバーから chrome://flags#test-third-party-cookie-phaseout に移動し、フラグを Enabled に変更します。フラグを変更したら、必ずブラウザを再起動してください。

ローカルで宣言された関連ウェブサイト セットを使用して Chrome を起動するには、セットのメンバーである URL を含む JSON オブジェクトを作成し、それを --use-related-website-set に渡します。

詳しくは、フラグを使用して Chromium を実行する方法をご覧ください。

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

関連ウェブサイト セットをローカルで有効にするには、chrome://flagstest-third-party-cookie-phaseout を有効にし、セットのメンバーである URL を含む JSON オブジェクトを指定して --use-related-website-set フラグを使用してコマンドラインから Chrome を起動する必要があります。

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

クロスサイト Cookie にアクセスできることを確認する

テスト対象のサイトから API(rSA または rSAFor)を呼び出し、クロスサイト クッキーへのアクセスを検証します。

次の手順で、ドメイン間の関係を宣言し、どのサブセットに属しているかを指定します。

1. RWS を特定する

関連するドメインを特定します。これには、関連ウェブサイト セットに含めるプライマリを設定し、メンバーを設定します。また、各セットメンバーが属するサブセット タイプも特定します。

2. RWS 送信を作成する

GitHub リポジトリのローカルコピー(クローンまたはフォーク)を作成します。新しいブランチで related_website_sets.JSON ファイルを変更して、セットを反映します。セットに正しい JSON 形式と構造があることを確認するには、JSON 生成ツールを使用します。

3. RWS が技術要件を満たしていることを確認する

セットの作成要件セットの検証要件が設定されていることを確認します。

4. RWS をローカルでテストする

セットを送信するためのプルリクエスト(PR)を作成する前に、送信内容をローカルでテストして、必要なすべてのチェックに合格していることを確認します。

5. RWS を送信する

Chrome が正規の関連ウェブサイト セットのリストをホストしている related_website_sets.JSON ファイルに PR を作成して、関連ウェブサイト セットを送信します。(PR を作成するには GitHub アカウントが必要です。また、リストに貢献するには、前に投稿者ライセンス契約書(CLA)に署名する必要があります)。

PR が作成されると、CLA に署名していることや .well-known ファイルが有効であることなど、ステップ 3 の要件が満たされていることを確認するための一連のチェックが完了します。

成功すると、PR にチェックが合格したことが示されます。承認された PR は、週に 1 回(東部時間の火曜日午後 0 時)手動でバッチ処理され、正規の関連ウェブサイト セット リストに統合されます。いずれかのチェックが失敗した場合、GitHub で PR の失敗が送信者に通知されます。送信者はエラーを修正して PR を更新できます。その際、次の点に注意してください。

  • PR が失敗した場合は、エラー メッセージに送信が失敗した理由に関する追加情報が表示されます。()。
  • セットの送信を管理するすべての技術的なチェックは GitHub で行われるため、技術的なチェックが原因で送信が失敗した場合は、すべて GitHub で確認できます。

エンタープライズ ポリシー

Chrome には、エンタープライズ ユーザーのニーズを満たすための 2 つのポリシーが用意されています。

  • 関連するウェブサイト セットと統合できないシステムでは、RelatedWebsiteSetsEnabled ポリシーを使用して、Chrome のすべてのエンタープライズ インスタンスで関連するウェブサイト セット機能を無効にできます。
  • 一部の企業システムには、関連ウェブサイト セットのドメインとは異なる登録可能なドメインを持つ内部専用サイト(イントラネットなど)があります。これらのサイトを一般公開せずに関連ウェブサイト セットの一部として扱う必要がある場合(ドメインが機密情報である場合など)は、RelatedWebsiteSetsOverrides ポリシーを使用して、公開されている関連ウェブサイト セットのリストに追加またはオーバーライドできます。

Chrome は、replacemements または additions が指定されているかどうかに応じて、公開セットと Enterprise セットの交差を 2 つの方法のいずれかで解決します。

たとえば、公開用に {primary: A, associated: [B, C]} を設定します。

replacements セット: {primary: C, associated: [D, E]}
エンタープライズ セットが共通サイトを吸収して新しいセットを形成します。
結果セット: {primary: A, associated: [B]}
{primary: C, associated: [D, E]}
additions セット: {primary: C, associated: [D, E]}
公開セットとエンタープライズ セットが統合されます。
結果セット: {primary: C, associated: [A, B, D, E]}

「ユーザー プロンプト」と「ユーザー操作」

「ユーザー プロンプト」と「ユーザー操作」は異なります。同じ関連ウェブサイト セットに含まれるサイトに対して、Chrome はユーザーに権限プロンプトを表示しませんが、ユーザーがページを操作する必要があります。Chrome では、権限を付与する前にユーザー操作(「ユーザー操作」または「ユーザーの有効化」とも呼ばれます)が必要です。これは、ウェブ プラットフォームの設計原則により、関連ウェブサイトセット コンテキスト(requestStorageAccess())の外部で Storage Access API を使用する場合にもユーザー操作が必要になるためです。

他のサイトの Cookie またはストレージにアクセスする

関連するウェブサイト セットは、異なるサイトのストレージを統合しません。requestStorageAccess() 呼び出しを簡単に(プロンプトなし)行うことができます。関連するウェブサイト セットは、Storage Access API の使用によるユーザーの負担を軽減するだけであり、アクセスが復元された後の対応方法を指定するものではありません。A と B が同じ関連ウェブサイト セット内の異なるサイトであり、A が B を埋め込む場合、B は requestStorageAccess() を呼び出して、ユーザーにプロンプトを表示せずにファースト パーティ ストレージにアクセスできます。関連ウェブサイト セットはクロスサイト通信を行いません。たとえば、関連ウェブサイト セットを設定しても、B に属する Cookie が A に送信されることはありません。データを共有する場合は、B iframe から A フレームに window.postMessage を送信するなど、ご自身で共有する必要があります。

関連ウェブサイト セットでは、API を呼び出すことなく、パーティショニングされていない Cookie への暗黙的なアクセスを許可できません。クロスサイト Cookie は、セット内でデフォルトでは使用できません。関連ウェブサイト セットでは、セット内のサイトが Storage Access API の権限プロンプトをスキップできるようにするだけです。iframe が Cookie にアクセスするには、document.requestStorageAccess() を呼び出す必要があります。または、トップレベル ページが document.requestStorageAccessFor() を呼び出すこともできます。

フィードバックを共有

GitHub でセットを送信し、Storage Access API と requestStorageAccessFor API を操作することで、プロセスに関する経験や発生した問題を共有できます。

関連ウェブサイト セットに関するディスカッションに参加するには: