Related Website Sets

Warning: This feature is currently opposed by two browser vendors. See the Standards positions section below for details of opposition.

Related website sets are a mechanism for defining a set of related sites that share trusted content. As a result, browsers will grant default access for these sites to third-party cookies when they have content embedded in other set members.

Concepts and usage

Let's consider situations where you have a series of related websites with different domain names, and you want to give site content access to third-party cookies when loaded in a third-party context inside other related sites (i.e., embedded in an <iframe>). Typical use cases are:

  • App sites: A single application may be deployed over multiple sites, aiming to allow users to navigate between them seamlessly in a single session.
  • Brand sites: A set of brand assets may be contained in a single site but then deployed over multiple domains, including session data relating to user preferences, customization, etc.

Third-party cookie access is commonly blocked by browser cookie-blocking policies. Still, you can work around it using the Storage Access API — see Using the Storage Access API for details.

Related website are a progressive enhancement mechanism that works alongside the Storage Access API. Supporting browsers grant third-party cookie access between websites in the same set without having to go through the usual user permission prompt workflow, once Document.requestStorageAccess() (or Document.requestStorageAccessFor()) is called. This results in a more user-friendly experience for users of sites in the set.

You should bear in mind that:

How does RWS work?

A related website set consists of one primary site and up to five associated sites.

JSON structure

A set is represented by a JSON structure. A hypothetical example is as follows:

json
{
  "sets": [
    {
      "contact": "email address or group alias if available",
      "primary": "https://primary1.com",
      "associatedSites": [
        "https://associateA.com",
        "https://associateB.com",
        "https://associateC.com"
      ],
      "serviceSites": ["https://servicesiteA.com"],
      "rationaleBySite": {
        "https://associateA.com": "Explanation of affiliation with primary site",
        "https://associateB.com": "Explanation of affiliation with primary site",
        "https://associateC.com": "Explanation of affiliation with primary site",
        "https://serviceSiteA.com": "Explanation of service functionality support"
      },
      "ccTLDs": {
        "https://associateA.com": [
          "https://associateA.ca",
          "https://associateA.co.uk"
        ],
        "https://associateB.com": [
          "https://associateB.ru",
          "https://associateB.co.kr"
        ],
        "https://primary1.com": ["https://primary1.co.uk"]
      }
    }
  ]
}

Note: The affiliation explanations must include a clear description of how the affiliation to the primary site is presented to users of those sites.

To use a set, its JSON must be added to the related_website_sets.JSON file available on the Related Website Sets GitHub repository, which Chrome then consumes to get the list of sets to apply RWS behavior to.

.well-known files

Each site in the set must also serve a .well-known file at /.well-known/related-website-set.json, which serves to verify the set structure and the relationship between the sites in the set.

The primary site's .well-known file must explicitly list out the full set structure. https://primary1.com in the above example would need a https://primary1.com/.well-known/related-website-set.json file similar to the following:

json
{
  "primary": "https://primary1.com",
  "associatedSites": [
    "https://associateA.com",
    "https://associateB.com",
    "https://associateC.com"
  ],
  "serviceSites": ["https://servicesiteA.com"],
  "rationaleBySite": {
    "https://associateA.com": "Explanation of affiliation with primary site",
    "https://associateB.com": "Explanation of affiliation with primary site",
    "https://associateC.com": "Explanation of affiliation with primary site",
    "https://serviceSiteA.com": "Explanation of service functionality support"
  },
  "ccTLDs": {
    "https://associateA.com": [
      "https://associateA.ca",
      "https://associateA.co.uk"
    ],
    "https://associateB.com": [
      "https://associateB.ru",
      "https://associateB.co.kr"
    ],
    "https://primary1.com": ["https://primary1.co.uk"]
  }
}

Each associate and service site needs to specify its primary site in a .well-known file. Each non-primary site in the above example (e.g. https://associateA.com) would need a /.well-known/related-website-set.json file like this:

json
{
  "primary": "https://primary1.com"
}

For full details of the process, JSON syntax, and other requirements for submitting sets, see the submission guidelines. Only domain administrators can create a set containing their sites.

Bear in mind that the .well-known files are also verified as part of the submission process, so they need to be put in place before the associated set is submitted.

Active set benefits

Once a set is active:

  • Requests from sites in the set (via Document.requestStorageAccess()) to access third-party cookies that belong to sites in the set are automatically granted, and no user permission step is required.
  • Document.requestStorageAccessFor() calls can be made from top-level sites in the set to request third-party cookie access for other sites in the set.

RWS security

RWS has been designed with security in mind. It would be disastrous if a bad actor site were able to claim to be part of a set and gain the privileges that entails. Lets consider a theoretical bad actor site, evilsite.example.com, and look at some examples of attacks it could try to make, all of which would fail:

  • evilsite.example.com claims to be an associated site in another set: If a site claiming to be in a set (i.e. by listing a primary in a .well-known file) is not included in the set submission and/or primary's .well-known file, it won't get the benefits of being in the set.
  • evilsite.example.com claims to be a primary site, and submits a set that includes some would-be victim sites: The submission process requires that .well-known files hosted by non-primary sites explicitly list out their primary. If this primary doesn't match the set submission (i.e. if the associated/service sites expect to have a different primary, or don't expect to be in a set at all), the submission will be rejected.
  • site1.example.com and site2.example.com are intentionally in the same set, but site1.example.com gets hijacked by evilsite.example.com: The impact of a site hijacking attack within a set isn't any worse than it would usually be, once the other sites are updated accordingly:
    • The regular Storage Access API requires an active opt-in by the embedded site, so site2.example.com can stop calling document.requestStorageAccess() when it's embedded in site1.example.com, avoiding a CSRF attack.
    • Use of requestStorageAccessFor() requires CORS, so site2.example.com could choose not to respond with the appropriate CORS headers when network requests are coming from site1.example.com, thereby avoiding a CSRF attack.

Examples

Specifications

Specification
User Agent Interaction with Related Website Sets

Standards positions

Two browser vendors oppose this specification. Known positions are as follows:

See also