Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StorageAccessHandle #33391

Merged
merged 29 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
56ab95e
Add StorageAccessHandle
arichiv May 3, 2024
f05dabc
fix
arichiv May 3, 2024
34a2b75
fix
arichiv May 3, 2024
3dae799
fix
arichiv May 3, 2024
dfdcfa0
Update files/en-us/web/api/document/requeststorageaccess/index.md
arichiv May 3, 2024
47a01a7
Update files/en-us/web/api/storage_access_api/using/index.md
arichiv May 3, 2024
5e3fa9b
Update files/en-us/web/api/storage_access_api/using/index.md
arichiv May 3, 2024
cd7cad4
Update files/en-us/web/api/storage_access_api/using/index.md
arichiv May 3, 2024
ca39133
Update files/en-us/web/api/storageaccesshandle/index.md
arichiv May 3, 2024
bf60b5d
fix
arichiv May 3, 2024
f6e4023
fix
arichiv May 3, 2024
70603c5
fix
arichiv May 3, 2024
cb6d39c
fix
arichiv May 3, 2024
6d374cf
fix
arichiv May 5, 2024
c4f3492
Merge branch 'main' into patch-3
arichiv May 5, 2024
641eacc
fix
arichiv May 5, 2024
3a9456f
Merge branch 'main' into patch-3
arichiv May 6, 2024
2d43dc9
Merge branch 'main' into patch-3
arichiv May 7, 2024
275de8c
Merge branch 'main' into patch-3
arichiv May 13, 2024
05d72c4
Merge branch 'main' into patch-3
arichiv May 14, 2024
3bfe6b4
Merge branch 'main' into patch-3
arichiv May 15, 2024
5c3ef39
Merge branch 'main' into patch-3
arichiv May 16, 2024
359d1eb
Merge branch 'main' into patch-3
arichiv May 17, 2024
19c8cf6
Merge branch 'main' into patch-3
arichiv May 20, 2024
5cb0515
Merge branch 'main' into patch-3
arichiv May 21, 2024
c08b7ab
Update index.md
arichiv May 21, 2024
fc27bed
Merge branch 'main' into patch-3
arichiv May 21, 2024
d302bed
Merge branch 'main' into patch-3
arichiv May 21, 2024
934cb4a
Merge branch 'main' into patch-3
arichiv May 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 61 additions & 6 deletions files/en-us/web/api/document/requeststorageaccess/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ browser-compat: api.Document.requestStorageAccess

{{APIRef("Storage Access API")}}

