1. Introduction
Client Hints is collection of HTTP and user-agent features that enables privacy-preserving, proactive content negotiation with an explicit third-party delegation mechanism:
-
Proactive content negotiation at the HTTP layer enables servers to request delivery of specific hints, in order to enable optimized and automated selection of resources based on a user’s device, conditions and preferences, and lets clients decide which hint requests they want to grant, with per-hint and per-origin granularity.
-
Integration of said mechanism with web concepts, defined in this document, enables browsers to benefit from content adaptation, and have it play nicely with current web restrictions (e.g. same-origin policy).
-
The opt-in nature of the mechanism enables browsers to advertise requested hint data (e.g. user agent and device characteristics) selectively to secure-transport origins, instead of appending such data on every outgoing request.
-
Origin opt-in applies to same-origin assets only and delivery to third-party origins is subject to explicit first party delegation via Permissions Policy, enabling tight control over which third party origins can access requested hint data.
The goal of Client Hints is to reduce passive fingerprinting on the web while enabling scalable and privacy preserving content adaptation between client and server, via a standardized set of content negotiation primitives at the HTTP and user agent levels.
2. Infrastructure definition
The specification of the Client Hints infrastructure is divided between the following specifications and proposals:
-
IETF [RFC8942]
-
Provides the motivation for Client Hints.
-
Defines the
Accept-CH
response header, which servers may use to advertise support for certain Client Hints. -
Provides both general guidelines, and formal requirements, about Client Hints’ impact on caching, security, and privacy.
-
Does not define any actual, particular hints – or say anything about how Client Hints works in web contexts.
-
-
Client Hints infrastructure - this document
-
Defines how web clients should process the
Accept-CH
headers sent by servers. -
Defines the environment settings object state related to
Accept-CH
, which stores information about which servers should get which hints. -
Defines how, and when, web clients should actually go about sending hints, based on the state of their environment settings object.
-
More specifically, it integrates the HTML web concepts with Fetch’s algorithms to make sure that opted-in hints are added to requests for same-origin or delegated-to cross-origin requests. It also makes sure hints are removed from not delegated-to cross-origin requests after redirections.
-
-
Defines the
Critical-CH
response header, which servers may use to request a restart to include critical Client Hints missing in the initial load. -
Integrates those concepts with the [HTML] and [FETCH] specifications, by patching various concepts there.
-
-
W3C Permissions Policy specification
-
In order to perform third party Client Hint delegation, Permissions Policy has been extended to control features within fetch requests (rather than just Documents). See Permissions Policy § 9.13 Should request be allowed to use feature?
-
3. Environment settings object processing
3.1. Client hints set
A client hints set is a set of client hints tokens.
3.2. Accept-CH
cache
An Accept-CH cache is owned by the user agent and is an ordered map, keyed on origin (an origin), with a value of client hints set (a client hints set).
The Accept-CH cache can effectively act as an alternative cookie store, since sites can use each of the hints as a bit set on the client, and that information will be communicated to them on every request. As such, a user agent MUST evict that cache whenever the user clears their cookies or when session cookies expire. A user agent also MUST clear the Accept-CH according to the rules of the Clear-Site-Data Header.
A site can clear the browser’s Accept-CH
cache for its origin by sending an empty Accept-CH
header in a response. This sets the origin’s client hints set to an empty set.
There MAY be multiple Accept-CH
headers per-response and sf-lists can be split across lines as long as each line contains at least one token.
Note: As the cache can only be modified by the top-level frame, it is considered to be partitioned.
When asked to update the client hints set from cache given a settingsObject:
- Let hintSet be an empty ordered set.
- Let originMatchingEntries be the entries in the Accept-CH cache whose origin is same origin with settingsObject’s origin.
- For each entry in originMatchingEntries, for each token in entry’s client hints set, append the token to hintSet.
- Let frameHintSet be the ordered set of hints requested by the
ACCEPT_CH
Frame (if any). - For each hint in frameHintSet append the hint to hintSet.
- For each hint in hintSet, append hint to settingsObject’s client hints set.
When asked to create or override the cached client hints set given a settingsObject and response:
- If settingsObject is a non-secure context, abort these steps.
- Let browsingContext be settingsObject’s global object's browsing context.
- If the top-level browsing context does not equal browsingContext, abort these steps.
- If response’s
Accept-CH
header is not present, abort these steps. - Let hintSet be an empty ordered set.
-
For each hint in the result of parsing
Accept-CH
according to the header parsing rules, as a field-name:- If hint is a client hints token add it to hintSet.
- Let origin be response’s origin.
- Set Accept-CH cache[origin] to hintSet.
3.3. Critical-CH
If an origin is loaded and the server sets an Accept-CH
header that
lists hints not already in the current Accept-CH cache that means only
subsiquent loads of that origin will include the hints. If it’s
critical that every load (including the first) has the requested Client Hints,
then the server can set a Critical-CH
header to request a restart. The Critical-CH
header itself does not modify the Accept-CH cache.
A restart will only occur when a hint in the Accept-CH
header is both not in the Accept-CH cache and in the Critical-CH
header. If hints listed in
the Critical-CH
header are already in the Accept-CH cache no restart is
needed as they were sent. If hints listed in the Critical-CH
header are not
in the Accept-CH
header a restart would not result in the hints being included
anyway.
The restart retries the entire navigation (including any prior redirects).
There MAY be multiple Critical-CH
headers per-response and sf-lists can be split across lines as long as each line contains at least one token.
When asked if the user agent should restart loading the page for critical client hints given a settingsObject and response:
- If settingsObject is a non-secure context, abort these steps.
- Let browsingContext be settingsObject’s global object's browsing context.
- If the top-level browsing context does not equal browsingContext, abort these steps.
- If response’s
Accept-CH
header is not present, abort these steps. - If response’s
Critical-CH
header is not present, abort these steps. - Let missingHintSet be an empty ordered set.
-
For each hint in the result of parsing
Accept-CH
according to the header parsing rules, as a field-name:- If hint is a client hints token add it to missingHintSet.
- Let origin be response’s origin.
-
For each hint in Accept-CH cache[origin]:
- Remove hint from missingHintSet if present.
-
For each hint in the result of parsing
Critical-CH
according to the header parsing rules, as a field-name:- If hint is in missingHintSet return
true
.
- If hint is in missingHintSet return
- Return
false
.
3.4. Delegate-CH
There MAY be multiple Delegate-CH
tags per-document and this algorithm is run once for each in the order of the appearance of the tags.
Note: This metadata appends client hints tokens to the environment settings object's client hints set. It does not add those hints to the Accept-CH cache.
- Let metaElement be the
meta
element. - If any
link
,style
, orscript
elements have begun to execute, then return. - If metaElement has no
http-equiv
attribute, or if that attribute’s value is notdelegate-ch
, then return. - If metaElement has no
content
attribute, or if that attribute’s value is the empty string, then return. - Let settingsObject be metaElement’s relevant settings object.
- If settingsObject is a non-secure context, abort these steps.
- Let browsingContext be settingsObject’s global object's browsing context.
- If the top-level browsing context does not equal browsingContext, abort these steps.
- Let permissionsPolicy be metaElement’s node document’s permissions policy.
- Let delegateCHValue be the value of metaElement’s
content
attribute. - Let policyDirective be the result of running Permissions Policy § 9.3 Parse policy directive on delegateCHValue and the origin of the metaElement’s node document.
-
For each feature->allowList of policyDirective:
- If feature is not a client hints token, then continue.
- If permissionsPolicy[feature]'s permissions policy is
*
, then continue. - Let filteredAllowList be an empty ordered set.
- For each item in allowList:
- Append feature to settingsObject’s client hints set and Append filteredAllowList to permissionsPolicy[feature]'s permissions policy.
Clarify detection of link
, style
, or script
element execution. [Issue #110]
3.5. Interaction with ACCEPT_CH
frame
The ACCEPT_CH
frame is a way for Client Hints to be requested by a server
during the TLS handshake of HTTP/2 and HTTP/3. The requested hints are not persisted in the Accept-CH cache, but will be retrieved and merged when update the client hints set from cache is run. The full processing model
is defined in Client Hints Reliability.
There MUST be only one ACCEPT_CH
frames per-connection. Additional frames will be ignored.
4. Integration with HTML
This specification integrates with the [HTML] specification by patching the algorithms below:
4.1. Navigable
Add a new field to navigable:
- A
Critical-CH
restart timeDOMHighResTimeStamp
, initially 0. This records the time the navigation was restarted to ensure required Client Hint headers will be sent.
4.2. Navigation response
At populating a session history entry, in step 6 after substep 7 insert the following:
- Let shouldRestartForCriticalClientHints be
false
. -
If navigable’s Critical-CH restart time is 0:
- Let shouldRestartForCriticalClientHints be the result of running should restart page for critical client hints with the relevant settings object and response.
- Run create or override the cached client hints set with the relevant settings object and response as inputs.
-
If shouldRestartForCriticalClientHints then:
- Set navigable’s Critical-CH restart time to the current high resolution time.
- Restart the initial navigation (before any redirects).
-
If navigable’s Critical-CH restart time is not 0:
- Set navigationParams’s Critical-CH restart time to be navigable’s Critical-CH restart time.
Clarify how "Restart the initial navigation (before any redirects)" integrates with the HTML spec. [Issue #154]
At navigation params, append the following:
Critical-CH
restart time- a
DOMHighResTimeStamp
used for creating the navigation timing entry for the newDocument
. This records the time the navigation was restarted to ensure required Client Hint headers will be sent.
4.3. Service Worker initialization
At set up a worker environment settings object, after step 6, add the following step:- If worker global scope implements
ServiceWorkerGlobalScope
, then set settings object’s client hints set to be a clone of outside settings’ client hints set.
4.4. Standard metadata names
For the section standard metadata names, add a subsection nameddelegate-ch
with the outlined explanation.
4.5. Extending environment settings object
An environment settings object has a client hints set: a client hints set, initially the empty set, used for fetches performed using the environment settings object as a request client.
5. Request processing
When asked to append client hints to request with settingsObject and request as input, run the following steps:
- If request is a non-subresource request for a "sharedworker" or "worker" destination, exit without appending any hints to the header list.
- Let hintSet be an empty client hints set.
- Run update the client hints set from cache with settingsObject.
- For each client hints token lowEntropyHint in the registry’s low entropy hint table, append lowEntropyHint to hintSet.
- If request’s client is not null, then for each client hints token requestHint in settingsObject’s client hints set, append requestHint to hintSet.
-
For each hintName in hintSet:
-
If request is not a navigation request for a "document" destination:
- Let requestPermitsHint be the result of running Permissions Policy § 9.13 Should request be allowed to use feature? given request and hintName’s associated feature in § 7.2 Policy-controlled features.
- If requestPermitsHint is
false
, then continue to next hintName.
- If the user agent decides, in an implementation-defined way (see § 8 Security and Privacy considerations), to omit this hint then continue.
- Let value be the result of running find client hint value with hintName.
- If the user agent decides, in an implementation-defined way (see § 8 Security and Privacy considerations), to modify value then do so.
- append hintName/value to the header list.
-
If request is not a navigation request for a "document" destination:
When asked to remove client hints from redirect if needed with request as input, run the following steps:
-
For each hintToken in the list of client hints tokens:
-
If request’s header list contains hintToken, then remove hintToken from request’s header list.
-
6. Integration with Fetch
This specification integrates with the [FETCH] specification by patching the algorithms below:
In HTTP-network-or-cache fetch, within step 8, after substep 23, run append client hints to request with the relevant settings object and request as input.
In HTTP-redirect fetch, after step 11, run remove client hints from redirect if needed with request as input.
In forbidden request-header, to the list of headers within step 1, add Save-Data
, DPR
, Device-Memory
, Width
, and Viewport-Width
.
7. Feature Registry
Note: This section contains feature-specific definitions. New features that rely on the Client Hints infrastructure need to add their respective definitions to this registry. User Agents can implement some of those features without implementing others.
7.1. Client hints token
A client hints token is a byte-lowercase representation of one of Save-Data
, Sec-CH-DPR
, Sec-CH-Width
, Sec-CH-Viewport-Width
, Sec-CH-Viewport-Height
, Sec-CH-Device-Memory
, Sec-CH-RTT
, Sec-CH-Downlink
, Sec-CH-ECT
, Sec-CH-Prefers-Color-Scheme
, Sec-CH-Prefers-Reduced-Motion
, Sec-CH-UA
, Sec-CH-UA-Arch
, Sec-CH-UA-Bitness
, Sec-CH-UA-Full-Version
, Sec-CH-UA-Full-Version-List
, Sec-CH-UA-Mobile
, Sec-CH-UA-Model
, Sec-CH-UA-Platform
, Sec-CH-UA-Platform-Version
, or Sec-CH-UA-WoW64
.
Note: A client hints token will also match the request header sent by the user agent when appropriate (as determined by the request processing algorithm).
7.2. Policy-controlled features
This document defines policy-controlled client hints features, the following policy-controlled features:
-
ch-save-data
which has a default allowlist of'*'
-
ch-dpr
which has a default allowlist of'self'
-
ch-width
which has a default allowlist of'self'
-
ch-viewport-width
which has a default allowlist of'self'
-
ch-viewport-height
which has a default allowlist of'self'
-
ch-device-memory
which has a default allowlist of'self'
-
ch-rtt
which has a default allowlist of'self'
-
ch-downlink
which has a default allowlist of'self'
-
ch-ect
which has a default allowlist of'self'
-
ch-prefers-color-scheme
which has a default allowlist of'self'
-
ch-prefers-reduced-motion
which has a default allowlist of'self'
-
ch-ua
which has a default allowlist of'*'
-
ch-ua-arch
which has a default allowlist of'self'
-
ch-ua-bitness
which has a default allowlist of'self'
-
ch-ua-form-factors
which has a default allowlist of'self'
-
ch-ua-full-version
which has a default allowlist of'self'
-
ch-ua-full-version-list
which has a default allowlist of'self'
-
ch-ua-mobile
which has a default allowlist of'*'
-
ch-ua-model
which has a default allowlist of'self'
-
ch-ua-platform
which has a default allowlist of'*'
-
ch-ua-platform-version
which has a default allowlist of'self'
-
ch-ua-wow64
which has a default allowlist of'self'
Should we tie low-entropy-ness to allowlists, generally?
7.3. Low-entropy hint table
The low-entropy hint table below defines hints that are safe to send by default due to their low amounts of entropy.A high-entropy client hint is a client hint that is not in the low-entropy hint table.
Name | Value |
---|---|
Save-Data
| a suitable Save-Data value |
Sec-CH-UA
| a suitable UA value |
Sec-CH-UA-Mobile
| a suitable Mobile value |
Sec-CH-UA-Platform
| a suitable Platform value |
Note: If the value transmitted by Save-Data
is the empty string, the header will be omitted entirely.
This is done to reduce redundant header information sent by default.
7.4. Find client hint value
When asked to find client hint value, given hint as input, switch on hint and return the result:
Save-Data
- a suitable Save-Data value
DPR
- a suitable DPR value
Viewport-Width
- a suitable Viewport-Width value
Viewport-Height
- a suitable Viewport-Height value
Width
- a suitable Width value
Device-Memory
- a suitable Device-Memory value
RTT
- a suitable RTT value
Downlink
- a suitable Downlink value
ECT
- a suitable ECT value
Prefers-Color-Scheme
- a suitable color theme value
Prefers-Reduced-Motion
- a suitable Reduced-Motion value
UA
- a suitable UA value
UA-Arch
- a suitable Arch value
UA-Bitness
- a suitable Bitness value
UA-Full-Version
- a suitable Full-Version value
UA-Full-Version-List
- a suitable Full-Version-List value
UA-Mobile
- a suitable Mobile value
UA-Model
- a suitable Model value
UA-Platform
- a suitable Platform value
UA-Platform-Version
- a suitable Platform-Version value
UA-WoW64
- a suitable WoW64 value
Links for image features are broken, need to actually define that and link to them.
8. Security and Privacy considerations
This specification exposes information regarding the user’s preferences and agent, which can be used as an active fingerprinting vector. User agents implementing this specification need to be aware of that, and take that into consideration when deciding whether to implement specific hints, modify their returned values for a given hint, or omit the hint entirely.
For example, the user might have a site specific setting to override or disable specific client hints to reduce the potential for fingerprinting.
9. Terms
The following terms are defined in the HTTP specifications: field-name