diff --git a/README.md b/README.md index 87dfdf1..bc951fd 100644 --- a/README.md +++ b/README.md @@ -68,20 +68,44 @@ For more on the policy format, see [the dedicated document](./policy-format.md). ### Fetching and applying the origin policy -Browsers then fetch and cache origin policies for a given origin. They can optionally do so proactively (e.g. for frequently-visited origins), but generally will be driven by the web application sending a HTTP response header requesting that a given origin policy be fetched and applied: +Browsers then fetch and cache origin policies for a given origin. They can optionally do so proactively (e.g. for frequently-visited origins), but generally will be driven by the web application sending a HTTP response header requesting that a given origin policy be fetched and applied. + +For more on the model for fetching and updating origin policies, including motivations behind the design, see [the dedicated document](./version-negotiation.md). Here we summarize the most common patterns applications will probably use: + +#### Optional-but-suggested policy + +``` +Origin-Policy: preferred="my-policy", allowed=("my-old-policy" null) +``` + +This allows a previous revision of the policy (identified by `"my-old-policy"`), or no policy at all (`null`), but specifies that the `"my-policy"` revision is preferred. This response might be processed with the old or null origin policy if those are in the HTTP cache, but in that case, the browser will perform an asynchronous update to fetch the latest policy for use with future responses. + +If a _different_ origin policy is found in the HTTP cache, apart from `"my-policy"` or `"my-old-policy"`, then the response will use the null origin policy, since that is allowed. + +#### Latest available policy, if any + +``` +Origin-Policy: preferred=latest-from-network, allowed=(latest null) +``` + +This says that any cached origin policy from `/.well-known/origin-policy` can be used, but if no such policy is cached, then the null policy will be used instead. In either case, the latest policy will be fetched asynchronously. + +This is essentially a simplification of the previous version, where the server operator is expressing fewer constraints on the exact contents of the policy. + + +#### Mandatory policy ``` -Origin-Policy: allowed=(null "my-policy" "my-old-policy"), preferred="my-policy" +Origin-Policy: allowed=("my-policy") ``` -Here the header specifies allowed and preferred policies, which are matched against the JSON document's `"ids"` values. This allows servers to take on a variety of behaviors, including: +This says that the only origin policy that is allowed is one identified by `"my-policy"`. The origin policy must be fetched, from the cache or network, and must have an `"ids"` value that contains `"my-policy"`, before the response can be processed. If such an origin policy cannot be found, then the response will be treated as a network error. -* Require that a given origin policy be available (either from the cache or via fetching) and applied, before proceeding with page initialization -* Allow a previous revision of the policy, or no policy at all, to apply, but in the background do an asynchronous update of the policy so that future resource fetches will apply the preferred one. +This makes the most sense if the origin policy contains security-critical policies which would not be acceptable to continue without. -For more on the model for fetching and updating origin policies, see [the dedicated document](./version-negotiation.md). +### Policy expiry -Another important note is that the policy items in question automatically stop applying (in a policy item-specific way) when the origin policy stops applying. So, for example, removing the `"content_security"` member of the origin policy manifest above would cause any future loads that use that origin policy to not include the CSP in question. Combined with the usual HTTP cache expiry mechanisms for the `/.well-known/origin-policy` resource, this allows a general "max age" mechanism for origin-wide configuration, similar to the `max-age` parameter of [HSTS](https://tools.ietf.org/html/rfc6797), but for all policy items. +Policy items in question automatically stop applying (in a policy item-specific way) when the origin policy stops applying. So, for example, removing the `"content_security"` member of the origin policy manifest above would cause any future loads that use that origin policy to not include the CSP in question. Combined with the usual HTTP cache expiry mechanisms for the `/.well-known/origin-policy` resource, this allows a general "max age" mechanism for origin-wide configuration, similar to the `max-age` parameter of [HSTS](https://tools.ietf.org/html/rfc6797), but for all policy items. ### Configurable policy items diff --git a/index.src.html b/index.src.html index 257ac18..8ead2b3 100644 --- a/index.src.html +++ b/index.src.html @@ -208,7 +208,7 @@
Origin-Policy
` response header to indicate that this new policy is preferred:
- Origin-Policy: allowed=("policy-1" "policy-2"), preferred="policy-2" + Origin-Policy: preferred="policy-2", allowed=("policy-1")When the browser sees this header value on any response from
https://example.com
, one of three things will happen:
@@ -260,6 +260,34 @@ ids
" field of their origin policy manifest, server operators will be best served by keeping any previous [=origin policy/IDs=] as well, at least until any cached resources that reference that origin policy could have expired.
++ Origin-Policy: preferred="policy-2", allowed=("policy-1" null) ++ + This indicates that the [=null origin policy=] is acceptable, if both "
policy-1
" and "policy-2
" are not cached, and thus allows responses to initial visitors to proceed without blocking on fetching an origin policy. But, because there is a preferred
value, in such cases the browser will also do a non-blocking fetch to https://example.com/.well-known/origin-policy
, to update the HTTP cache for any future requests to https://example.com/
.
+
+ MegaCorp could even vary their `Origin-Policy
` header dynamically between this fast-but-permissive version and the previous blocking-and-strict version, depending on characteristics of the request such as [=credentials=].
+ids
" field, and their `Origin-Policy
` header allowed
and preferred
values. They just want to perform updates to their origin policy manifest, and have them rolled out to their visitors as soon as is possible.
+
+ To make this work, they change all their response headers to
+
+ + Origin-Policy: preferred=latest-from-network, allowed=(latest null) ++ + which will ensure that browser uses the latest origin policy available from the cache, if any, or the [=null origin policy=], if nothing is cached. Furthermore, the
preferred=latest-from-network
part of the header ensures that the browser will always perform a non-blocking fetch to https://example.com/.well-known/origin-policy
to update the HTTP cache.
+
+ This is slightly less efficient than the previous version. And, it doesn't allow expressing constraints on the contents of policies, by matching preferred and allowed values with the manifest's "ids
" field. But, it is simpler to maintain.
+Origin-Policy
` response header:
@@ -267,7 +295,7 @@ https://example.com/.well-known/origin-policy
.
+ When the browser receives this header, it will ensure that no origin policy is applied for the response, since only the [=null policy=] is allowed.
Origin-Policy
` HTTP headerOrigin-Policy
` is a [=structured header/dictionary=] structured header. The dictionary has two keys: [[!STRUCTURED-HEADERS]]
-* allowed
, whose value is an [=structured header/inner list=] that contains [=valid origin policy IDs=] as strings, or the token null
, and
-* preferred
, whose value is a [=valid origin policy ID=].
+* allowed
, whose value is an [=structured header/inner list=] that contains [=valid origin policy IDs=] as strings, or the token null
, or the token latest
; and
+* preferred
, whose value is either a [=valid origin policy ID=], or the token latest-from-network
.
At least one of these two entries needs to be provided for the header to have useful behavior.
+If an ID is provided for preferred
, it is unnecessary to also include it in the allowed
list.
Origin-Policy: allowed=(null)
` is sent, and thus use the [=null policy|null origin policy=] for processing the [=response=]. The processing model for omitting the header is to use any previously-cached [=/origin policy=] for the [=/origin=].
+The processing model for this header, including the fallback behavior for when it is not provided or does not conform to the above data model, is given in [[#from-response]]. In general, the fallback behavior for malformed headers is to behave the same as if `Origin-Policy: allowed=(null)
` is sent, and thus use the [=null origin policy=] for processing the [=response=]. The processing model for omitting the header is to use any previously-cached [=/origin policy=] for the [=/origin=].