From d4f7157d0a3d4638f49394a219c3377edd6ff797 Mon Sep 17 00:00:00 2001 From: Andrew Verge Date: Tue, 21 Jan 2025 09:19:46 -0500 Subject: [PATCH 1/9] Spec: Enable get() in fenced frames with network access revoked. After script running in a fenced frame successfully resolves a call to `window.fence.disableUntrustedNetwork()`, the fenced frame gains access to Shared Storage via `get()`. This patch refactors the `get()` algorithm to be accessible from `Window` and `SharedStorageWorklet` scopes, but the `Window` branch will fail outside of a fenced frame tree with network disabled. --- spec.bs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/spec.bs b/spec.bs index 58b582b..6b3afa7 100644 --- a/spec.bs +++ b/spec.bs @@ -1632,9 +1632,16 @@ On the other hand, methods for getting data from the [=shared storage database=] The get(|key|) method steps are: 1. Let |promise| be a new [=promise=]. - 1. If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. + 1. Let |globalObject| be the [=current realm=]'s [=global object=]. + 1. Let |context| be null. + 1. If |globalObject| is a {{Window}}: + 1. Set |context| to |globalObject|'s [=Window/browsing context=]. + 1. Let |navigable| be |globalObject|'s [=Window/navigable=]. + 1. If the result of [=determining if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. + 1. Else: + 1. Set |context| to {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=]. + 1. If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. If |key|'s [=string/length=] exceeds the [=key/maximum length=], return a [=promise rejected=] with a {{TypeError}}. - 1. Let |context| be {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=]. 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. 1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}. 1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=]. From 365970afc58b1c7832f0bad6d8b7e5842301106f Mon Sep 17 00:00:00 2001 From: Andrew Verge Date: Tue, 21 Jan 2025 11:50:53 -0500 Subject: [PATCH 2/9] Add permissions policy section. --- spec.bs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec.bs b/spec.bs index b9c06a5..53d1b5a 100644 --- a/spec.bs +++ b/spec.bs @@ -1880,6 +1880,9 @@ On the other hand, methods for getting data from the [=shared storage database=] 1. Let |context| be null. 1. If |globalObject| is a {{Window}}: 1. Set |context| to |globalObject|'s [=Window/browsing context=]. + 1. Let |document| be |context|'s [=active document=]. + 1. Let |origin| be |globalObject|'s [=relevant settings object=]'s [=environment settings object/origin=]. + 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |origin| is false, [=reject=] |promise| with an {{OperationError}}. 1. Let |navigable| be |globalObject|'s [=Window/navigable=]. 1. If the result of [=determining if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. 1. Else: @@ -2392,9 +2395,14 @@ The [=obtain a lock manager=] algorithm should be prepended with the following s Permissions Policy Integration {#permission} ============================================ -This specification defines a [=policy-controlled feature=] identified by the string "shared-storage," along with a second [=policy-controlled feature=] identified by "shared-storage-select-url". +This specification defines three [=policy-controlled features=]: -"[=PermissionsPolicy/shared-storage=]" gates access to Shared Storage in general, whereas "[=shared-storage-select-url=]" adds an extra permission layer to {{SharedStorageWorklet/selectURL()}}. For each of these, the default allowlist is *. +1. "shared-storage" gates access to Shared Storage in general. +1. "shared-storage-select-url" adds an extra permission layer to {{SharedStorageWorklet/selectURL()}} +1. "fenced-unpartitioned-storage-read" adds an extra permission layer to {{SharedStorage/get()}}, to +ensure it can only be invoked successfully from a {{Window}} if the {{Promise}} returned from {{Fence/disableUntrustedNetwork()}} has [=resolved=]. + +For each of these, the default allowlist is *. Clear Site Data Integration {#clear} ==================================== From 2695c7fe735181bfc43727f74d86b0cb4613d2b3 Mon Sep 17 00:00:00 2001 From: Andrew Verge Date: Tue, 21 Jan 2025 13:44:29 -0500 Subject: [PATCH 3/9] Fixes --- spec.bs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec.bs b/spec.bs index 53d1b5a..fafe5a2 100644 --- a/spec.bs +++ b/spec.bs @@ -1880,16 +1880,18 @@ On the other hand, methods for getting data from the [=shared storage database=] 1. Let |context| be null. 1. If |globalObject| is a {{Window}}: 1. Set |context| to |globalObject|'s [=Window/browsing context=]. + 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. 1. Let |document| be |context|'s [=active document=]. - 1. Let |origin| be |globalObject|'s [=relevant settings object=]'s [=environment settings object/origin=]. + 1. Let |origin| be |context|'s [=active window=]'s [=relevant settings object=]'s [=environment settings object/origin=]. + 1. If |origin| is an [=opaque origin=], [=reject=] |promise| with an {{TypeError}}. 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |origin| is false, [=reject=] |promise| with an {{OperationError}}. - 1. Let |navigable| be |globalObject|'s [=Window/navigable=]. - 1. If the result of [=determining if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. + 1. Let |navigable| be |document|'s [=node navigable=]. + 1. If the result of running [=determine if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. 1. Else: 1. Set |context| to {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=]. + 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. 1. If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. If |key|'s [=string/length=] exceeds the [=key/maximum length=], return a [=promise rejected=] with a {{TypeError}}. - 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. 1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}. 1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=]. 1. Let |realm| be the [=current realm=]. From d89e086dd2c064507bdcd0bc78efc1546a50e0c2 Mon Sep 17 00:00:00 2001 From: Andrew Verge Date: Tue, 21 Jan 2025 13:47:21 -0500 Subject: [PATCH 4/9] Reorder addModule clause --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index fafe5a2..d401b2c 100644 --- a/spec.bs +++ b/spec.bs @@ -1888,9 +1888,9 @@ On the other hand, methods for getting data from the [=shared storage database=] 1. Let |navigable| be |document|'s [=node navigable=]. 1. If the result of running [=determine if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. 1. Else: + 1 If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. Set |context| to {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=]. 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. - 1. If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. If |key|'s [=string/length=] exceeds the [=key/maximum length=], return a [=promise rejected=] with a {{TypeError}}. 1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}. 1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=]. From 19b3e89b1d2be64171c3a7944bf6cdb1fc3a5ac8 Mon Sep 17 00:00:00 2001 From: Andrew Verge Date: Wed, 22 Jan 2025 15:01:42 -0500 Subject: [PATCH 5/9] More complete algo, doc updates --- spec.bs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/spec.bs b/spec.bs index d401b2c..b05b3b6 100644 --- a/spec.bs +++ b/spec.bs @@ -224,7 +224,8 @@ Introduction {#intro} In order to prevent cross-site user tracking, browsers are partitioning all forms of storage by [=top-level traversable=] site; see [=Client-Side Storage Partitioning=]. But, there are many [=legitimate use cases=] currently relying on unpartitioned storage. -This document introduces a new storage API that is intentionally not partitioned by [=top-level traversable=] site (though still partitioned by context origin), in order to serve a number of the use cases needing unpartitioned storage. To limit cross-site reidentification of users, data in Shared Storage may only be read in a restricted environment, called a worklet, and any output from the worklet is in the form of a [=fenced frame=] or a [=Private Aggregation=] report. Over time, there may be additional output gates included in the standard. +This document introduces a new storage API that is intentionally not partitioned by [=top-level traversable=] site (though still partitioned by context origin), in order to serve a number of the use cases needing unpartitioned storage. To limit cross-site reidentification of users, data in Shared Storage may only be read in two restricted environments. One such environment is called a worklet, and any output from the worklet is in the form of a [=fenced frame=] or a [=Private Aggregation=] report. Over time, there may be additional worklet output gates included in the standard. +The other restricted environment is a [=fenced frame=] in which {{Fence/disableUntrustedNetwork()}} has resolved successfully, which prevent the read data from being shared outside the frame.
`a.example` randomly assigns users to groups in a way that is consistent cross-site. @@ -319,6 +320,7 @@ When {{Worklet/addModule()}} is called for a worklet, it will run [=check if add - For creating a worklet, |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the module script url's [=url/origin=]. - For running operations on a worklet (from a {{Window}}), |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the worklet's [=global scopes=][0]'s [=global object/realm=]'s [=realm/settings object=]'s [=environment settings object/origin=]. - For [[#setter]], |environment| is either the current context (when called from a {{Window}}) or the [=environment settings object=] associated with the {{Window}} that created the worklet (when called from a {{SharedStorageWorkletGlobalScope}}), and |origin| is |environment|'s [=environment settings object/origin=]. + - For {{SharedStorage/get()}}, |environment| is the - For [[#ss-fetch-algo]], |environment| is the request's [=request/window=], and |origin| is the request's [=request/current URL=]'s [=url/origin=]. - For [[#ss-fetch-algo]], for {{SharedStorage/createWorklet()}} called with a cross-origin worklet script using the dataOrigin option with value `"script-origin"` (which would result in a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true), and for {{SharedStorageWorklet/selectURL()}} and {{SharedStorageWorklet/run()}} that operate on a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true, |allowedInOpaqueOriginContext| is true. For other methods, |allowedInOpaqueOriginContext| is false.
@@ -1556,11 +1558,14 @@ Methods that allow the setting and/or deleting of data are exposed to both the { Meanwhile, methods for posting operations to run inside {{SharedStorageWorkletGlobalScope}} (i.e. {{SharedStorageWorklet/selectURL()}} and {{SharedStorageWorklet/run()}}), along with the {{SharedStorage/worklet}} attribute which is used to call {{Worklet/addModule()}}, are exposed to the {{Window}} only, as these are the means by which the {{Window}} interacts with the {{SharedStorageWorklet}}. -On the other hand, methods for getting data from the [=shared storage database=] are exposed to the {{SharedStorageWorklet}} only, in order to carefully control the flow of data read from the [=shared storage database|database=]. +On the other hand, methods for getting data from the [=shared storage database=] are exposed to the {{SharedStorageWorklet}} only, in order to carefully control the flow of data read from the [=shared storage database|database=]. The only exception is that {{SharedStorage/get()}} is exposed to {{Window}}, but will only succeed if the result of the [=determine if a navigable has fully revoked network=] algorithm is true. + +Note: The [=determine if a navigable has fully revoked network=] algorithm ensures that {{SharedStorage/get()}} only succeeds for [=fenced frames=] that have successfully resolved a call to {{Fence/disableUntrustedNetwork()}}. [Exposed=(Window,SharedStorageWorklet)] interface SharedStorage { + Promise<DOMString> get(DOMString key); Promise<any> set(DOMString key, DOMString value, optional SharedStorageSetMethodOptions options = {}); @@ -1587,9 +1592,6 @@ On the other hand, methods for getting data from the [=shared storage database=] [Exposed=Window] readonly attribute SharedStorageWorklet worklet; - [Exposed=SharedStorageWorklet] - Promise<DOMString> get(DOMString key); - [Exposed=SharedStorageWorklet] Promise<unsigned long> length(); @@ -1878,22 +1880,25 @@ On the other hand, methods for getting data from the [=shared storage database=] 1. Let |promise| be a new [=promise=]. 1. Let |globalObject| be the [=current realm=]'s [=global object=]. 1. Let |context| be null. + 1. Let |environment| be null. 1. If |globalObject| is a {{Window}}: 1. Set |context| to |globalObject|'s [=Window/browsing context=]. 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. + 1. Set |environment| to |context|'s [=active window=]'s [=relevant settings object=]. + 1. Let |allowedInOpaqueOriginContext| be false. + 1. If the result of running [=determine whether shared storage is allowed by context=] given |environment|, |environment|'s [=environment settings object/origin=], and |allowedInOpaqueOriginContext| is false, [=reject=] |promise| with a {{TypeError}}. + 1. If the result of running [=check if user preference setting allows access to shared storage=] given |environment| and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with a {{TypeError}}. 1. Let |document| be |context|'s [=active document=]. - 1. Let |origin| be |context|'s [=active window=]'s [=relevant settings object=]'s [=environment settings object/origin=]. - 1. If |origin| is an [=opaque origin=], [=reject=] |promise| with an {{TypeError}}. - 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |origin| is false, [=reject=] |promise| with an {{OperationError}}. + 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with an {{OperationError}}. 1. Let |navigable| be |document|'s [=node navigable=]. 1. If the result of running [=determine if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. 1. Else: 1 If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. Set |context| to {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=]. 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. + 1. Set |environment| to |context|'s [=active window=]'s [=relevant settings object=]. 1. If |key|'s [=string/length=] exceeds the [=key/maximum length=], return a [=promise rejected=] with a {{TypeError}}. 1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}. - 1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=]. 1. Let |realm| be the [=current realm=]. 1. Let |databaseMap| be the result of running [=obtain a shared storage bottle map=] given |environment| and |realm|'s [=realm/settings object=]'s [=environment settings object/origin=]. 1. If |databaseMap| is failure, then return a [=promise rejected=] with a {{TypeError}}. From 26b3fcbeb0166a0a30e1f6f15292273102af5ffa Mon Sep 17 00:00:00 2001 From: Andrew Verge <averge@chromium.org> Date: Wed, 22 Jan 2025 15:11:47 -0500 Subject: [PATCH 6/9] Fix permissions policy build issue. --- spec.bs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec.bs b/spec.bs index b05b3b6..c977e84 100644 --- a/spec.bs +++ b/spec.bs @@ -320,7 +320,7 @@ When {{Worklet/addModule()}} is called for a worklet, it will run [=check if add - For creating a worklet, |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the module script url's [=url/origin=]. - For running operations on a worklet (from a {{Window}}), |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the worklet's [=global scopes=][0]'s [=global object/realm=]'s [=realm/settings object=]'s [=environment settings object/origin=]. - For [[#setter]], |environment| is either the current context (when called from a {{Window}}) or the [=environment settings object=] associated with the {{Window}} that created the worklet (when called from a {{SharedStorageWorkletGlobalScope}}), and |origin| is |environment|'s [=environment settings object/origin=]. - - For {{SharedStorage/get()}}, |environment| is the + - For {{SharedStorage/get()}}, |environment| is either the current context (when called from a {{Window}}) or the [=environment settings object=] associated with the active {{Window}} of the {{SharedStorageWorkletGlobalScope}}, and |origin| is |environment|'s [=environment settings object/origin=]. - For [[#ss-fetch-algo]], |environment| is the request's [=request/window=], and |origin| is the request's [=request/current URL=]'s [=url/origin=]. - For [[#ss-fetch-algo]], for {{SharedStorage/createWorklet()}} called with a cross-origin worklet script using the <var ignore=''>dataOrigin</var> option with value `"script-origin"` (which would result in a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true), and for {{SharedStorageWorklet/selectURL()}} and {{SharedStorageWorklet/run()}} that operate on a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true, |allowedInOpaqueOriginContext| is true. For other methods, |allowedInOpaqueOriginContext| is false. </div> @@ -2402,12 +2402,13 @@ The [=obtain a lock manager=] algorithm should be prepended with the following s Permissions Policy Integration {#permission} ============================================ -This specification defines three [=policy-controlled features=]: +This specification defines three [=policy-controlled features=]. -1. "<dfn for="PermissionsPolicy">shared-storage</dfn>" gates access to Shared Storage in general. -1. "<dfn for="PermissionsPolicy">shared-storage-select-url</dfn>" adds an extra permission layer to {{SharedStorageWorklet/selectURL()}} -1. "<dfn for="PermissionsPolicy">fenced-unpartitioned-storage-read</dfn>" adds an extra permission layer to {{SharedStorage/get()}}, to -ensure it can only be invoked successfully from a {{Window}} if the {{Promise}} returned from {{Fence/disableUntrustedNetwork()}} has [=resolved=]. +<dfn for="PermissionsPolicy">shared-storage</dfn>" gates access to Shared Storage in general. + +"<dfn for="PermissionsPolicy">shared-storage-select-url</dfn>" adds an extra permission layer to {{SharedStorageWorklet/selectURL()}} + +"<dfn for="PermissionsPolicy">fenced-unpartitioned-storage-read</dfn>" adds an extra permission layer to {{SharedStorage/get()}}, to ensure it can only be invoked successfully from a {{Window}} if the {{Promise}} returned from {{Fence/disableUntrustedNetwork()}} has [=resolved=]. For each of these, the default allowlist is *. From 51c71fe35794b83aece671ab6440d9c552ca69a8 Mon Sep 17 00:00:00 2001 From: Andrew Verge <averge@chromium.org> Date: Wed, 22 Jan 2025 15:21:55 -0500 Subject: [PATCH 7/9] Fix missing divs. --- spec.bs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index c977e84..57c3a57 100644 --- a/spec.bs +++ b/spec.bs @@ -1487,6 +1487,8 @@ A {{SharedStorageDeleteMethod}} has the following associated fields: 1. Set |this|'s [=SharedStorageModifierMethod/with lock=] to |options|["{{SharedStorageModifierMethodOptions/withLock}}"]. </div> + <div algorithm="SharedStorageAppendMethod"> + The <dfn constructor for="SharedStorageAppendMethod" lt="SharedStorageAppendMethod(key, value)">new SharedStorageAppendMethod(|key|, |value|, |options|)</dfn> constructor steps are: 1. Let |globalObject| be the [=current realm=]'s [=global object=]. @@ -1510,6 +1512,8 @@ A {{SharedStorageDeleteMethod}} has the following associated fields: 1. Set |this|'s [=SharedStorageModifierMethod/with lock=] to |options|["{{SharedStorageModifierMethodOptions/withLock}}"]. </div> + <div algorithm="SharedStorageDeleteMethod"> + The <dfn constructor for="SharedStorageDeleteMethod" lt="SharedStorageDeleteMethod(key)">new SharedStorageAppendMethod(|key|, |options|)</dfn> constructor steps are: 1. Let |globalObject| be the [=current realm=]'s [=global object=]. @@ -1531,6 +1535,8 @@ A {{SharedStorageDeleteMethod}} has the following associated fields: 1. Set |this|'s [=SharedStorageModifierMethod/with lock=] to |options|["{{SharedStorageModifierMethodOptions/withLock}}"]. </div> + <div algorithm="SharedStorageClearMethod"> + The <dfn constructor for="SharedStorageClearMethod" lt="SharedStorageClearMethod()">new SharedStorageClearMethod(|options|)</dfn> constructor steps are: 1. Let |globalObject| be the [=current realm=]'s [=global object=]. @@ -1547,7 +1553,7 @@ A {{SharedStorageDeleteMethod}} has the following associated fields: 1. If |databaseMap| is failure, throw a {{TypeError}}. 1. If |options|["{{SharedStorageModifierMethodOptions/withLock}}"] [=map/exists=]: 1. If |options|["{{SharedStorageModifierMethodOptions/withLock}}"] starts with U+002D HYPHEN-MINUS (-), throw a {{TypeError}}. - 1. Set |this|'s [=SharedStorageModifierMethod/with lock=] to |options|["{{SharedStorageModifierMethodOptions/withLock}}"]. + 1. Set [=this=]'s [=SharedStorageModifierMethod/with lock=] to |options|["{{SharedStorageModifierMethodOptions/withLock}}"]. </div> The {{SharedStorage}} Interface {#shared-storage-interface} From 86d8585f61c6534a299753bd6e76e1055cbc634a Mon Sep 17 00:00:00 2001 From: Andrew Verge <averge@chromium.org> Date: Thu, 23 Jan 2025 08:29:49 -0500 Subject: [PATCH 8/9] Fix preferences error and documentation sections. --- spec.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.bs b/spec.bs index 57c3a57..38d4b88 100644 --- a/spec.bs +++ b/spec.bs @@ -225,7 +225,7 @@ Introduction {#intro} In order to prevent cross-site user tracking, browsers are partitioning all forms of storage by [=top-level traversable=] site; see [=Client-Side Storage Partitioning=]. But, there are many [=legitimate use cases=] currently relying on unpartitioned storage. This document introduces a new storage API that is intentionally not partitioned by [=top-level traversable=] site (though still partitioned by context origin), in order to serve a number of the use cases needing unpartitioned storage. To limit cross-site reidentification of users, data in Shared Storage may only be read in two restricted environments. One such environment is called a worklet, and any output from the worklet is in the form of a [=fenced frame=] or a [=Private Aggregation=] report. Over time, there may be additional worklet output gates included in the standard. -The other restricted environment is a [=fenced frame=] in which {{Fence/disableUntrustedNetwork()}} has resolved successfully, which prevent the read data from being shared outside the frame. +The other restricted environment is within a [=fenced frame=]'s content after it resolves a call to {{Fence/disableUntrustedNetwork()}}, which prevents the read data from being shared outside the frame. <div class="example"> `a.example` randomly assigns users to groups in a way that is consistent cross-site. @@ -320,7 +320,7 @@ When {{Worklet/addModule()}} is called for a worklet, it will run [=check if add - For creating a worklet, |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the module script url's [=url/origin=]. - For running operations on a worklet (from a {{Window}}), |environment| is the [=environment settings object=] associated with the {{Window}} that created the worklet, and |origin| is the worklet's [=global scopes=][0]'s [=global object/realm=]'s [=realm/settings object=]'s [=environment settings object/origin=]. - For [[#setter]], |environment| is either the current context (when called from a {{Window}}) or the [=environment settings object=] associated with the {{Window}} that created the worklet (when called from a {{SharedStorageWorkletGlobalScope}}), and |origin| is |environment|'s [=environment settings object/origin=]. - - For {{SharedStorage/get()}}, |environment| is either the current context (when called from a {{Window}}) or the [=environment settings object=] associated with the active {{Window}} of the {{SharedStorageWorkletGlobalScope}}, and |origin| is |environment|'s [=environment settings object/origin=]. + - For {{SharedStorage/get()}} invoked from a {{Window}} (which can only succed in a [=fenced frame=]), |environment| is the current context, and |origin| is |environment|'s [=environment settings object/origin=]. - For [[#ss-fetch-algo]], |environment| is the request's [=request/window=], and |origin| is the request's [=request/current URL=]'s [=url/origin=]. - For [[#ss-fetch-algo]], for {{SharedStorage/createWorklet()}} called with a cross-origin worklet script using the <var ignore=''>dataOrigin</var> option with value `"script-origin"` (which would result in a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true), and for {{SharedStorageWorklet/selectURL()}} and {{SharedStorageWorklet/run()}} that operate on a worklet where [=SharedStorageWorklet/has cross-origin data origin=] is true, |allowedInOpaqueOriginContext| is true. For other methods, |allowedInOpaqueOriginContext| is false. </div> @@ -1893,7 +1893,7 @@ Note: The [=determine if a navigable has fully revoked network=] algorithm ensur 1. Set |environment| to |context|'s [=active window=]'s [=relevant settings object=]. 1. Let |allowedInOpaqueOriginContext| be false. 1. If the result of running [=determine whether shared storage is allowed by context=] given |environment|, |environment|'s [=environment settings object/origin=], and |allowedInOpaqueOriginContext| is false, [=reject=] |promise| with a {{TypeError}}. - 1. If the result of running [=check if user preference setting allows access to shared storage=] given |environment| and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with a {{TypeError}}. + 1. If the result of running [=check if user preference setting allows access to shared storage=] given |environment| and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with an {{OperationError}}. 1. Let |document| be |context|'s [=active document=]. 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with an {{OperationError}}. 1. Let |navigable| be |document|'s [=node navigable=]. @@ -2408,7 +2408,7 @@ The [=obtain a lock manager=] algorithm should be prepended with the following s Permissions Policy Integration {#permission} ============================================ -This specification defines three [=policy-controlled features=]. +This specification defines three [=policy-controlled features=] identified by the following strings: <dfn for="PermissionsPolicy">shared-storage</dfn>" gates access to Shared Storage in general. From e786201aa1db34f87cde061a3e185a7c55fbdf81 Mon Sep 17 00:00:00 2001 From: Andrew Verge <averge@chromium.org> Date: Thu, 23 Jan 2025 09:44:25 -0500 Subject: [PATCH 9/9] Fix promise rejections --- spec.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.bs b/spec.bs index 38d4b88..b1d1c0c 100644 --- a/spec.bs +++ b/spec.bs @@ -1892,12 +1892,12 @@ Note: The [=determine if a navigable has fully revoked network=] algorithm ensur 1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}. 1. Set |environment| to |context|'s [=active window=]'s [=relevant settings object=]. 1. Let |allowedInOpaqueOriginContext| be false. - 1. If the result of running [=determine whether shared storage is allowed by context=] given |environment|, |environment|'s [=environment settings object/origin=], and |allowedInOpaqueOriginContext| is false, [=reject=] |promise| with a {{TypeError}}. - 1. If the result of running [=check if user preference setting allows access to shared storage=] given |environment| and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with an {{OperationError}}. + 1. If the result of running [=determine whether shared storage is allowed by context=] given |environment|, |environment|'s [=environment settings object/origin=], and |allowedInOpaqueOriginContext| is false, return a [=promise rejected=] with a {{TypeError}}. + 1. If the result of running [=check if user preference setting allows access to shared storage=] given |environment| and |environment|'s [=environment settings object/origin=] is false, return a [=promise rejected=] with an {{OperationError}}. 1. Let |document| be |context|'s [=active document=]. - 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |environment|'s [=environment settings object/origin=] is false, [=reject=] |promise| with an {{OperationError}}. + 1. If the result of running [=Is feature enabled in document for origin?=] on "[=PermissionsPolicy/fenced-unpartitioned-storage-read=]", |document|, and |environment|'s [=environment settings object/origin=] is false, return a [=promise rejected=] with an {{OperationError}}. 1. Let |navigable| be |document|'s [=node navigable=]. - 1. If the result of running [=determine if a navigable has fully revoked network=] given |navigable| is false, [=reject=] |promise| with an {{OperationError}}. + 1. If the result of running [=determine if a navigable has fully revoked network=] given |navigable| is false, return a [=promise rejected=] with an {{OperationError}}. 1. Else: 1 If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}. 1. Set |context| to {{SharedStorage}}'s {{SharedStorageWorkletGlobalScope}}'s [=outside settings=]'s [=target browsing context=].