From ae48e0a576800042371ed6cf95750d9cd0036cee Mon Sep 17 00:00:00 2001 From: Chris Mills Date: Fri, 24 Nov 2023 13:13:12 +0000 Subject: [PATCH 01/57] Related website sets docs --- .../en-us/web/api/storage_access_api/index.md | 76 +++++++++++------- .../related_website_sets/index.md | 77 +++++++++++++++++++ files/en-us/web/http/cookies/index.md | 8 +- files/en-us/web/privacy/index.md | 6 +- .../web/privacy/partitioned_cookies/index.md | 2 - files/en-us/web/security/index.md | 2 +- files/jsondata/GroupData.json | 8 +- 7 files changed, 139 insertions(+), 40 deletions(-) create mode 100644 files/en-us/web/api/storage_access_api/related_website_sets/index.md diff --git a/files/en-us/web/api/storage_access_api/index.md b/files/en-us/web/api/storage_access_api/index.md index 58e4b037061a256..3804e699e0bbe08 100644 --- a/files/en-us/web/api/storage_access_api/index.md +++ b/files/en-us/web/api/storage_access_api/index.md @@ -5,51 +5,63 @@ page-type: web-api-overview browser-compat: - api.Document.hasStorageAccess - api.Document.requestStorageAccess + - api.Permissions.permission_storage-access +spec-urls: https://privacycg.github.io/storage-access/ --- {{DefaultAPISidebar("Storage Access API")}} -The Storage Access API provides a way for cross-site content loaded in a third-party context (i.e. embedded in an {{htmlelement("iframe")}}) to gain access to _unpartitioned cookies_ that it would normally only have access to in a first-party context (i.e. when loaded directly in a browser tab). +The Storage Access API provides a way for cross-site content loaded in a third-party context (i.e. embedded in an {{htmlelement("iframe")}}) to gain access to [third-party cookies](/en-US/docs/Web/HTTP/Cookies#third-party_cookies) that it would normally only have access to in a first-party context (i.e. when loaded directly in a browser tab). -> **Note:** When we say _unpartitioned cookies_, we are talking about cookies stored in the traditional way they have historically been stored since the early web — all cookies set on the same site are stored in the same cookie jar. This is in contrast to _partitioned cookies_, where embedded resources under each top-level site are given a unique cookie storage space (see for example [Cookies Having Independent Partitioned State (CHIPS)](/en-US/docs/Web/Privacy/Partitioned_cookies)). +The Storage Access API is relevant to user agents that by default block access to third-party cookies to improve privacy (for example, to prevent tracking). There are legitimate uses for third-party cookies that we still want to enable, even with these default restrictions in place. Examples include SSO with federated IdPs, or persisting user details such as location data or viewing preferences across different sites. -The Storage Access API is relevant to user agents that by default block access to unpartitioned cookies by sites loaded in a third-party context to improve privacy (for example, to prevent tracking). There are legitimate uses for unpartitioned cookie access by third-party content that we still want to enable, even with these default restrictions in place. Examples include SSO with federated IdPs, or persisting user details such as location data or viewing preferences across different sites. - -The API provides methods that allow embedded resources to check whether they currently have access to unpartitioned cookies and, if not, to request access from the user agent. +The API provides methods that allow embedded resources to check whether they currently have access to third-party cookies and, if not, to request access from the user agent. > **Note:** The _Storage Access API_ name may seem like somewhat of a misnomer, given that it only provides access to cookies, and not other client-side storage mechanisms such as {{domxref("Web_Storage_API", "Web Storage", "", "nocode")}} or {{domxref("IndexedDB_API", "IndexedDB", "", "nocode")}}. The name has been kept generic because it may provide access to other forms of client-side storage in the future. ## Concepts and usage -Browsers implement several storage access features and policies that restrict access to unpartitioned cookies by embedded, cross-site resources. These range from giving embedded resources under each top-level origin a unique cookie storage space (_partitioned cookies_), to outright blocking of cookie access when resources are loaded in a third-party context. +Browsers implement several storage access features and policies that restrict access to third-party cookies. These range from giving embedded resources under each top-level origin a unique cookie storage space ([partitioned cookies](#unpartitioned_versus_partitioned_cookies)), to outright blocking of cookie access when resources are loaded in a third-party context. + +The semantics around third-party cookie blocking features/policies differ from browser to browser, but the core functionality is similar: cross-site resources embedded in a third-party context are not given access to the same cookies that they would have access to when loaded in a first-party context. This is done with good intent — browser vendors want to take steps to better protect their user's privacy and security, for example leaving them less open to having their activity tracked across different sites, and less vulnerable to exploits such as cross-site request forgery ({{glossary("CSRF")}}). + +However, there are legitimate uses for embedded cross-site content accessing third-party cookies, which the above features/policies are known to break. Let's say you've got a series of different sites that provide users with access to different products — `heads-example.com`, `shoulders-example.com`, `knees-example.com`, and `toes-example.com`. + +> **Note:** Alternatively, you might choose to separate out your content or services into different country domains for localization purposes — `example.com`, `example.ua`, `example.br`, etc. — or in some other way. + +You might have accompanying utility sites that have components embedded in all the other sites, for example to provide Single Sign-On (`sso-example.com`) or general personalization services (`services-example.com`). These utility sites will want to share state with the sites they are embedded in via cookies. They cannot share first-party cookies because they are on different domains, and third-party cookies will no longer work in browsers that block them. + +In such situations, site owners often encourage users to add their site as an exception or to disable third-party cookie blocking policies entirely. Users who wish to continue to interact with their content are forced to greatly relax their blocking policy for resources loaded from all embedded origins and possibly across all websites. -The semantics around unpartitioned cookie blocking features/policies differ from browser to browser, but the core functionality is similar: cross-site resources embedded in a third-party context are not given access to the same cookies that they would have access to when loaded in a first-party context. This is done with good intent — browser vendors want to take steps to better protect their user's privacy and security, for example leaving them less open to having their activity tracked across different sites, and less vulnerable to exploits such as cross-site request forgery ({{glossary("CSRF")}}). +The Storage Access API is intended to solve this problem; embedded cross-site content can request unrestricted access to third-party cookies on a frame-by-frame basis, via the {{domxref("Document.requestStorageAccess()")}} method. It can also check whether it already has access via the {{domxref("Document.hasStorageAccess()")}} method. -However, there are legitimate uses for embedded cross-site content accessing unpartitioned cookies, which the above features/policies are known to break. As an example, federated logins often require access to authentication cookies, and will require the user to sign in on each site separately (or completely break) if those cookies are not available. As a result, site owners often encourage users to add their site as an exception or to disable such policies entirely. Users who wish to continue to interact with embedded content are forced to greatly relax their blocking policy for resources loaded from all embedded origins and possibly across all websites. +### Unpartitioned versus partitioned cookies -The Storage Access API is intended to solve this problem; embedded cross-site content can request unrestricted access to unpartitioned cookies on a frame-by-frame basis, for a particular top-level embedding site, via the {{domxref("Document.requestStorageAccess()")}} method. It can also check whether it already has access via the {{domxref("Document.hasStorageAccess()")}} method. +It is important to note that the Storage Access API is only needed to provide access to _unpartitioned_ third-party cookies. This means cookies stored in the traditional way they have historically been stored since the early web — all cookies set on the same site are stored in the same cookie jar. This is in contrast to _partitioned_ cookies, where embedded resources under each top-level site are given a unique cookie storage space, thereby making tracking users across sites via cookies impossible. -## How it works +Browsers have various mechanisms to partition third party cookie access, for example [Firefox Total Cookie Protection](https://blog.mozilla.org/products/firefox/firefox-rolls-out-total-cookie-protection-by-default-to-all-users-worldwide/) and [Cookies Having Independent Partitioned State (CHIPS)](/en-US/docs/Web/Privacy/Partitioned_cookies). -As explained above, modern browsers implement various features and policies to restrict or block access to unpartitioned cookies by embedded content. Such content that has a legitimate need for cookie access can get around this problem using the Storage Access API as follows: +When we talk about third-party cookies in the content of the Storage Access API, we implicitly mean _unpartitioned_ third-party cookies. + +### How it works + +Embedded content that has a legitimate need for third party cookie access can request access using the Storage Access API as follows: 1. It can call the {{domxref("Document.hasStorageAccess()")}} method to check whether it has the access it needs already. 2. If not, it can request access via the {{domxref("Document.requestStorageAccess()")}} method. 3. Depending on the browser, the user will be asked whether to grant access to the requesting embed in slightly different ways. - Safari shows prompts for all embedded content that has not previously received storage access. - Firefox only prompts users after an origin has requested storage access on more than a threshold number of sites. - - At the time of writing, Chrome doesn't prompt the user. Instead, it only resolves `requestStorageAccess()` calls that come from domains within a [first-party set](https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/). This behavior will change as the implementation is developed further. -4. Access is granted or denied based on whether the content meets all the security requirements (see [Security measures](#security_measures), below). The {{jsxref("Promise")}}-based nature of `requestStorageAccess()` allows you to run code to handle success and failure cases. - - Modern spec behavior dictates that access is granted **per-frame** — every separate content embed has its unpartitioned cookie access blocked by default, and needs to call `requestStorageAccess()` to opt-in to access. If a content embed has received access, and same-site embeds then call `requestStorageAccess()`, their promises will fulfill automatically. But they still need to opt-in. - - In older versions of the spec, the access was **per-page**. As soon as one embed received unpartitioned cookie access via `requestStorageAccess()`, all other same-site embeds would automatically receive access. This was not desirable behavior from a security standpoint — for example, if `shop.example.com` embedded `locator.users.com` to allow users to use their location info while shopping, and `locator.users.com` called `requestStorageAccess()`, `shop.example.com` and any other sites it embeds would be able to access its cookies, but also access cookies from `private.users.com`, which is not intended to be embedded. [Read more about the motivations](https://github.com/privacycg/storage-access/issues/113) behind this change. - - Consult the [Browser compatibility information](#browser_compatibility) to see which browsers implement which behavior. + - Chrome shows prompts for all embedded content that has not previously received storage access, but it will automatically grant access and skip prompts if the embedded content and embedding site are part of the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). +4. Access is granted or denied based on whether the content meets all the security requirements — see [Security measures](#security_measures) for general requirements, and [Browser-specific variations](#browser-specific_variations) for some browser-specific security requirements. The {{jsxref("Promise")}}-based nature of `requestStorageAccess()` allows you to run code to handle success and failure cases. + - Modern spec behavior dictates that access is granted **per-frame** — every separate content embed has its third-party cookie access blocked by default, and needs to call `requestStorageAccess()` to opt-in to access. If a content embed has received access, and same-site embeds then call `requestStorageAccess()`, their promises will fulfill automatically. But they still need to opt-in. + - In older versions of the spec, the access was **per-page** (Safari is the only browser that still uses this model). As soon as one embed received third-party cookie access via `requestStorageAccess()`, all other same-site embeds would automatically receive access. This was not desirable behavior from a security standpoint — for example, if `shop.example.com` embedded `locator.users.com` to allow users to use their location info while shopping, and `locator.users.com` called `requestStorageAccess()`, `shop.example.com` and any other sites it embeds would be able to access its cookies, but also access cookies from `private.users.com`, which is not intended to be embedded. [Read more about the motivations](https://github.com/privacycg/storage-access/issues/113) behind this change. 5. Once access is granted, a permission key is stored in the browser with the structure ``. For example, if the embedding site is `embedder.com`, and the embed is `locator.example.com`, the key would be ``. Same-site embeds (`docs.example.com`, `profile.example.com`, etc.) would then be able to call `requestStorageAccess()` and the promise would fulfill automatically, as mentioned earlier. - Older versions of the spec used the more specific permission key structure ``, which meant that same-site, cross-origin embeds didn't match the permission key and had to go through the whole process separately. - - At the time of writing, only Chromium browsers had implemented the new behavior. > **Note:** The only exception to the "blocked by default" behavior is when a content embed makes a successful `requestStorageAccess()`, but then performs a same-origin navigation (for example reloading itself). In such cases, the storage access is carried over from the previous navigation. -> **Note:** In cases where a top-level site has its cookies partitioned (for example via [CHIPS](/en-US/docs/Web/Privacy/Partitioned_cookies) or [Total Cookie Protection](https://blog.mozilla.org/en/mozilla/firefox-androids-new-privacy-feature-total-cookie-protection-stops-companies-from-keeping-tabs-on-your-moves/)), the Storage Access API isn't required, as sharing the cookies by default has no privacy risk. +> **Note:** In cases where a top-level site has its cookies [partitioned](#unpartitioned_versus_partitioned_cookies), the Storage Access API isn't required, as sharing the cookies by default has no privacy risk. ## Security measures @@ -73,19 +85,22 @@ Several different security measures could cause a {{domxref("Document.requestSto ``` 6. Usage of this feature may be blocked by a {{httpheader("Permissions-Policy/storage-access", "storage-access")}} [Permissions Policy](/en-US/docs/Web/HTTP/Permissions_Policy) set on your server. -7. At the time of writing, Chrome only resolves `requestStorageAccess()` calls that come from domains within a [first-party set](https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/). This restriction is intended to be relaxed as the implementation is developed further. > **Note:** The document may also be required to pass additional browser-specific checks. Examples: allowlists, blocklists, on-device classification, user settings, anti-[clickjacking](/en-US/docs/Glossary/Clickjacking) heuristics, or prompting the user for explicit permission. -## Browser storage access policy variations +## Browser-specific variations -Although the API surface is the same, websites using the Storage Access API should expect differences in the level and extent of unpartitioned cookie access they receive between different browsers, due to differences in their storage access policies. +Although the API surface is the same, websites using the Storage Access API should expect differences in the level and extent of third-party cookie access they receive between different browsers, due to differences in their storage access policies. -### Firefox +### Chrome -Design properties unique to Firefox are summarized here: +- Cookies must have [`SameSite=None`](/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) explicitly set on them, because the default value for Chrome is `SameSite=Lax` (`SameSite=None` is the default in Firefox and Safari). +- Cookies must have the [`Secure`](/en-US/docs/Web/HTTP/Headers/Set-Cookie#secure) attribute set on them. +- The storage access grants are phased out after 30 days of browser usage passed without user interaction. Successful use of the Storage Access API extends this limit by another 30 days. + +### Firefox -- If the embedded origin `tracker.example` has already obtained unpartitioned cookie access on the top-level origin `foo.example`, and the user visits a page from `foo.example` embedding a page from `tracker.example` again in less than 30 days, the embedded origin will have unpartitioned cookie access immediately when loading. +- If the embedded origin `tracker.example` has already obtained third-party cookie access on the top-level origin `foo.example`, and the user visits a page from `foo.example` embedding a page from `tracker.example` again in less than 30 days, the embedded origin will have third-party cookie access immediately when loading. - The storage access grants are phased out after 30 calendar days have passed. Documentation for Firefox's new storage access policy for blocking tracking cookies includes [a detailed description](/en-US/docs/Web/Privacy/Storage_Access_Policy#storage_access_grants) of the scope of storage access grants. @@ -96,21 +111,24 @@ Documentation for Firefox's new storage access policy for blocking tracking cook ## Examples -See [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for an implementation guide with code examples. +- See [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for an implementation guide with code examples. +- See [Storage Access API Demo](https://storage-access-api-demo.glitch.me/) for a live demo. ## API methods - {{domxref("Document.hasStorageAccess()")}} - - : Returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to unpartitioned cookies. + - : Returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to third-party cookies. - {{domxref("Document.requestStorageAccess()")}} - - : Returns a {{jsxref("Promise")}} that resolves if the access to unpartitioned cookies was granted, and rejects if access was denied. + - : Requests access to third-party cookies from embedded content; returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. +- {{domxref("Document.requestStorageAccessFor()")}} {{non-standard_inline}} + - : Allows top-level sites to request third-party cookie access on behalf of embedded origin content originating from another site in the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). Returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. -> **Note:** User interaction propagates to the promise returned by both of these methods, allowing the callers to take actions that require user interaction without requiring a second click from the user. For example, a caller could open a pop-up window from the resolved promise without triggering Firefox's pop-up blocker. +> **Note:** User interaction propagates to the promise returned by these methods, allowing the callers to take actions that require user interaction without requiring a second click from the user. For example, a caller could open a pop-up window from the resolved promise without triggering Firefox's pop-up blocker. ### Additions to other APIs - {{domxref("Permissions.query()")}} - - : You can call `Permissions.query()` with a value of `"storage-access"` to query whether unpartitioned cookie access has been granted in general, i.e. to another same-site embed. If so, you can call `requestStorageAccess()` without user interaction, and the promise will resolve automatically. + - : You can call `Permissions.query()` with a value of `"storage-access"` to query whether third-paty cookie access has been granted in general, i.e. to another same-site embed. If so, you can call `requestStorageAccess()` without user interaction, and the promise will resolve automatically. ## Specifications diff --git a/files/en-us/web/api/storage_access_api/related_website_sets/index.md b/files/en-us/web/api/storage_access_api/related_website_sets/index.md new file mode 100644 index 000000000000000..d21b14851859482 --- /dev/null +++ b/files/en-us/web/api/storage_access_api/related_website_sets/index.md @@ -0,0 +1,77 @@ +--- +title: Related Website Sets +slug: Web/API/Storage_Access_API/Related_website_sets +page-type: guide +status: + - experimental +browser-compat: api.document.requestStorageAccessFor +spec-urls: https://wicg.github.io/first-party-sets/ +--- + +{{QuicklinksWithSubPages("Web/Privacy")}} + +> **Warning:** One or more browser vendors oppose this feature — in its current state, it will never be implemented across all browsers. See [Standards positions](#standards_positions) and [Browser compatibility](#browser_compatibility) for details of opposition and support status. + +Related website sets is 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](/en-US/docs/Web/HTTP/Cookies#third-party_cookies) in situations where they have content embedded in other members of the set. + +## 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 {{htmlelement("iframe")}}). A typical use case is federated sign-in. A separate site handling Single-Sign-On (SSO) will be embedded in multiple sites that require sign-in functionality. The SSO site will typically require access to third-party authentication cookies, and will require the user to sign in on each site separately (or completely break) if those cookies are not available. + +Third-party cookie access is increasingly commonly blocked by browser cookie blocking policies, but you can work around it using the Storage Access API — see [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for details. + +Related website sets can be considered a progressive enhancement mechanism that works alongside the Storage Access API — supporting browsers grant **default** third-party cookie access between websites in the same set. This means **without** having to go through the usual user permission prompt workflow, meaning a more user-friendly experience for users of sites in the set. + +In addition: + +- The Chrome-only {{domxref("Document.requestStorageAccessFor()")}} method — which allows top-level sites to request storage access on behalf of embedded origin content — is only supported on domains within a related website set. See [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for an example. +- When Chrome first supported the Storage Access API, it required calling sites to be part of a related website set, however this is no longer the case. + +## How does RWS work? + +A related website set consists of one primary domain and up to five associated domains, which are represented in a JSON structure like the following: + +```json +{ + "primary": "https://primary.com", + "associatedSites": [ + "https://associate1.com", + "https://associate2.com", + "https://associate3.com" + ] +} +``` + +To use a set, it must be added to the `related_website_sets.JSON` file available on the [Related Website Sets GitHub repository](https://github.com/GoogleChrome/related-website-sets/blob/main/related_website_sets.JSON), which Chrome then consumes to get the list of sets to apply RWS behavior to. + +To find out about the process and requirements for submitting sets, see the [submission guidelines](https://github.com/GoogleChrome/related-website-sets/blob/main/RWS-Submission_Guidelines.md). Only domain administrators can create a set containing that domain. + +Once a set is active: + +- Requests from sites in the set (via {{domxref("Document.requestStorageAccess()")}}) to access third party cookies that belong to sites in the set are automatically granted, and no user permission step is required. +- {{domxref("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. + +## Examples + +- The [Related Website Sets demo](https://related-website-sets.glitch.me/) demonstrates how RWS is used. +- Also see [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using). + +## Specifications + +{{Specifications}} + +### Standards positions + +One or more vendors oppose this specification. Known positions are as follows: + +- Mozilla (Firefox): [Negative](https://mozilla.github.io/standards-positions/#first-party-sets) +- Apple (Safari): [Negative](https://webkit.org/standards-positions/#position-93) + +## Browser compatibility + +{{Compat}} + +## See also + +- [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) +- [Related Website Sets](https://developer.chrome.com/docs/privacy-sandbox/related-website-sets/) on developer.chrome.com (2023) diff --git a/files/en-us/web/http/cookies/index.md b/files/en-us/web/http/cookies/index.md index 6cb490d48344d85..376946af2d9b1f2 100644 --- a/files/en-us/web/http/cookies/index.md +++ b/files/en-us/web/http/cookies/index.md @@ -198,9 +198,11 @@ A cookie is associated with a particular domain and scheme (such as `http` or `h If the cookie domain and scheme match the current page, the cookie is considered to be from the same site as the page, and is referred to as a _first-party cookie_. If the domain and scheme are different, the cookie is not considered to be from the same site, and is referred to as a _third-party cookie_. -While the server hosting a web page sets first-party cookies, the page may contain images or other components stored on servers in other domains (for example, ad banners) that may set third-party cookies. -These are mainly used for advertising and tracking across the web. -For example, the [types of cookies used by Google](https://policies.google.com/technologies/types). +While the server hosting a web page sets first-party cookies, the page may contain components stored on servers in other domains, such as images or other documents embedded in {{htmlelement("iframe")}}s. These components may set third-party cookies. + +Typical use cases for third-party cookies include sharing user profile information or collecting analytics across different related domains. They are also often used for advertising and tracking users across the web. + +> **Note:** See the [types of cookies used by Google](https://policies.google.com/technologies/types). A third-party server can create a profile of a user's browsing history and habits based on cookies sent to it by the same browser when accessing multiple sites. Firefox, by default, blocks third-party cookies that are known to contain trackers. diff --git a/files/en-us/web/privacy/index.md b/files/en-us/web/privacy/index.md index 6a4c59dbfd542df..bc5eee4c27d2975 100644 --- a/files/en-us/web/privacy/index.md +++ b/files/en-us/web/privacy/index.md @@ -125,8 +125,8 @@ Some of the most developed parts of the privacy sandbox project are as follows: - [Cookies Having Independent Partitioned State (CHIPS)](/en-US/docs/Web/Privacy/Partitioned_cookies) - : Also known as **partitioned cookies**, CHIPs allows developers to opt a cookie into partitioned storage, with a separate cookie jar per top-level site. -- [First-party sets](https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/) - - : A mechanism for a company to declare relationships between different origins. Supporting browsers will then allow limited third-party cookie access across those origins for specific purposes. +- [Related website sets](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets) + - : A mechanism for a company to declare relationships between different origins. Supporting browsers will then allow limited third-party cookie access across those origins for specific purposes, via the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API). - Third-party cookie default - : Chrome does not yet block third-party cookies by default, but this can be set by users in Chrome settings. @@ -203,7 +203,7 @@ Earlier on we discussed tracking, and some of the unethical purposes they are us Also recall from earlier that browsers are implementing a number of technologies to limit the usage of tracking cookies, especially cross-site cookies, with the eventual aim of removing them altogether. It is a good idea to prepare for this, by limiting the amount of tracking activities you rely on, and/or implementing desired information persistence in other ways. For example: - Use an alternative client-side storage mechanism such as [Web Storage](/en-US/docs/Web/API/Web_Storage_API) to persist data. This does have the downside that the data is stored per-origin, so it can't be shared. -- Use a technology such as [IFrame credentialless](/en-US/docs/Web/Security/IFrame_credentialless), [First-party sets](https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/) and/or the [Storage access API](/en-US/docs/Web/API/Storage_Access_API) to allow your sites to opt in to using cross-site cookies in a safe, controlled way, or block them altogether. These currently have limited browser support. +- Use a technology such as [IFrame credentialless](/en-US/docs/Web/Security/IFrame_credentialless) or the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) to allow your sites to opt in to using cross-site cookies in a safe, controlled way, or block them altogether. - Use a server-side solution for data persistence. > **Note:** To reiterate what we said earlier, make sure you clearly communicate to your users what you are doing via your privacy policy, allow them to opt-in, and easily delete their data if they change their mind at a later date. diff --git a/files/en-us/web/privacy/partitioned_cookies/index.md b/files/en-us/web/privacy/partitioned_cookies/index.md index 64e7b14e5f89eeb..0ee0a3b4e0587b3 100644 --- a/files/en-us/web/privacy/partitioned_cookies/index.md +++ b/files/en-us/web/privacy/partitioned_cookies/index.md @@ -54,8 +54,6 @@ Blocking all third-party cookies would currently be problematic, for example in 2. The storage key for the cookie would be `{("https://shoppy.example"), ("3rd-party.example/chat")}`. 3. The user visits various subdomains in the quest to solve their problem that also embed `https://3rd-party.example/chat`, including `https://support.shoppy.example` and `https://checkout.shoppy.example`. The new embedded instances are able to access the cookie because the partition key still matches. -> **Note:** [First-party sets](https://github.com/WICG/first-party-sets) is a proposal that aims to allow site owners to declare a collection of related domains that will act like they are a single top-level site, for the purposes of cookie access mechanisms like CHIPS. - ## Specifications {{Specifications}} diff --git a/files/en-us/web/security/index.md b/files/en-us/web/security/index.md index 394fdf09ebdc7ac..33a0a3312a77a1e 100644 --- a/files/en-us/web/security/index.md +++ b/files/en-us/web/security/index.md @@ -92,7 +92,7 @@ You should prepare for the removal of cross-site cookies by limiting the amount For example: - Use an alternative client-side storage mechanism such as the [Web Storage API](/en-US/docs/Web/API/Web_Storage_API) to persist data. Web storage does have the downside that the data is stored per-origin, so it can't be shared. Note that web storage has two variants — `sessionStorage` and `localStorage`. We would recommend using `sessionStorage` for extra security, as data only persists for the lifetime of the window or tab it exists in. `localStorage` data persists even after the window or tab is closed and reopened. This means that there is a higher chance of it falling into the wrong hands, for example on a shared workstation. -- Use a technology such as [IFrame credentialless](/en-US/docs/Web/Security/IFrame_credentialless), [First-party sets](https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/) and/or the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) to allow your sites to opt-in to using cross-site cookies in a safe and controlled way or block them altogether. These technologies currently have limited browser support. +- Use a technology such as [IFrame credentialless](/en-US/docs/Web/Security/IFrame_credentialless) or the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) to allow your sites to opt-in to using cross-site cookies in a safe and controlled way or block them altogether. - Use a server-side solution for data persistence. See our [privacy guide](/en-US/docs/Web/Privacy) and particularly [Cut down on tracking cookies](/en-US/docs/Web/Privacy#cut_down_on_tracking_cookies) for more context around this. diff --git a/files/jsondata/GroupData.json b/files/jsondata/GroupData.json index 8524f5686485cf3..5e658a07039f762 100644 --- a/files/jsondata/GroupData.json +++ b/files/jsondata/GroupData.json @@ -1298,11 +1298,15 @@ }, "Storage Access API": { "overview": ["Storage Access API"], - "guides": ["/docs/Web/API/Storage_Access_API/Using"], + "guides": [ + "/docs/Web/API/Storage_Access_API/Using", + "/docs/Web/API/Storage_Access_API/Related_website_sets" + ], "interfaces": [], "methods": [ "Document.hasStorageAccess()", - "Document.requestStorageAccess()" + "Document.requestStorageAccess()", + "Document.requestStorageAccessFor()" ], "properties": [], "events": [] From 7a00819c719af37f2d3daef8f6eec3e13a6c9c5a Mon Sep 17 00:00:00 2001 From: Chris Mills Date: Mon, 27 Nov 2023 10:06:07 +0000 Subject: [PATCH 02/57] Rest of required content --- .../api/document/hasstorageaccess/index.md | 9 +- .../document/requeststorageaccess/index.md | 9 +- .../document/requeststorageaccessfor/index.md | 99 +++++++++++++++++++ files/en-us/web/api/permissions_api/index.md | 4 +- .../en-us/web/api/storage_access_api/index.md | 7 +- .../related_website_sets/index.md | 11 +-- .../web/api/storage_access_api/using/index.md | 92 +++++++++++++++-- 7 files changed, 204 insertions(+), 27 deletions(-) create mode 100644 files/en-us/web/api/document/requeststorageaccessfor/index.md diff --git a/files/en-us/web/api/document/hasstorageaccess/index.md b/files/en-us/web/api/document/hasstorageaccess/index.md index 3ac71359508e0c3..b2d3b8353863b27 100644 --- a/files/en-us/web/api/document/hasstorageaccess/index.md +++ b/files/en-us/web/api/document/hasstorageaccess/index.md @@ -8,7 +8,7 @@ browser-compat: api.Document.hasStorageAccess {{APIRef("Storage Access API")}} -The **`hasStorageAccess()`** method of the {{domxref("Document")}} interface returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to unpartitioned cookies. +The **`hasStorageAccess()`** method of the {{domxref("Document")}} interface returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to [third-party cookies](/en-US/docs/Web/HTTP/Cookies#third-party_cookies), [unpartitioned](/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies) cookies. This method is part of the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API). @@ -24,12 +24,12 @@ None. ### Return value -A {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to unpartitioned cookies — `true` if it does, and `false` if not. +A {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to third-party cookies — `true` if it does, and `false` if not. The result returned by this method can be inaccurate in a couple of circumstances: -1. The user may have browser settings active that block unpartitioned cookies entirely — in this case `true` may be returned even though unpartitioned cookies are still inaccessible. To handle such a situation, you should gracefully handle any errors resulting in cookie values being unretrievable; for example, inform the user that access to their personalized settings is blocked and invite them to sign in again to use them. -2. The browser might not block third-party cookie access by default — in this case `false` may be returned even though unpartitioned cookies are accessible, and storage access wouldn't need to be requested (i.e. via {{domxref("Document.requestStorageAccess()")}}). To get around this issue, you could query {{domxref("Document.cookie")}} to find out whether your cookies are accessible, and call {{domxref("Document.requestStorageAccess()")}} if they are not. +1. The user may have browser settings active that block third-party cookies entirely — in this case `true` may be returned even though third-party cookies are still inaccessible. To handle such a situation, you should gracefully handle any errors resulting in cookie values being unretrievable; for example, inform the user that access to their personalized settings is blocked and invite them to sign in again to use them. +2. The browser might not block third-party cookie access by default — in this case `false` may be returned even though third-party cookies are accessible, and storage access wouldn't need to be requested (i.e. via {{domxref("Document.requestStorageAccess()")}}). To get around this issue, you could query {{domxref("Document.cookie")}} to find out whether your cookies are accessible, and call {{domxref("Document.requestStorageAccess()")}} if they are not. > **Note:** If the promise gets resolved and a user gesture event was being processed when the function was originally called, the resolve handler will run as if a user gesture was being processed, so it will be able to call APIs that require user activation. @@ -63,5 +63,6 @@ document.hasStorageAccess().then((hasAccess) => { ## See also +- {{domxref("Document.requestStorageAccess()")}}, {{domxref("Document.requestStorageAccessFor()")}} - [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) - [Introducing Storage Access API](https://webkit.org/blog/8124/introducing-storage-access-api/) (WebKit blog) diff --git a/files/en-us/web/api/document/requeststorageaccess/index.md b/files/en-us/web/api/document/requeststorageaccess/index.md index 4fcb7225b83256b..244120b4eefc6a9 100644 --- a/files/en-us/web/api/document/requeststorageaccess/index.md +++ b/files/en-us/web/api/document/requeststorageaccess/index.md @@ -8,12 +8,14 @@ browser-compat: api.Document.requestStorageAccess {{APIRef("Storage Access API")}} -The **`requestStorageAccess()`** method of the {{domxref("Document")}} interface allows a document loaded in a third-party context (i.e. embedded in an {{htmlelement("iframe")}}) to request access to unpartitioned cookies. +The **`requestStorageAccess()`** method of the {{domxref("Document")}} interface allows a document loaded in a third-party context (i.e. embedded in an {{htmlelement("iframe")}}) to request access to third-party cookies. -This is relevant to user agents that by default block access to unpartitioned cookies by sites loaded in a third-party context to improve privacy (e.g. to prevent tracking), and is part of the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API). +This is relevant to user agents that by default block access to [third-party cookies](/en-US/docs/Web/HTTP/Cookies#third-party_cookies), [unpartitioned](/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies) cookies to improve privacy (e.g. to prevent tracking), and is part of the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API). > **Note:** Usage of this feature may be blocked by a {{httpheader("Permissions-Policy/storage-access", "storage-access")}} [Permissions Policy](/en-US/docs/Web/HTTP/Permissions_Policy) set on your server. In addition, the document must pass additional browser-specific checks such as allowlists, blocklists, on-device classification, user settings, anti-[clickjacking](/en-US/docs/Glossary/Clickjacking) heuristics, or prompting the user for explicit permission. +> **Note:** To check whether permission to access third-party cookies has already been granted, you can call {{domxref("Permissions.query()")}}, specifying the feature name `"storage-access"`. + ## Syntax ```js-nolint @@ -26,7 +28,7 @@ None. ### Return value -A {{jsxref("Promise")}} that fulfills with `undefined` if the access to unpartitioned cookies was granted, and rejects if access was denied. +A {{jsxref("Promise")}} that fulfills with `undefined` if the access to third-party cookies was granted, and rejects if access was denied. `requestStorageAccess()` requests are automatically denied unless the embedded content is currently processing a user gesture such as a tap or click ({{Glossary("transient activation")}}), or unless permission was already granted previously. If permission was not previously granted, they need to be run inside a user gesture-based event handler. The user gesture behavior depends on the state of the promise: @@ -70,5 +72,6 @@ document.requestStorageAccess().then( ## See also +- {{domxref("Document.hasStorageAccess()")}}, {{domxref("Document.requestStorageAccessFor()")}} - [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) - [Introducing Storage Access API](https://webkit.org/blog/8124/introducing-storage-access-api/) (WebKit blog) diff --git a/files/en-us/web/api/document/requeststorageaccessfor/index.md b/files/en-us/web/api/document/requeststorageaccessfor/index.md new file mode 100644 index 000000000000000..6c322c791b2fe02 --- /dev/null +++ b/files/en-us/web/api/document/requeststorageaccessfor/index.md @@ -0,0 +1,99 @@ +--- +title: "Document: requestStorageAccessFor() method" +short-title: requestStorageAccessFor() +slug: Web/API/Document/requestStorageAccessFor +page-type: web-api-instance-method +status: + - experimental +browser-compat: api.Document.requestStorageAccessFor +--- + +{{APIRef("Storage Access API")}}{{seecompattable}} + +The **`requestStorageAccessFor()`** method of the {{domxref("Document")}} interface allows top-level sites to request third-party cookie access on behalf of embedded content originating from another site in the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). It Returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. + +This is intended to address challenges in adopting the Storage Access API on top-level sites that use cross-site images or {{htmlelement("script")}} elements requiring cookies. + +`requestStorageAccessFor()` is relevant to user agents that by default block access to [third-party cookies](/en-US/docs/Web/HTTP/Cookies#third-party_cookies), [unpartitioned](/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies) cookies to improve privacy (e.g. to prevent tracking), and is part of the [Storage Access API](/en-US/docs/Web/API/Storage_Access_API). + +> **Note:** To check whether permission to access third-party cookies has already been granted via `requestStorageAccessFor()`, you can call {{domxref("Permissions.query()")}}, specifying the feature name `"top-level-storage-access"`. Note that this is different to the feature name used for the regular {{domxref("Document.requestStorageAccess()")}} method, which is `"storage-access"`. + +## Syntax + +```js-nolint +requestStorageAccessFor(requestedOrigin) +``` + +### Parameters + +- `requestedOrigin` + - : A string representing the URL of the origin you are requesting third-party cookie access for. + +### Return value + +A {{jsxref("Promise")}} that fulfills with `undefined` if the access to third-party cookies was granted, and rejects if access was denied. + +`requestStorageAccessFor()` requests are automatically denied unless the embedded content is currently processing a user gesture such as a tap or click ({{Glossary("transient activation")}}), or unless permission was already granted previously. If permission was not previously granted, they need to be run inside a user gesture-based event handler. The user gesture behavior depends on the state of the promise: + +- If the promise resolves (i.e. if permission was granted), then the user gesture has not been consumed, so the script can subsequently call APIs that require a user gesture. +- If the promise rejects (i.e. permission was not granted), then the user gesture has been consumed, so the script can't do anything that requires a gesture. This is intentional protection against abuse — it prevents scripts from calling `requestStorageAccessFor()` in a loop until the user accepts the prompt. + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the current {{domxref("Document")}} is not yet active. +- `NotAllowedError` {{domxref("DOMException")}} + - : Thrown if: - The document's window is not a [secure context](/en-US/docs/Web/Security/Secure_Contexts). - The document or the top-level document has a `null` origin. - The top-level site and embedded site are not in the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). - The embedding {{htmlelement("iframe")}} is sandboxed, and the `allow-storage-access-by-user-activation` token is not set. - Usage is denied by the user agent's permission request to use the API. + `TypeError` + - : Thrown if `requestedOrigin` is not a valid URL. + +## Examples + +```js +function rSAFor() { + if ("requestStorageAccessFor" in document) { + document.requestStorageAccessFor("https://example.com").then( + (res) => { + // Use storage access + doThingsWithCookies(); + }, + (err) => { + // Handle errors + }, + ); + } +} +``` + +After a successful `requestStorageAccessFor()` call, cross-site requests will include cookies if they include [CORS](/en-US/docs/Web/HTTP/CORS) / [`crossorigin`](/en-US/docs/Web/HTML/Attributes/crossorigin), so sites may want to wait before triggering a request. Such requests must use the [`credentials: 'include'`](/en-US/docs/Web/API/fetch#credentials) option and resources must include the `crossorigin="use-credentials"` attribute. + +For example: + +```js +function checkCookie() { + fetch("https://example.com/getcookies.json", { + method: "GET", + credentials: "include", + }) + .then((response) => response.json()) + .then((json) => { + // Do something + }); +} +``` + +> **Note:** See [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for a more complete example. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("Document.hasStorageAccess()")}}, {{domxref("Document.requestStorageAccess()")}} +- [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) +- [Introducing Storage Access API](https://webkit.org/blog/8124/introducing-storage-access-api/) (WebKit blog) diff --git a/files/en-us/web/api/permissions_api/index.md b/files/en-us/web/api/permissions_api/index.md index 58290b938e0952b..ed0c057091d7651 100644 --- a/files/en-us/web/api/permissions_api/index.md +++ b/files/en-us/web/api/permissions_api/index.md @@ -40,7 +40,7 @@ A non-exhaustive list of permission-aware APIs includes: - [Payment Handler API](/en-US/docs/Web/API/Payment_Handler_API): `payment-handler` - [Push API](/en-US/docs/Web/API/Push_API): `push` - [Sensor APIs](/en-US/docs/Web/API/Sensor_APIs): `accelerometer`, `gyroscope`, `magnetometer`, `ambient-light-sensor` -- [Storage Access API](/en-US/docs/Web/API/Storage_Access_API): `storage-access` +- [Storage Access API](/en-US/docs/Web/API/Storage_Access_API): `storage-access`, `top-level-storage-access` - [Storage API](/en-US/docs/Web/API/Storage_API): `persistent-storage` - [Web Audio Output Devices API](/en-US/docs/Web/API/Audio_Output_Devices_API): `speaker-selection` - [Web MIDI API](/en-US/docs/Web/API/Web_MIDI_API): `midi` @@ -48,7 +48,7 @@ A non-exhaustive list of permission-aware APIs includes: ## Examples -We have made a simple example available called Location Finder. You can [run the example live](https://chrisdavidmills.github.io/location-finder-permissions-api/), or [view the source code on GitHub](https://github.com/chrisdavidmills/location-finder-permissions-api/tree/gh-pages). +We have created a simple example called Location Finder. You can [run the example live](https://chrisdavidmills.github.io/location-finder-permissions-api/), or [view the source code on GitHub](https://github.com/chrisdavidmills/location-finder-permissions-api/tree/gh-pages). Read more about how it works in our article [Using the Permissions API](/en-US/docs/Web/API/Permissions_API/Using_the_Permissions_API). diff --git a/files/en-us/web/api/storage_access_api/index.md b/files/en-us/web/api/storage_access_api/index.md index 3804e699e0bbe08..59398113e00e2cb 100644 --- a/files/en-us/web/api/storage_access_api/index.md +++ b/files/en-us/web/api/storage_access_api/index.md @@ -5,6 +5,7 @@ page-type: web-api-overview browser-compat: - api.Document.hasStorageAccess - api.Document.requestStorageAccess + - api.Document.requestStorageAccessFor - api.Permissions.permission_storage-access spec-urls: https://privacycg.github.io/storage-access/ --- @@ -96,7 +97,7 @@ Although the API surface is the same, websites using the Storage Access API shou - Cookies must have [`SameSite=None`](/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) explicitly set on them, because the default value for Chrome is `SameSite=Lax` (`SameSite=None` is the default in Firefox and Safari). - Cookies must have the [`Secure`](/en-US/docs/Web/HTTP/Headers/Set-Cookie#secure) attribute set on them. -- The storage access grants are phased out after 30 days of browser usage passed without user interaction. Successful use of the Storage Access API extends this limit by another 30 days. +- The storage access grants are phased out after 30 days of browser usage passed without user interaction. Successful use of the Storage Access API extends this limit by another 30 days. This doesn't occur when {{domxref("requestStorageAccessFor()")}} is called because the user is already on the page. ### Firefox @@ -120,8 +121,8 @@ Documentation for Firefox's new storage access policy for blocking tracking cook - : Returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to third-party cookies. - {{domxref("Document.requestStorageAccess()")}} - : Requests access to third-party cookies from embedded content; returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. -- {{domxref("Document.requestStorageAccessFor()")}} {{non-standard_inline}} - - : Allows top-level sites to request third-party cookie access on behalf of embedded origin content originating from another site in the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). Returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. +- {{domxref("Document.requestStorageAccessFor()")}} {{experimental_inline}} + - : Allows top-level sites to request third-party cookie access on behalf of embedded content originating from another site in the same [related website set](/en-US/docs/Web/API/Storage_Access_API/Related_website_sets). Returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied. > **Note:** User interaction propagates to the promise returned by these methods, allowing the callers to take actions that require user interaction without requiring a second click from the user. For example, a caller could open a pop-up window from the resolved promise without triggering Firefox's pop-up blocker. diff --git a/files/en-us/web/api/storage_access_api/related_website_sets/index.md b/files/en-us/web/api/storage_access_api/related_website_sets/index.md index d21b14851859482..1979d669232198c 100644 --- a/files/en-us/web/api/storage_access_api/related_website_sets/index.md +++ b/files/en-us/web/api/storage_access_api/related_website_sets/index.md @@ -8,9 +8,9 @@ browser-compat: api.document.requestStorageAccessFor spec-urls: https://wicg.github.io/first-party-sets/ --- -{{QuicklinksWithSubPages("Web/Privacy")}} +{{DefaultAPISidebar("Storage Access API")}} -> **Warning:** One or more browser vendors oppose this feature — in its current state, it will never be implemented across all browsers. See [Standards positions](#standards_positions) and [Browser compatibility](#browser_compatibility) for details of opposition and support status. +> **Warning:** One or more browser vendors oppose this feature — in its current state, it will never be implemented across all browsers. See [Standards positions](#standards_positions) for details of opposition. Related website sets is 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](/en-US/docs/Web/HTTP/Cookies#third-party_cookies) in situations where they have content embedded in other members of the set. @@ -25,7 +25,7 @@ Related website sets can be considered a progressive enhancement mechanism that In addition: - The Chrome-only {{domxref("Document.requestStorageAccessFor()")}} method — which allows top-level sites to request storage access on behalf of embedded origin content — is only supported on domains within a related website set. See [Using the Storage Access API](/en-US/docs/Web/API/Storage_Access_API/Using) for an example. -- When Chrome first supported the Storage Access API, it required calling sites to be part of a related website set, however this is no longer the case. +- When Chrome first supported the standard Storage Access API (i.e. {{domxref("Document.hasStorageAccess()")}} and {{domxref("Document.requestStorageAccess()")}}), it required calling sites to be part of a related website set, however this is no longer the case. ## How does RWS work? @@ -67,11 +67,8 @@ One or more vendors oppose this specification. Known positions are as follows: - Mozilla (Firefox): [Negative](https://mozilla.github.io/standards-positions/#first-party-sets) - Apple (Safari): [Negative](https://webkit.org/standards-positions/#position-93) -## Browser compatibility - -{{Compat}} - ## See also - [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) - [Related Website Sets](https://developer.chrome.com/docs/privacy-sandbox/related-website-sets/) on developer.chrome.com (2023) +- [Related Website Sets: developer guide](https://developer.chrome.com/docs/privacy-sandbox/related-website-sets-integration/) on developer.chrome.com (2023) diff --git a/files/en-us/web/api/storage_access_api/using/index.md b/files/en-us/web/api/storage_access_api/using/index.md index c20834c2d1d347e..cd4ee0243dd78e2 100644 --- a/files/en-us/web/api/storage_access_api/using/index.md +++ b/files/en-us/web/api/storage_access_api/using/index.md @@ -6,13 +6,15 @@ page-type: guide {{DefaultAPISidebar("Storage Access API")}} -The [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) can be used by embedded cross-site documents to verify whether they have access to unpartitioned cookies and, if not, to request access. We'll briefly look at a common storage access scenario. +The [Storage Access API](/en-US/docs/Web/API/Storage_Access_API) can be used by embedded cross-site documents to verify whether they have access to [third-party cookies](/en-US/docs/Web/HTTP/Cookies#third-party_cookies) cookies and, if not, to request access. We'll briefly look at a common storage access scenario. + +> **Note:** When we talk about third-party cookies in the content of the Storage Access API, we implicitly mean [_unpartitioned_](/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies) third-party cookies. ## Usage notes -The Storage Access API is designed to allow embedded content to request access to unpartitioned cookies — most modern browsers block such access by default to protect user privacy. Since embedded content won't know what a browser's behavior is going to be in this regard, it's best to always check whether the embedded {{htmlelement("iframe")}} has storage access before attempting to read or write a cookie. This is particularly true for {{domxref("Document.cookie")}} access, as browsers will often return an empty cookie jar when third-party cookie access is blocked. +The Storage Access API is designed to allow embedded content to request access to third-party cookies — most modern browsers block such access by default to protect user privacy. Since embedded content won't know what a browser's behavior is going to be in this regard, it's best to always check whether the embedded {{htmlelement("iframe")}} has storage access before attempting to read or write a cookie. This is particularly true for {{domxref("Document.cookie")}} access, as browsers will often return an empty cookie jar when third-party cookie access is blocked. -In the example below, we show how an embedded cross-site {{htmlelement("iframe")}} can access unpartitioned cookies under a browser storage access policy that blocks third-party cookie access. +In the example below, we show how an embedded cross-site {{htmlelement("iframe")}} can access third-party cookies under a browser storage access policy that would otherwise block access to them. ## Allowing a sandboxed \