This page summarises some considerations for developers preparing for the rollout of Google's User-Agent Client-Hints (UA-CH) proposal. We recently recorded a webinar on this topic: User Agent Client Hints: Navigating the new landscape.
The first request issue
High entropy UA-CH headers are sent by browsers only on request by the server. This means that servers receive the full set of requested headers only in the second request from a newly-seen browser.
If a web application needs full device information in order to build a meaningful response to a browser it is recommended to force a retry of the first request in the case where a request from a browser supporting UA-CH does not have the required hints present. Subsequent requests and future visits should contain any requested UA-CH headers, as long as the user or browser has not deliberately limited this.
Google have proposed a mechanism to work around the first request issue called Critical CH, discussed below.
Accept-CH
The Accept-CH
response header is the means by which a web server communicates its wish to receive User-Agent Client Hints from a browser. But the Accept-CH
opt-in is defined on a navigation response , meaning it is defined only for requests corresponding to a user navigating to a page:
A navigation request is a request whose destination is "document", "embed", "frame", "iframe", or "object".
From https://fetch.spec.whatwg.org/#navigation-request
In practice this means that the Accept-CH
response header applies only to top-level navigation requests (i.e. requests for pages, iframes and so on) and not linked resources. Requests for resources linked to pages are controlled by the Delegate-CH
response header. This is is discussed in further detail below.
As such, page resource requests are not in scope. Delegation of hints to cross-origin resources are covered by Permission Policy settings, covered below.
Critical-CH
The Critical-CH
response header from a server requests that, if a particular Client Hint header was not received but could have been sent according to the browser's policies, a new request should automatically be made that includes the requested Client Hints header. This proposal makes handling the first-request problem slightly easier since the client will know to try the request again without an explicit redirect request from the server.
The details of this proposal are documented in the Client Hint Reliability RFC.
Critical-CH is currently supported in Chrome and Chrome Mobile. The only other browser to support UA-CH, Microsoft Edge, does not currently support this.
Quoted header values
UA-CH headers follow RFC8941, a standard for structured field values for HTTP. This means that header values are wrapped in double quotes, unlike the more traditional HTTP headers such as User-Agent. Thus, the Sec-CH-UA-Model
header value for a Google Pixel 6 is "Pixel 6"
, not Pixel 6
. The same applies to all other new headers mentioned in the UA-CH proposal. DeviceAtlas requires the header value as received in order to work correctly.
Client hint delegation, cross-origin requests and iframes
The UA-CH proposal requires that pages explicitly grant permission for cross-origin requests and iframes to obtain UA-CH headers from the browser. This mechanism to do this is part of the broader Permissions Policy standard in development by the W3C. This permission can be granted via response headers sent by the origin server or <meta>
tags in the origin page HTML.
permissions-policy: ch-ua-platform-version=(self "example.com"), sec-ch-ua-model=(self "example.com" "anotherexample.com");
<meta name="accept-ch" content="sec-ch-ua-model=( https://example.com )">
It is not possible to delegate to all third-party domains via *
in the meta tag.
High entropy Client Hints and JavaScript
As mentioned above, the sending of Client Hints to third-party origins is normally controlled by the Permissions Policy set by the first-party page. For some use cases Permission Policies are difficult to work with since they require prior knowledge of the full hostnames of any third-party origins referenced by the first-party origin. JavaScript-based solutions may be more suitable in this case.
A script loaded from a third-party origin can currently access high entropy Client Hints via the JavaScript API irrespective of any Permission Policy configuration. Once gathered, these details can then be packaged up into a request to a server operated by the third-party service. Note that there is an open issue on the UA-CH GitHub page about how a browser should decide whether or not to supply the high entropy details when asked for them via the JavaScript API:
getHighEntropyValues()
It seems likely that in the case of Google Chrome this will be part of their broader policy about limiting bits of entropy to each origin in a general way e.g. including sensor data, canvas fingerprinting etc.
De-duplicating server requests
If the Critical-CH
is utilised as decribed above, Chrome will automatically retry requests if doing so would provide the server with the critical hints it has requested. Depending on the application, server-side logic may be required to ensure that requests are appropriately treated at the server. As an example, for web analytics purposes or non-idempotent requests it may be necessary to ignore the initial request and act only on the second one.
Note that in the case of a Critical-CH
induced retry, the Network panel of the Chrome inspector currently does not show the second request request taking place—you will only see evidence of this in your server logs. We have mentioned this to Google. The Chromium team have logged bug 1176879 to track it.
UA-CH preference lifetime
The lifetime of client hint preferences is the "browser session", which is generally fairly long-lived. The current implementation in Chrome clears the preferences on browser restart and if origin-specific information is cleared (e.g. cookies, storage, cache). Opening a new incognito window in Chrome does not clear these preferences.
Microsoft Edge
Microsoft has supported UA-CH in Edge since version 90 and have stated that UA-CH is their preferred way to detect Edge. Microsoft have not yet settled on the final reduced format of the Edge User-Agent header.
Frozen/reduced User-Agent Strings
At the time of writing only Chrome has published their final frozen/reduced user-agent strings. The general format is as follows:
Mozilla/5.0 (<unifiedPlatform>) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/<majorVersion>.0.0.0 <deviceCompat> Safari/537.36
Where:
- <deviceCompat> = "Mobile" or ""
- <majorVersion> = Chrome major version
- <unifiedPlatform> = a combination of platform, OS/CPU, Android Version, and deviceModel. It has two sets of possible values:
- Desktop
- Windows NT 10.0; Win64; x64
- Macintosh; Intel Mac OS X 10_15_7
- X11; Linux x86_64
- X11; CrOS x86_64
- Mobile
- Linux; Android 10; K
- Desktop
Some examples of this follow.
MacOS desktop, before and after User Agent header reduction:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Safari/537.36
Android phone (Huawei P30 Pro), before and after User Agent header reduction:
Mozilla/5.0 (Linux; Android 11; VOG-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36
FAQ
What about the Android WebView? Will it follow the path of Chome?
In a Chromium Blog blog post published on May 19th 2021 it was stated that "We have no plans to change the User-Agent string on Android WebView or Chrome for iOS at this time, but will make public updates if and when that changes."
This view is countered by a more recent post on the blink-dev group on chromium.org where an intent to ship UA-CH for the Android WebView is mentioned.
For how long will browsers retain UA-CH preferences for an origin?
This is an issue with the HTTP Client Hints more than this definition of particular hints; this is defined in RFC 8942. The relevant section of the spec says
"[the opt in] SHOULD be persisted and bound to the origin to enable delivery of Client Hints on subsequent requests to the server's origin, for the duration of the user's session (as defined by the user agent)."
The current implementation in Chrome clears the preferences on browser restart and if origin-specific information is cleared (e.g. cookies, storage, cache).
Is there any loss of functionality in DeviceAtlas resulting from the move to UA-CH?
DeviceAtlas's accuracy will be not be impacted except for a handful of phone models which share identical model names e.g. "M1" or "X1". In the current UA-CH proposal there is no way to distinguish between identical model names from different manufacturers since the Sec-CH-UA-Model
client hint specification does not include manufacturer.
How can I leave feedback for the WICG and the W3C?
DeviceAtlas recommends that any feedback for the WICG on the UA-CH proposal should be left on the GitHub issues page. Customers can also provide feedback to the W3C's Technical Architecture Group review of the proposal.
Are other browsers likely to support UA-CH?
It's unclear at this point. Apart from Chrome, of the major browsers only Edge supports the UA-CH, and only on the desktop version right now. Mozilla has declared UA-CH as harmful. This probably means that more general support for UA-CH will be slow to arrive, if it arrives at all.
References
- The UA-CH specification is maintained on the WICG UA-CH page on GitHub.
- Google's roadmap for the progressive reduction of content in the User Agent string
- Chrome browser's public release schedule.
- Initial blog post on User-Agent Reduction Origin Trial and Dates.
The phases of the Chrome user-agent string reduction are as follows:
Reduction phase | Chrome version | Date | Change |
---|---|---|---|
Phase 2 | Chrome 95 | October 2021 | Origin trial to experiment with Client Hints and provide feedback |
Phase 3 | Chrome 100 | March 2022 | Deprecation trial (opt-in) |
Phase 4 | Chrome 101 | April 2022 | Reduced Chrome version number rollout. MINOR.BUILD.PATCH version numbers becomes “0.0.0”. |
Phase 5 | Chrome 107 | October 2022 | Reduced Desktop User-agent string rollout |
Phase 6 | Chrome 110 | February 2023 | Reduced Mobile User-agent string rollout |
Phase 7 | Chrome 113 | May 2023 | Deprecation trial ends. Everyone receives reduced user-agents |