The **`requestStorageAccess()`** method of the {{domxref("Document")}} interface allows content loaded in a third-party context (i.e., embedded in an {{htmlelement("iframe")}}) to request access to [third-party cookies](/en-US/docs/Web/Privacy/Third-party_cookies). This is relevant to user agents that, by default, block access to third-party, [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).
The **`requestStorageAccess()`** method of the {{domxref("Document")}} interface allows content loaded in a third-party context (i.e., embedded in an {{htmlelement("iframe")}}) to request access to [third-party cookies](/en-US/docs/Web/Privacy/Third-party_cookies) and [unpartitioned state](/en-US/docs/Web/Privacy/State_Partitioning#state_partitioning). This is relevant to user agents that, by default, block access to third-party, [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).

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"`.

Expand All @@ -18,15 +18,58 @@ To check whether permission to access third-party cookies has already been grant

```js-nolint
requestStorageAccess()
requestStorageAccess(types)
```

### Parameters

None.
- `types` {{optional_inline}}

- : An object containing properties that control what unpartitioned state is made accessible. Available properties are as follows:

- `all`
- : A boolean specifying all possible unpartitioned state should be made accessible.
If not specified the default is `false`.
- `cookies`
- : A boolean specifying third-party cookies should be made accessible.
If not specified the default is `false`.
- `sessionStorage`
- : A boolean specifying {{domxref("StorageAccessHandle.sessionStorage")}} should be made accessible.
If not specified the default is `false`.
- `localStorage`
- : A boolean specifying {{domxref("StorageAccessHandle.localStorage")}} should be made accessible.
If not specified the default is `false`.
- `indexedDB`
- : A boolean specifying {{domxref("StorageAccessHandle.indexedDB")}} should be made accessible.
If not specified the default is `false`.
- `locks`
- : A boolean specifying {{domxref("StorageAccessHandle.locks")}} should be made accessible.
If not specified the default is `false`.
- `caches`
- : A boolean specifying {{domxref("StorageAccessHandle.caches")}} should be made accessible.
If not specified the default is `false`.
- `getDirectory`
- : A boolean specifying {{domxref("StorageAccessHandle.getDirectory()")}} should be made accessible.
If not specified the default is `false`.
- `estimate`
- : A boolean specifying {{domxref("StorageAccessHandle.estimate()")}} should be made accessible.
If not specified the default is `false`.
- `createObjectURL`
- : A boolean specifying {{domxref("StorageAccessHandle.createObjectURL()")}} should be made accessible.
If not specified the default is `false`.
- `revokeObjectURL`
- : A boolean specifying {{domxref("StorageAccessHandle.revokeObjectURL()")}} should be made accessible.
If not specified the default is `false`.
- `BroadcastChannel`
- : A boolean specifying {{domxref("StorageAccessHandle.BroadcastChannel()")}} should be made accessible.
If not specified the default is `false`.
- `SharedWorker`
- : A boolean specifying {{domxref("StorageAccessHandle.SharedWorker()")}} should be made accessible.
If not specified the default is `false`.
arichiv marked this conversation as resolved.
Show resolved Hide resolved

### Return value

A {{jsxref("Promise")}} that fulfills with `undefined` if the access to third-party 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 no `types` parameter was provided, fufills with {{domxref("StorageAccessHandle")}} if the access to unpartitioned state requested by the `types` parameter was provided, 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:

Expand All @@ -36,7 +79,9 @@ A {{jsxref("Promise")}} that fulfills with `undefined` if the access to third-pa
### Exceptions

- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if the current {{domxref("Document")}} is not yet active.
- : Thrown if:
- The current {{domxref("Document")}} is not yet active.
- The `types` parameter is provided and all of its properties are `false`.
- `NotAllowedError` {{domxref("DOMException")}}
- : Thrown if:
- The document's window is not a [secure context](/en-US/docs/Web/Security/Secure_Contexts).
Expand All @@ -50,10 +95,20 @@ A {{jsxref("Promise")}} that fulfills with `undefined` if the access to third-pa
```js
document.requestStorageAccess().then(
() => {
console.log("access granted");
console.log("cookie access granted");
},
() => {
console.log("cookie access denied");
},
);

document.requestStorageAccess({ localStorage: true }).then(
(handle) => {
console.log("localStorage access granted");
handle.localStorage.setItem("foo", "bar");
},
() => {
console.log("access denied");
console.log("localStorage access denied");
},
);
```
Expand Down
24 changes: 12 additions & 12 deletions files/en-us/web/api/storage_access_api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@ browser-compat:
- api.Document.requestStorageAccess
- api.Document.requestStorageAccessFor
- api.Permissions.permission_storage-access
spec-urls: https://privacycg.github.io/storage-access/
spec-urls:
- https://privacycg.github.io/storage-access/
- https://privacycg.github.io/saa-non-cookie-storage/
---

{{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 [third-party cookies](/en-US/docs/Web/Privacy/Third-party_cookies) that it would typically 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/Privacy/Third-party_cookies) and [unpartitioned state](/en-US/docs/Web/Privacy/State_Partitioning#state_partitioning) that it would typically only have access to in a first-party context (i.e., when loaded directly in a browser tab).

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 single sign-on (SSO) with federated identity providers (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 third-party cookies and unpartitioned state to improve privacy (for example, to prevent tracking). There are legitimate uses for third-party cookies and unpartitioned state that we still want to enable, even with these default restrictions in place. Examples include single sign-on (SSO) with federated identity providers (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 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 restricting 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.
Browsers implement several storage access features and policies restricting access to third-party cookies and unpartitioned state. 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 and 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. Examples include 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 semantics around third-party cookie and unpartitioned state blocking features and 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 state 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. Examples include 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 and policies are known to break. Let's say you've got a series of different sites that provide access to different products — `heads-example.com`, `shoulders-example.com`, `knees-example.com`, and `toes-example.com`.
However, there are legitimate uses for embedded cross-site content accessing third-party cookies and unpartitioned state, which the above features and policies are known to break. Let's say you've got a series of different sites that provide access to different products — `heads-example.com`, `shoulders-example.com`, `knees-example.com`, and `toes-example.com`.

Alternatively, you might separate 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 with components embedded in all the other sites, for example, to provide SSO (`sso-example.com`) or general personalization services (`services-example.com`). These utility sites will want to share their 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 interacting with their content must significantly relax their blocking policy for resources loaded from all embedded origins and possibly across all websites.

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.
The Storage Access API is intended to solve this problem; embedded cross-site content can request unrestricted access to third-party cookies and unpartitioned state 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.

### Unpartitioned versus partitioned cookies

Expand All @@ -46,7 +46,7 @@ When we talk about third-party cookies in the context of the Storage Access API,

### 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:
Embedded content that has a legitimate need for third party cookie or unpartitioned state 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.
Expand All @@ -73,7 +73,7 @@ Several different security measures could cause a {{domxref("Document.requestSto
2. The document and top-level document must not have a `null` origin.
3. Origins that have never been interacted with as a first party do not have a notion of first-party storage. From the user's perspective, they only have a third-party relationship with that origin. Access requests are automatically denied if the browser detects that the user hasn't interacted with the embedded content in a first-party context recently (in Firefox, "recently" means within 30 days).
4. The document's window must be a [secure context](/en-US/docs/Web/Security/Secure_Contexts).
5. Sandboxed {{htmlelement("iframe")}}s cannot be granted storage access by default for security reasons. The API therefore also adds the `allow-storage-access-by-user-activation` [sandbox token](/en-US/docs/Web/HTML/Element/iframe#sandbox). The embedding website needs to add this to allow storage access requests to be successful, along with `allow-scripts` and `allow-same-origin` to allow it to execute a script to call the API and execute it in an origin that can have cookies:
5. Sandboxed {{htmlelement("iframe")}}s cannot be granted storage access by default for security reasons. The API therefore also adds the `allow-storage-access-by-user-activation` [sandbox token](/en-US/docs/Web/HTML/Element/iframe#sandbox). The embedding website needs to add this to allow storage access requests to be successful, along with `allow-scripts` and `allow-same-origin` to allow it to execute a script to call the API and execute it in an origin that can have cookies/state:

```html
<iframe
Expand Down Expand Up @@ -119,7 +119,7 @@ Documentation for Firefox's new storage access policy for blocking tracking cook
- {{domxref("Document.hasStorageAccess()")}}
- : Returns a {{jsxref("Promise")}} that resolves with a boolean value indicating whether the document has access to third-party cookies.
- {{domxref("Document.requestStorageAccess()")}}
- : Allows content loaded in a third-party context (i.e., embedded in an {{htmlelement("iframe")}}) to request access to third-party cookies; returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied.
- : Allows content loaded in a third-party context (i.e., embedded in an {{htmlelement("iframe")}}) to request access to third-party cookies and unpartitioned state; returns a {{jsxref("Promise")}} that resolves if the access was granted, and rejects if access was denied.
- {{domxref("Document.requestStorageAccessFor()")}} {{experimental_inline}}
- : A proposed extension to the Storage Access API that 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.

Expand Down