diff --git a/index.bs b/index.bs
index 05877bc2..745a4a3c 100644
--- a/index.bs
+++ b/index.bs
@@ -229,19 +229,36 @@ spec: RFC8941; urlPrefix: https://datatracker.ietf.org/doc/html/rfc8941#
A permissions policy is a [=struct=] with the following items: A declared policy is a [=struct=] with the following
+ [=struct/items=]: A permissions policy is a [=struct=] with the following
+ [=struct/items=]: An empty permissions policy is a permissions
policy that has an inherited policy which
- contains "Policies
-
+ : declarations
+ :: an [=ordered map=] from [=features=] to [=allowlists=]
+
+ : reporting configuration
+ :: an [=ordered map=] from [=features=] to [=strings=]
+
+
+
+
: inherited policy
:: an [=ordered map=] from [=features=] to "`Enabled`" or "`Disabled`"
: declared policy
- :: an [=ordered map=] from [=features=] to [=allowlists=]
+ :: a [=/declared policy=]
+
+
Enabled
" for every supported feature, and a declared policy which is an empty map.Enabled
" for every supported feature, a declared policy whose [=declared
+ policy/declarations=] and [=declared policy/reporting configuration=] are
+ both empty [=ordered maps=].
A policy directive is an [=ordered map=], mapping policy-controlled - features to corresponding allowlists of origins.
+ features to corresponding [=allowlists=] of origins.A policy directive is represented in HTTP headers as the serialization of an sf-dictionary structure, and in and HTML attributes as its ASCII serialization.
@@ -409,8 +426,9 @@ spec: RFC8941; urlPrefix: https://datatracker.ietf.org/doc/html/rfc8941# Dictionary. Each Dictionary Member associates a feature with an allowlist. - The Member Names must be Tokens. If a token does not name a supported - feature, then the Dictionary Member will be ignored by the processing steps. + The Member Names must be Tokens. If a token does not name one of the user + agent's [=supported features=], then the Dictionary Member will be ignored + by the processing steps. The Member Values represent allowlists, and must be one of: * a String containing the ASCII permissions-source-expression @@ -418,6 +436,9 @@ spec: RFC8941; urlPrefix: https://datatracker.ietf.org/doc/html/rfc8941# * the Token `self` * an Inner List containing zero or more of the above items. + Member Values may have a Parameter named `"report-to"`, whose value must be + a String. Any other parameters will be ignored. + Any other items inside of an Inner List will be ignored by the processing steps, and the Member Value will be processed as if they were not present. Member Values of any other form will cause the entire Dictionary Member to @@ -427,15 +448,15 @@ spec: RFC8941; urlPrefix: https://datatracker.ietf.org/doc/html/rfc8941#The `Permissions-Policy
`
+
The \`Permissions-Policy
\`
HTTP header field can be used in the [=response=] (server to client) to
communicate the permissions policy that should be enforced by the
client.
Permissions-Policy is a structured header. Its value - must be a dictionary. It's ABNF is: +
\`Permissions-Policy
\` is a structured
+ header. Its value must be a dictionary. It's ABNF is:
PermissionsPolicy = sf-dictionary@@ -671,21 +692,25 @@ partial interface HTMLIFrameElement {
The {{getAllowlistForFeature(feature)}} method must run the following steps: - 1. Set |result| to an empty list + 1. Set |result| to an empty list. 2. Let |origin| be this {{PermissionsPolicy}} object's default - origin. + origin. 3. Let |policy| be the observable policy for this - {{PermissionsPolicy}} object's associated node. + {{PermissionsPolicy}} object's associated node. 4. If |feature| is not allowed in |policy| for |origin|, return |result| - 5. Let |allowlist| be |policy|'s declared policy[|feature|] + 5. Let |allowlist| be |policy|'s [=/declared policy=][|feature|]'s + [=declared policy/declarations=]. 6. If |allowlist| is the special value `*`: 1. Append "`*`" to |result| 2. Return |result|. 7. If the allowlist's self-origin is not null, - append the serialization of it to |result| + append the serialization of it to + |result|. 8. If the allowlist's src-origin is not null, - append the serialization of it to |result| - 9. Otherwise, for each permissions-source-expression |item| in |allowlist|'s expressions: + append the serialization of it to + |result|. + 9. Otherwise, for each permissions-source-expression |item| in + |allowlist|'s expressions: 1. Append |item| to |result| 10. Return |result|. @@ -704,8 +729,10 @@ partial interface HTMLIFrameElement { |feature|, |node| and |node|'s declared origin. 2. Set |inherited policy|[|feature|] to |isInherited|. 4. Return a new permissions policy with inherited policy |inherited policy| and declared policy a new [=ordered map=]. + policy">inherited policy |inherited policy|, declared policy a [=struct=] with both + [=declared policy/declarations=] and [=declared policy/reporting + configuration=] new [=ordered maps=].
To get the declared origin for an Element |node|, run the
following steps:
@@ -786,9 +813,24 @@ partial interface HTMLIFrameElement {
resulted only in this report being generated (with no further action taken
by the user agent in response to the violation).
- Note: There is currently no mechanism in place for enabling report-only
- mode, so [=PermissionsPolicyViolationReportBody/disposition=] will always
- be set to "enforce".
+ The \` \`\``Permissions-Policy-Report-Only`\`
+ HTTP Header Field
+ Permissions-Policy-Report-Only
\`
+ HTTP header field can be used in the [=response=] (server to client) to
+ communicate a permissions policy that should not be enforced by the
+ client, but instead should be used to trigger reports to be sent if any
+ policy declared within it *would* have been violated, had the policy been
+ active.Permissions-Policy-Report-Only
\` is a
+ structured header. Its value must be a dictionary.
+
+ The semantics of the dictionary are defined in
+ [[#structured-header-serialization]].
+
+ The processing steps are defined in [[#algo-construct-policy]].
+
Permissions-Policy-Report-Only
" if
+ |report-only| is True, or "Permissions-Policy
" otherwise.
1. Let |parsed header| be the result of executing get a structured
- field value given "Permissions-Policy
" and "dictionary" from
- |response|’s header list.
+ field value given |header name| and "dictionary" from |response|’s
+ [=response/header list=].
1. If |parsed header| is null, return an empty [=ordered map=].
1. Let |policy| be the result of executing Construct policy from
dictionary and origin on |parsed header| and |origin|.
@@ -815,13 +859,16 @@ partial interface HTMLIFrameElement {
Disabled
", return "Disabled
".
1. If |feature| is present in |policy|'s declared
policy:
- 1. If the allowlist for |feature| in |policy|'s declared policy matches |origin|, then return
- "Enabled
".
+ 1. If |policy|'s declared
+ policy's [=declared policy/declarations=][|feature|]
+ matches |origin|, then return "Enabled
".
1. Otherwise return "Disabled
".
1. Return "Enabled
".
Disabled
" if |feature| should be considered
- disabled, and "Enabled
" otherwise.
- 1. Let |policy| be |document|'s [=Document/permissions policy=].
+ ## Check permissions policy ## {#algo-check-permissions-policy}
+
+ Disabled
" if
+ |feature| should be considered disabled, and "Enabled
"
+ otherwise.
1. If |policy|'s inherited policy for
|feature| is "Disabled
", return "Disabled
".
- 1. If |feature| is present in |policy|'s declared
- policy:
- 1. If the allowlist for |feature| in |policy|'s declared policy matches |origin|, then return
- "Enabled
".
+ 1. If |feature| is present in |policy|'s declared policy:
+ 1. If |policy|'s declared
+ policy's [=declared policy/declarations=][|feature|]
+ matches |origin|, then return "Enabled
".
1. Otherwise return "Disabled
".
1. If |feature|'s default allowlist is *
, return
"Enabled
".
1. If |feature|'s default allowlist is 'self'
, and
- |origin| is [=same origin=] with |document|'s [=Document/origin=], return
+ |origin| is [=same origin=] with |document origin|, return
"Enabled
".
1. Return "Disabled
".
Disabled
"
+ if |feature| should be considered disabled, and "Enabled
"
+ otherwise. If |report| is True, then it will also [=generate and queue a
+ report=] if the feature is not enabled in either |document|'s
+ [=Document/permissions policy=] or |document|'s [=Document/report-only
+ permissions policy=]
+
+ Note: The default value of True for |report| means that most permissions
+ policy checks will generate a violation report if the feature is not
+ enabled. This is the expected result, as most checks are for an actual
+ attempted use of the feature. If a call to this algorithm is performed just
+ to query the state of a feature, and does not represent an actual attempt to
+ use the feature, then |report| should be set to False.
+
+ 1. Let |policy| be |document|'s [=Document/permissions policy=].
+ 1. Let |report-only policy| be |document|'s [=Document/report-only
+ permissions policy=].
+ 1. Let |result| be the result of calling Check permissions
+ policy, given |policy|,
+ |feature|, |origin|, and |document|'s [=Document/origin=].
+ 1. Let |report-only result| be the result of calling Check
+ permissions policy, given |report-only policy|, |feature|, |origin|,
+ and |document|'s [=Document/origin=].
+ 1. If |report| is True:
+ 1. Let |settings| be |document|'s environment settings object.
+ 1. If |result| is "Disabled
":
+ 1. Let |endpoint| be the result of calling Get the
+ reporting endpoint for a feature given |feature| and
+ |policy|.
+ 1. Call Generate report for violation of permissions
+ policy on settings given |feature|, |settings|,
+ "Enforce
", and |endpoint|.
+ 1. Else, if |report-only result| is "Disabled
":
+ 1. Let |report-only endpoint| be the result of calling Get the reporting endpoint for a feature given
+ |feature| and |report-only policy|.
+ 1. Call Generate report for violation of permissions
+ policy on settings given |feature|, |settings|,
+ "Report
", and |report-only endpoint|.
+ 1. Return result
+
+ The permanent message header field registry should be updated with the