1. Introduction
This document defines Document Policy, which is a framework for designing configurable features as part of the web platform, and for allowing web developers to configure those features as part of their site deployment.
2. Examples #
Needs new examples. For now, see explainer.
3. Other and related mechanisms
Document Policy is similar in scope to some existing mechanisms for document configuration, though there are significant differences from each.
3.1. Relation to Feature Policy
Feature Policy [FEATURE-POLICY] is another mechanism which allows authors to configure features in documents, and is similar in scope, though it uses a different inheritance mechanism, which makes it more suitable for certain types of features, separate from those which are suitable for control by document policy.
Historically, document policy was created as a response to a number of proposed feature additions to feature policy, which either didn’t quite fit the existing 'feature' model, or required significant additional complexity to be added to the feature policy spec. This included features with parameters, features with optional inheritance into subframes, and features which would inherit differently in popups than in other top-level browsing contexts.
Those features are now proposed to be covered by document policy, and feature policy is used for features where delegation is the primary concern. Feature policy features are boolean-valued (either enabled or disabled), can never be re-enabled in a child frame if disabled in parent, and generally follow the model of "available in top-level browsing contexts and their same-origin children; must be delegated to cross-origin frames."
In contrast, features controlled by document policy may take parameters, and those parameters may have unrelated values in different frames (constraining a feature in a parent frame does not necessarily constrain its child frames.)
3.2. Relation to Content Security Policy
Content-Security-Policy [CSP] also configures 'features' in documents, although it is primarily concerned with the origin of resources in a page, rather than controlling what those resources can do once loaded.
CSP also provides a different mechanism for setting sandbox flags on a document, through the sandbox directive. If sandbox flags are moved to document policy, then this may be redundant, as the two headers may encode identical information.
CSP-Embedded-Enforcement introduced a model for forcing a policy to be adhered to by child documents, and for rejecting non-conforming documents as network errors during Fetch. This model is adopted by document policy for the required policy mechanism.
3.3. Relation to Sandboxing
Iframe sandboxing is another mechanism for controlling features in documents, and behaves in a very similar manner to document policy’s required policies: disabling a feature is something that can be imposed on a frame, and affects all content loaded into that frame.
The features which are controlled by the iframe sandbox attribute could be expressed very naturally with document policy.
One key difference between iframe sandboxing and document policy is that all sandbox features are applied by default when the 'sandbox' attribute is used on a frame, and must be re-enabled one-by-one. This makes it very difficult to extend the sandboxing model with new features, as any additions will immediately affect all existing sandboxed content. Additionally, there is no mechanism for the origin server to know that its content will be sandboxed, so it is difficult to add new sandbox features which could potentially alter control flow in a sandboxed document, as this could introduce new security vulnerabilities in existing content.
4. Framework
4.1. Features
-
A name, which is a token,
-
A value type, which is either
boolean
,integer
,float
, orenum
, -
A value range, which is a subset of the possible values for the feature’s type, and
-
A default value, which is an element of the feature’s value range.
4.2. Policies
-
Browsing context has a required document policy, which is a document policy.
-
Browsing context has a nested context required document policy, which is a document policy.
-
Document has a declared document policy, which is a document policy.
A document policy is an ordered map from features to values.
-
A browsing context with a null opener browsing context has an empty required document policy.
4.3. Values
-
Policies have values for features
-
Values have domains
-
Domains have ordering
-
Examples: positive ints, floats, bools, enums
4.4. Default Values
-
features have default values.
-
(Non-normative) Defaults are chosen for web compatibility.
5. Required Policy Serialization
-
Explain here how required policies are serialized as structured headers.
-
Ensure that there is a canonical form (for compat testing).
6. Delivery
6.1. 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 policy directive. 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.
6.1.1. Boolean-valued features
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.
Examples:
-
boolean-feature
-
no-boolean-feature
6.1.2. Integer-valued features
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.
Examples:
-
integer-feature;p=2
6.1.3. Float-valued features
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.
Examples:
-
float-feature;q=-0.2
6.1.4. Enum-valued features
Enum-valued features should take a parameter with no value. The allowed values for the enum should be used as the parameter name.
Examples:
-
enum-feature;state
6.2. HTTP Headers
6.2.1. Document-Policy
The `Document-Policy
` HTTP
header can be used in the response (server to client) to communicate the document policy that should be enforced by the client.
The Document-Policy
header is a Structured Header. Its value
must be a list. Its ABNF is:
Document-Policy = sh-list
Each list element must be a token. If the token does not name a supported feature, (or a supported boolean feature prefixed by "no-",) then the list element must be ignored.
6.2.2. Require-Document-Policy
The `Require-Document-Policy
`
HTTP header field is a response header which is used to communicate to the
client the minimum required document policy to apply to all nested
content.
The Require-Document-Policy
header is a Structured Header list, with
exactly the same syntax as the Document-Policy
header.
6.2.3. Sec-Required-Document-Policy
The `Sec-Required-Document-Policy
`
HTTP header field is a request header which is used to communicate to the
server the document policy which must be sent with the document
returned with the request.
The header’s value is the § 5 Required Policy Serialization of one or more policy directives
6.3. The policy
attribute of the iframe
element
iframe
elements have a "policy
" attribute, which contains a required
policy directive (SH format).
7. Integrations
If a frame has a required policy, then that policy must be advertised in the request header for any outgoing document requests, to inform the server of the policy which will be applied to the document by the user agent. This allows the server to alter the representation which is returned, to conform to that policy.
In the case where a required policy request header is present, the response must contain a compatible document policy header, or the fetch will fail.
7.1. Integration with HTML
The following changes should be incorporated into [HTML]:
-
iframe
elements should have the following IDL added:
[CEReactions] attribute DOMString policy;
-
The iframe policy attribute should be defined as follows:
-
The
policy
attribute, when specified, adds a required document policy to theiframe
's nested browsing context, when it is initialized. Its value must be a serialized document policy.
-
-
In HTML 5 §3.1.1 The Document object, add the following line:
-
The Document has a document policy, which is a document policy, which is initially empty.
-
-
In the algorithm:
-
Add the following step after step 5:
-
Set browsingContext’s required document policy to the result of creating a required policy for a browsing context browsingContext.
-
-
Change step 9 (renumbered now to 10) to read:
-
Let document be a new Document, marked as an HTML document in quirks mode, whose content type is
"text/html"
, origin is origin, active sandboxing flag set is sandboxFlags, feature policy is feature policy, document policy is identical to browsingContext’s required document policy, and which is both ready for post-load tasks and completely loaded immediately.
-
-
-
In the process a navigate fetch algorithm:
-
Add the following step after step 5:
-
Set request’s required document policy to browsingContext’s required document policy.
-
-
-
In the algorithm:
-
Add the following step after step 3:
-
Let documentPolicy be the result of creating a document policy for browsingContext from response.
-
-
Change step 6 (renumbered now to 7) to read:
-
Let document be a new Document, whose type is type, content type is contentType, origin is origin, feature policy is featurePolicy, active sandboxing flag set is finalSandboxFlags, and document policy is documentPolicy.
-
-
7.2. Integration with Fetch
The following changes should be incorporated into [FETCH]:
-
In Fetch Standard §2.2.5 Requests, add the following:
-
A request has an associated required document policy, which is a document policy. Unless otherwise stated, it is null.
-
-
In Fetch Standard §4.5 HTTP-network-or-cache fetch, after step 15, insert the following:
-
If httpRequest has a required document policy, then
-
Let serializedRequiredPolicy be the result of calling Serialize Required Policy on httpRequest’s required document policy.
-
Append
Sec-Required-Document-Policy
/serializedRequiredPolicy to httpRequest’s header list.
-
-
-
In Fetch Standard §4.1 Main fetch, add the following algorithm to the list of algorithms in step 11:
-
Add the following algorithm to Fetch Standard §2.2.2 Headers:
-
To get and parse a structured header name as type from header list list, run these steps:
-
Let input be the result of getting name from list.
-
If input is null, then return null.
-
Let value be the result of running the Parsing Header Fields into Structured Headers algorithm with input as input_string and type as header_type. [HEADER-STRUCTURE]
-
If the previous step fails, return null.
-
Return value.
-
-
8. Algorithms
8.1. Is policy compatible?
Given a required document policy requiredPolicy and a declared document policy declaredPolicy, this algorithm returns true if declaredPolicy is compatible with requiredPolicy, or false otherwise.
-
For each feature → value in requiredPolicy:
-
If feature does not require acknowledgement, then continue.
-
If declaredPolicy[feature] does not exist, then return false.
-
If requiredPolicy[feature] is stricter than declaredPolicy[feature], then return false.
-
-
Return true.
8.2. Process response policy
Given a response (response), this algorithm returns a declared document policy.
-
Abort these steps if the response’s header list does not contain a header whose name is "
Document-Policy
". -
Let header be the concatenation of the values of all header fields in response’s header list whose name is "
Document-Policy
", separated by U+002C (,) (according to [RFC7230, 3.2.2]). -
Let document policy be the result of executing Parse document policy on header.
-
Return document policy.
8.3. Parse document policy
Given a string (policyString), this algorithm returns a document policy, if it can be parsed as one, or else fails.
-
Let policy be a new ordered map.
-
Let list be the result of parsing policyString as a list.
-
If parsing fails, then fail.
-
For each element in list,
-
If element is not a token, then fail
-
If element is the name of a supported feature which is a boolean feature, then
-
If element has any associated parameters, then fail.
-
Let feature be the supported feature with name element.
-
If policy[feature] exists, then continue with the next element.
-
Set policy[feature] to the boolean value true.
-
Continue with the next element.
-
-
If element begins with the string "no-", and the remaining characters match the name of a supported feature which is a boolean feature, then
-
If element has any associated parameters, then fail.
-
Let feature be the supported feature with name element.
-
If policy[feature] exists, then continue with the next element.
-
Set policy[feature] to the boolean value false.
-
Continue with the next element.
-
-
If element is the name of a supported feature, then
-
If element does not have exactly one parameter, then fail.
-
Let feature be the supported feature with name element.
-
If policy[feature] exists, then continue with the next element.
-
If feature is an enum-valued feature, then
-
If element’s parameter has a value, then fail.
-
Let value be the name of element’s parameter.
-
If value is not the name of one of features allowed enum values, then fail.
-
Let policy[feature] be the enum value named value.
-
Continue with the next element.
-
-
If element’s parameter’s name does not match feature’s parameter name, then fail.
-
Let value be the value of element’s parameter.
-
If feature is an integer-valued feature, then
-
If value is not an integer, then fail.
-
If value is not in feature’s range, then fail.
-
Let policy[feature] be the integer value value.
-
Continue with the next element.
-
-
If feature is an float-valued feature, then
-
If value is not a float, then fail.
-
If value is not in feature’s range, then fail.
-
Let policy[feature] be the float value value.
-
Continue with the next element.
-
-
-
-
Return policy.
8.4. Serialize required policy
Given a document policy (requiredPolicy), this algorithm returns a string which represents the canonical serialization of the policy.
-
Let list be an empty sh-list
-
Let features be the keys of requiredPolicy
-
Sort features by the name of each element, in ASCII order.
-
For each feature in features:
-
If feature is a boolean-valued feature, then
-
If requiredPolicy[feature] is true, append feature’s name to list.
-
Otherwise, append the sh-token formed by concatenating the string "no-" and feature’s name to list.
-
-
Otherwise, if feature is an enum-valued feature, then
-
Let value be requiredPolicy[feature].
-
Let param be a parameter with param-name value and with no param-value.
-
Append an sh-item which is an sh-token formed from feature’s name, with the single parameter param, to list.
-
-
Otherwise,
-
Let value be requiredPolicy[feature].
-
Let param be a parameter with param-name being features’s parameter name, and with param-value value.
-
Append an sh-item which is an sh-token formed from feature’s name, with the single parameter param, to list.
-
-
-
Return the serialization of list.
8.5. Create a required policy for a browsing context
Given a browsing context (browsingContext), this algorithm returns a new Document Policy.
-
If browsingContext is a nested browsing context, then
-
Let requiredPolicy be a clone of browsingContext’s browsing context container’s nested context required document policy.
-
If browsingContext’s browsing context container has a "policy" attribute, then
-
Let somethingPolicy be the result of parsing the attribute
-
For each feature -> value in somethingPolicy:
-
If requiredPolicy[feature] does not exist, or if value is stricter than requiredPolicy[feature], then set requiredPolicy[feature] to value.
-
-
-
-
Otherwise, let requiredPolicy be a new ordered map.
-
return requiredPolicy.
8.6. Create a document Policy for a browsing context from response
Given a browsing context (browsingContext) and a response (response), this algorithm returns a new Document Policy.
-
Let requiredPolicy be the result of running Create a required policy for a browsing context given browsingContext.
-
Let declaredPolicy be the result of running Process response policy on response.
-
If declaredPolicy is compatible with requiredPolicy, then return declaredPolicy.
-
Throw an exception.
8.7. Should response to request be blocked due to document policy?
-
If request has a required document policy, then
-
Let documentPolicy be the result of getting and parsing the structured header
Document-Policy
as "list" from response’s header list. -
If documentPolicy is not compatible with request’s required document policy, return "blocked".
-
Return "valid".
-
8.8. Get policy value for feature in document
Given a feature (feature) and a Document
object (document), this
algorithm the value for feature in document’s document policy.
-
Let policy be document’s Document Policy.
-
If policy[feature] exists, return it.
-
Return feature’s default value.
9. IANA Considerations
The permanent message header field registry should be updated with the following registrations [RFC3864]:
- Header field name
- Document-Policy
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- Document Policy API
- Header field name
- Require-Document-Policy
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- Document Policy API
- Header field name
- Sec-Required-Document-Policy
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- Document Policy API
10. Privacy and Security
This is going to be very similar to feature policy, with these notes:
-
Opt-in generally required to enable enforcement in subframes.
-
Policy attribute may conflict with sandbox attribute
-
Observability? Yes, still. Take care when designing features that their effects cannot be seen across origin boundaries.
-
Take care in creating non-reflect features
This specification standardizes a mechanism for an embedding page to set a
policy which will be enforced on an embedded page. When explicit
acknowlegement of a required policy is not required, similar to iframe sandbox
, this means that behaviors of existing features may be
changed in published web sites, by embedding them in another document with an
appropriate required policy.
As such, the biggest privacy and security concerns are:
-
Exposure of behavior in a cross-origin subframe to its embedder.
-
Unanticipated behavior changes in subframes controlled by the embedder.
To a degree, these concerns are already present in the web platform, and this 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.
10.1. 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.
10.2. Unanticipated behavior changes
Document policy grants a document the ability to control which features will and will not be availble in a subframe at the time it is loaded. When a feature represents an existing, long-standing behavior of the web platform, this may mean that existing published content on the web was not written with the expectation that a particular API could fail.
-
Mitigated by requiring opt-in
-
non-opt-in features have issues similar to sandbox.
-
Reference FP section
10.3. Advertisement of required policy
-
May leak details of embedder headers or markup.