Skip to content

Commit

Permalink
Start being more consistent with definitions (#371)
Browse files Browse the repository at this point in the history
This change updates a number of definitions in the document policy spec, replacing the term "feature" in many places with the maybe-still-too-vague "configuration point", clarifies that 'values' are part of a policy configuration, while 'default values', 'ranges' and 'types' are part of the definition of a configuration point, and more clearly shows that 'directives' are part of the structured-header serialization, rather than being part of the 'policy' concept.

Starts addressing #369
  • Loading branch information
clelland authored Apr 15, 2020
1 parent 34c7d56 commit 1e35db6
Showing 1 changed file with 148 additions and 127 deletions.
275 changes: 148 additions & 127 deletions document-policy.bs
Original file line number Diff line number Diff line change
Expand Up @@ -138,53 +138,65 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
# Framework # {#framework}

<section>
## Features ## {#features}
## Configuration Points ## {#configuration-points}

A <dfn export data-lt="document policy feature">feature</dfn> is
defined by
A <dfn export>configuration point</dfn> is a Web Platform API or behaviour
which can be enabled, diabled, or configured through Document Policy.
Configuration points should be defined in the specification which describes
the underlying API or behaviour, although there is a registry of defined
configuration points in use attached to this document.

* A name, which is a token,
* A value type, which is either `boolean`, `integer`, `float`, or `enum`,
* A value range, which is a subset of the possible values for the feature's
type, and
* A <dfn>default value</dfn>, which is an element of the feature's value
range.
* A <dfn>requires acknowledgment</dfn> flag, which is either `yes` or `no`.
A <a>configuration point</a> has a <dfn
for="configuration point">name</dfn>, which is a token.

A <a>configuration point</a> has a <dfn
for="configuration point">type</dfn>, which is one of:
* `boolean`,
* `integer`,
* `float`, or
* `enum`.

A <a>configuration point</a> has a <dfn
for="configuration point">range</dfn>, which is a subset of all values for
its <a for="configuration point">type</a>.

A <a>configuration point</a> has a <dfn
for="configuration point">default value</dfn>, which is an element of its
<a for="configuration point">range</a>.

A <a>configuration point</a> has a <dfn
for="configuration point">requires acknowlegement</dfn> flag, which is
either `yes` or `no`.

A <a>configuration point</a> which has <a
for="configuration point">type</a> `integer` or `float` also has a <a
for="configuration point">parameter name</a>, which is a token, which must
be a valid param-name.

<div class="issue">Should configuration points be allowed to have multiple
parameters? Perhaps parameters should be defined separately, with names,
types, and ranges.</div>

<div class="informative">
When introducing a new feature, the default value should be chosen
When introducing a new configuration point, the <a
for="configuration point">default value</a> and <a
for="configuration point">requires acknowlegment</a> flag should be chosen
carefully, with highest consideration given to web compatibility. When no
explicit policy has been declared for a document, the default value will be
in effect.
</div>
</section>
<section>
### Directives ### {#directives}

A <dfn export data-lt="document policy directive">directive</dfn> is an
element of a <a>document policy</a>, and consists of a <a>directive name</a>
and optional parameters.

A <dfn>directive name</dfn> may be one of:

* A <a>document policy feature</a> name,
* A <a>document policy feature</a> name, prefixed by "no-", if it is the
name of a boolean feature, or
* The token "`*`".

Directive parameters are defined per-directive.
</section>
<section>
## Policies ## {#policies}

A <dfn>document policy</dfn> is an ordered map from <a
data-lt="policy-controlled feature">features</a> to <a>policy
configurations</a>
A <dfn>document policy</dfn> is an ordered map from <a>configuration
points</a> to <a>policy configurations</a>

A <dfn>policy configuration</dfn> is a tuple consisting of a <dfn
for="policy configuration">value</dfn> and a <dfn
for="policy configuration">reporting endpoint</dfn>, which is a string, and
which may be null.
for="policy configuration">value</dfn>, which is an element of the
<a>configuration point</a>'s <a for="configuration point">range</a>, and a
<dfn for="policy configuration">reporting endpoint</dfn>, which is a string,
and which may be null.

A <a>browsing context</a> has a <dfn>required document policy</dfn>, which
is a <a>document policy</a>. A <a>browsing context</a> with a null <a>opener
Expand All @@ -199,20 +211,6 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
A <a>Document</a> has a <dfn>report-only document policy</dfn>, which is a
<a>document policy</a>.
</section>
<section>
## Values ## {#values}

* Policies have values for features
* Values have domains
* Domains have ordering
* Examples: positive ints, floats, bools, enums
</section>
<section>
## Default Values ## {#default-values}

* features have default values.
* (Non-normative) Defaults are chosen for web compatibility.
</section>
</section>

<section>
Expand Down Expand Up @@ -312,16 +310,21 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/

A document policy can be a "report-only" policy. Report-only policies are
specified with a `Document-Policy-Report-Only` header. Violations of a
report-only policy are reported on, exactly as an enforcing policy, but they
do not cause any other action to be taken by the user agent.
report-only policy will cause a report to be generated, as the enforcing
policy would, but they do not cause any other action to be taken by the user
agent.


Document-Policy-Report-Only

The `report-to` directive parameter should be used with directives in this
header, or else they will have no effect at all.

Document-Policy-Report-Only: something;f=1.0;report-to=endpoint, no-something-else;report-to=endpoint2
Example:
```
Document-Policy-Report-Only: something;f=1.0;report-to=endpoint,
no-something-else;report-to=endpoint2
```
</section>

</section>
Expand All @@ -332,46 +335,56 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
## Policies as Structured Headers ## {#policies-as-structured-headers}

Policies are represented in HTTP headers and in HTML attributes as the
serialization of an sh-list structure. The list members are tokens, each
corresponding to a <dfn>policy directive</dfn>. Each token may take a single
parameter; the details of the parameter name and allowed values are
determined by the value type of the feature which the token names.

### Boolean-valued features ### {#boolean-valued-features}
serialization of an sh-list structure. The list members are parameterized
tokens, each of which is a <a>document policy directive</a>.

Boolean-valued features do not take any parameters. They may be expressed in
headers by simply naming them, to enable the feature, or naming them with a
prefix of 'no-', to disable the feature.
A <dfn export>document policy directive</dfn> is an element of a
<a>serialized document policy</a>, and consists of a <a>directive name</a>,
which is an sh-token, and associated <a
for="document policy directive">parameters</a>.

Examples:
* `boolean-feature`
* `no-boolean-feature`
A <dfn>directive name</dfn> may be one of:

### Integer-valued features ### {#integer-valued-features}
* The <a for="configuration point">name</a> of a <a>configuration point</a>.
* The <a for="configuration point">name</a> of <a>configuration point</a>
whose <a for="configuration point">type</a> is `boolean`, prefixed by the
string "no-",
* The Token "`*`".

Integer-valued features should have a single parameter, whose name is
defined by the feature, and whose value should be an Integer. The range of
Integers allowed should be defined by the feature.
A <dfn>policy value</dfn> is an element of the <a for="configuration point">range</a>
for the named <a>configuration point</a>.
</section>

Examples:
* `integer-feature;p=2`
### Parameters ### {#document-policy-directive-parameters}

### Float-valued features ### {#float-valued-features}
Any <a>document policy directive</a> may include a parameter named
`report-to`, whose value must be a string.

Float-valued features should have a single parameter, whose name is defined
by the feature, and whose value should be a Float. The range of Floats
allowed should be defined by the feature.
A <a>document policy directive</a> whose <a>directive name</a> names a
<a>configuration point</a> with <a>type</a> `boolean` has no required
parameters.

Examples:
* `float-feature;q=-0.2`
A <a>document policy directive</a> whose <a>directive name</a> names a
<a>configuration point</a> with <a>type</a> `integer` has a required
parameter, whose value must be an integer in the <a>configuration
point</a>'s <a>range</a>.

### Enum-valued features ### {#enum-valued-features}
A <a>document policy directive</a> whose <a>directive name</a> names a
<a>Configuration point</a> with <a>type</a> `float` has a required
parameter, whose value must be an decimal in the <a>configuration
point</a>'s <a>range</a>.

Enum-valued features should take a parameter with no value. The allowed
values for the enum should be used as the parameter name.
A <a>document policy directive</a> whose <a>directive name</a> names a
<a>configuration point</a> with <a>type</a> `enum` has a required parameter,
whose value must be 'true', and whose name must be a token in the
<a>configuration point</a>'s <a>range</a>.

Examples:
* `enum-feature;state`
* `boolean-feature`
* `no-boolean-feature`
* `integer-feature;p=2`
* `float-feature;q=-0.2`
* `enum-feature;state`

</section>
<section>
Expand All @@ -390,8 +403,9 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
Document-Policy = sh-list

Each list element must be a token. If the token does not name a supported
feature or pseudo-feature, (or a supported boolean feature prefixed by
"no-",) then the list element will be ignored by the processing steps.
configuration point or a supported boolean configuration point prefixed by
"no-", or the special value "*", then the list element will be ignored by
the processing steps.
</section>
<section>
### Document-Policy-Report-Only ### {#document-policy-report-only-http-header}
Expand Down Expand Up @@ -568,12 +582,13 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
document policy</a> |declaredPolicy|, this algorithm returns true if
|declaredPolicy| is compatible with |requiredPolicy|, or false otherwise.

1. For each |feature| → |value| in |requiredPolicy|:
1. If |feature|'s <a>requires acknowledgment</a> flag is `no`, then
continue.
1. If |declaredPolicy|[|feature|] does not exist, then return false.
1. If |value| is stricter than |declaredPolicy|[|feature|], then return
false.
1. For each |configuration point| → |value| in |requiredPolicy|:
1. If |configuration point|'s <a>requires acknowledgment</a> flag is
`no`, then continue.
1. If |declaredPolicy|[|configuration point|] does not exist, then
return false.
1. If |value| is stricter than |declaredPolicy|[|configuration point|],
then return false.
1. Return true.

</div>
Expand Down Expand Up @@ -619,69 +634,75 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
1. Remove |element|["report-to"].
1. If |element| is the string "`*`", then:
1. Set |defaultEndpoint| to |currentEndpoint|.
1. Otherwise, if |element| is the name of a supported feature which is a
boolean feature, then:
1. Otherwise, if |element| is the name of a supported configuration
point whose type is boolean, then:
1. If |element| has any associated parameters, then fail.
1. Let |feature| be the supported feature with name |element|.
1. If |policy|[|feature|] exists, then continue with the next
|element|.
1. Set |policy|[|feature|] to a new boolean <a>policy
1. Let |configuration point| be the supported configuration point
with name |element|.
1. If |policy|[|configuration point|] exists, then continue with the
next |element|.
1. Set |policy|[|configuration point|] to a new boolean <a>policy
configuration</a> with <a for="policy configuration">value</a>
true, and <a for="policy configuration">reporting endpoint</a>
|currentEndpoint|.
1. Continue with the next |element|.
1. Otherwise, if |element| begins with the string `"no-"`, and the
remaining characters match the name of a supported feature which is a
boolean feature, then:
remaining characters match the name of a supported configuration point
whose type is boolean, then:
1. If |element| has any associated parameters, then fail.
1. Let |elementName| be the substring of |element| after the prefix
`"no-"`.
1. Let |feature| be the supported feature with name |elementName|.
1. If |policy|[|feature|] exists, then continue with the next
|element|.
1. Set |policy|[|feature|] to a new boolean <a>policy
1. Let |configuration point| be the supported configuration point
with name |elementName|.
1. If |policy|[|configuration point|] exists, then continue with the
next |element|.
1. Set |policy|[|configuration point|] to a new boolean <a>policy
configuration</a> with <a for="policy configuration">value</a>
false, and <a for="policy configuration">reporting endpoint</a>
|currentEndpoint|.
1. Continue with the next |element|.
1. Otherwise, if |element| is the name of a supported feature, then:
1. Otherwise, if |element| is the name of a supported configuration
point, then:
1. If |element| does not have exactly one parameter, then fail.
1. Let |feature| be the supported feature with name |element|.
1. If |policy|[|feature|] exists, then continue with the next
|element|.
1. If |feature| is an enum-valued feature, then
1. Let |configuration point| be the supported configuration point
with name |element|.
1. If |policy|[|configuration point|] exists, then continue with the
next |element|.
1. If |configuration point|'s type is enum, then:
1. If |element|'s parameter has a value, then fail.
1. Let |value| be the name of |element|'s parameter.
1. If |value| is not the name of one of |feature|s allowed
enum values, then fail.
1. Set |policy|[|feature|] to a new enum <a>policy
1. If |value| is not the name of one of |configuration point|s
allowed enum values, then fail.
1. Set |policy|[|configuration point|] to a new enum <a>policy
configuration</a> with <a
for="policy configuration">value</a> |value|, and <a
for="policy configuration">reporting endpoint</a>
|currentEndpoint|.
1. Continue with the next |element|.
1. If |element|'s parameter's name does not match |feature|'s
parameter name, then fail.
1. If |element|'s parameter's name does not match |configuration
point|'s parameter name, then fail.
1. Let |value| be the value of |element|'s parameter.
1. If |feature| is an integer-valued feature, then
1. If |configuration point|'s type is integer, then:
1. If |value| is not an integer, then fail.
1. If |value| is not in |feature|'s range, then fail.
1. Set |policy|[|feature|] to a new integer <a>policy
configuration</a> with <a
1. If |value| is not in |configuration point|'s range, then
fail.
1. Set |policy|[|configuration point|] to a new integer
<a>policy configuration</a> with <a
for="policy configuration">value</a> |value|, and <a
for="policy configuration">reporting endpoint</a>
|currentEndpoint|.
1. Continue with the next |element|.
1. If |feature| is an float-valued feature, then
1. If |configuration point|'s type is float, then:
1. If |value| is not a float, then fail.
1. If |value| is not in |feature|'s range, then fail.
1. Set |policy|[|feature|] to a new float <a>policy
1. If |value| is not in |configuration point|'s range, then
fail.
1. Set |policy|[|configuration point|] to a new float <a>policy
configuration</a> with <a
for="policy configuration">value</a> |value|, and <a
for="policy configuration">reporting endpoint</a>
|currentEndpoint|.
1. Continue with the next |element|.
1. For each |feature| → |config| in |policy|,
1. For each |configuration point| → |config| in |policy|,
1. If |config| does not have a <a for="policy configuration">reporting
endpoint</a>, set |config|'s <a
for="policy configuration">reporting endpoint</a> to
Expand Down Expand Up @@ -965,20 +986,20 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
specification attempts to at least not make them needlessly worse.
Security and privacy issues may also be caused by the design of individual
features, so care must be taken when integrating with this specification. This
section attempts to provide some guidance as to what kinds of behaviors could
cause such issues.
configuration points, so care must be taken when integrating with this
specification. This section attempts to provide some guidance as to what kinds
of behaviors could cause such issues.
## Exposure of cross-origin behavior {#exposure-of-cross-origin-behavior}
Features should be designed such that a violation of the policy in a
framed document is not observable by documents in other frames. For instance,
a hypothetical feature which caused a event to be fired in the embedding
document if it is used while disabled by policy, could be used to extract
information about the state of an embedded document. If the feature is known
only to be used while a user is logged in to the site, for instance, then the
embedder could disable that feature for the frame, and then listen for the
resulting events to determine whether or not the user is logged in.
Configuraton points should be designed such that a violation of the policy in
a framed document is not observable by documents in other frames. For
instance, a hypothetical feature which caused a event to be fired in the
embedding document if it is used while disabled by policy, could be used to
extract information about the state of an embedded document. If the feature is
known only to be used while a user is logged in to the site, for instance,
then the embedder could disable that feature for the frame, and then listen
for the resulting events to determine whether or not the user is logged in.
## Unanticipated behavior changes ## {#unanticipated-behavior-changes}
Expand Down

0 comments on commit 1e35db6

Please sign in to comment.