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-CHresponse 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-CHheaders 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-CHresponse 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.15 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 token s.
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_CHFrame (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-CHheader is not present, abort these steps. - Let hintSet be an empty ordered set .
-
For
each
hint
in
the
result
of
parsing
Accept-CHaccording 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-CHheader is not present, abort these steps. -
If
response
’s
Critical-CHheader is not present, abort these steps. - Let missingHintSet be an empty ordered set .
-
For
each
hint
in
the
result
of
parsing
Accept-CHaccording 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-CHaccording 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 token s to the environment settings object ’s client hints set . It does not add those hints to the Accept-CH cache .
-
Let
metaElement
be
the
metaelement. -
If
any
link,style, orscriptelements have begun to execute, then return. -
If
metaElement
has
no
http-equivattribute, or if that attribute’s value is notdelegate-ch, then return. -
If
metaElement
has
no
contentattribute, 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
contentattribute. - 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-CHrestart 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-CHrestart time -
a
DOMHighResTimeStampused 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 named
delegate-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.15 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 token s:
-
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-datawhich has a default allowlist of'*' -
ch-dprwhich has a default allowlist of'self' -
ch-widthwhich has a default allowlist of'self' -
ch-viewport-widthwhich has a default allowlist of'self' -
ch-viewport-heightwhich has a default allowlist of'self' -
ch-device-memorywhich has a default allowlist of'self' -
ch-rttwhich has a default allowlist of'self' -
ch-downlinkwhich has a default allowlist of'self' -
ch-ectwhich has a default allowlist of'self' -
ch-prefers-color-schemewhich has a default allowlist of'self' -
ch-prefers-reduced-motionwhich has a default allowlist of'self' -
ch-uawhich has a default allowlist of'*' -
ch-ua-archwhich has a default allowlist of'self' -
ch-ua-bitnesswhich has a default allowlist of'self' -
ch-ua-form-factorswhich has a default allowlist of'self' -
ch-ua-full-versionwhich has a default allowlist of'self' -
ch-ua-full-version-listwhich has a default allowlist of'self' -
ch-ua-mobilewhich has a default allowlist of'*' -
ch-ua-modelwhich has a default allowlist of'self' -
ch-ua-platformwhich has a default allowlist of'*' -
ch-ua-platform-versionwhich has a default allowlist of'self' -
ch-ua-wow64which 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