forked from WICG/ua-client-hints
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
785 lines (585 loc) · 31.9 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
<pre class="metadata">
Title: User-Agent Client Hints
Status: CG-DRAFT
Group: WICG
ED: https://wicg.github.io/ua-client-hints/
Repository: wicg/ua-client-hints
Shortname: ua-client-hints
Level: None
Editor: Mike West 56384, Google Inc., [email protected]
Editor: Yoav Weiss 58673, Google Inc., [email protected]
Abstract:
This document defines a set of Client Hints that aim to provide developers with the ability
to perform agent-based content negotiation when necessary and provide an option to remove
"historical baggage" from the venerable `User-Agent` header.
Indent: 4
Default Biblio Status: current
Markup Shorthands: css off, markdown on
Boilerplate: omit conformance, omit feedback-header
!Participate: <a href="https://github.com/WICG/ua-client-hints/issues/new">File an issue</a> (<a href="https://github.com/WICG/ua-client-hints/issues">open issues</a>)
</pre>
<pre class="link-defaults">
spec:fetch; type:dfn; for:/; text:request
spec:webidl; type:dfn; text:resolve
spec:infra; type:dfn; text:user agent
spec:infra; type:dfn; for:/; text:list
</pre>
<pre class="anchors">
urlPrefix: https://tools.ietf.org/html/draft-ietf-httpbis-header-structure; spec: I-D.ietf-httpbis-header-structure
type: dfn
text: structured header; url: #
for: structured header
type: dfn
text: token; url: #section-3.3.6
text: boolean; url: #section-3.3.4
text: string; url: #section-3.3.3
text: list; url: #section-3.1
type: abstract-op
text: serialize Structured Header; url: #section-4.1
</pre>
<pre class="biblio">
{
"FacebookYearClass": {
"href": "https://engineering.fb.com/android/year-class-a-classification-system-for-android/",
"title": "Year class: A classification system for Android",
"authors": [ "Chris Marra", "Daniel Weaver" ]
},
"RFC2026" : {
"href": "https://tools.ietf.org/html/rfc2026#section-4.2.1",
"title": "The Internet Standards Process -- Revision 3",
"authors": [ "S. Bradner" ]
},
"I-D.draft-ietf-httpbis-client-hints": {
"href": "https://tools.ietf.org/html/draft-ietf-httpbis-client-hints",
"title": "HTTP Client Hints (Experimental)",
"authors": [ "Ilya Grigorik" ],
"status": "ID",
"publisher": "IETF"
},
"I-D.ietf-httpbis-header-structure": {
"authors": [ "Mark Nottingham", "Poul-Henning Kamp" ],
"href": "https://tools.ietf.org/html/draft-ietf-httpbis-header-structure",
"title": "Structured Headers for HTTP",
"status": "ID",
"publisher": "IETF"
},
"Janc2014": {
"href": "https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms#TOC-Browser-level-fingerprints",
"title": "Technical analysis of client identification mechanisms",
"authors": [ "Artur Janc", "Michal Zalweski" ]
},
"Rossi2015": {
"href": "https://channel9.msdn.com/Events/WebPlatformSummit/2015/The-Microsoft-Edge-Rendering-Engine-that-makes-the-Web-just-work#time=9m45s",
"title": "The Microsoft Edge Rendering Engine that makes the Web just work",
"author": [ "Jacob Rossi" ]
},
"51Degrees": {
"href": "https://51degrees.com/device-detection",
"title": "Use cases for device detection with 51Degrees",
"author": [ "51Degrees" ]
},
"Scientiamobile": {
"href": "https://www.scientiamobile.com",
"title": "WURFL based device detection",
"author": [ "Scientiamobile" ]
},
"DeviceAtlas": {
"href": "https://deviceatlas.com/",
"title": "Use cases for device detection with DeviceAtlas",
"author": [ "DeviceAtlas" ]
},
"AlexRussell": {
"href": "https://twitter.com/slightlylate/status/1139684093602349056/photo/2",
"title": "Performance scores by device model",
"author": [ "Alex Russell" ]
},
"Google-Analytics": {
"href": "https://support.google.com/analytics/answer/3123672?hl=en",
"title": "Acquisition device",
"author": [ "Google" ]
},
"Client-Hints-Infrastructure": {
"href": "https://wicg.github.io/client-hints-infrastructure/",
"title": "Client Hints Infrastructure",
"author": [ "Yoav Weiss" ]
},
"CMA-UK": {
"href": "https://www.gov.uk/cma-cases/online-platforms-and-digital-advertising-market-study",
"title": "Online platforms and digital advertising market study",
"author": [ "UK Competition and Markets Authority" ]
},
"Privacy-Budget": {
"href": "https://github.com/bslassey/privacy-budget",
"title": "Combating Fingerprinting with a Privacy Budget",
"author": [ "Brad Lassey" ]
}
}
</pre>
Dependencies {#dependencies}
============
This document is dependent on the following related specifications which the reader must be
familiar with before reading this document.
1. Experimental IETF specification for Client Hints ([[I-D.draft-ietf-httpbis-client-hints]]).
Not currently on track to become a standard [[RFC2026]].
2. Unofficial community draft Client Hints Infrastructure ([[Client-Hints-Infrastructure]]).
No official standing in W3C like this document.
ISSUE(https://wicg.github.io/client-hints-infrastructure): How are low and high entropy Client
Hints determined in the Client Hints Infrastructure document? How are they balanced against
considerations other than privacy? This needs to be resolved before referencing in this document.
Introduction {#intro}
============
Today, user agents generally identify themselves to servers by sending a `User-Agent` HTTP request
header field along with each request (defined in Section 5.5.3 of [[RFC7231]]). This header value
gives servers the option to perform content negotiation, sending down exactly those bits that best
represent the requested resource in a given user agent, optimizing both bandwidth and user
experience. In addition to performance improvements the information also supports analytics, fraud
detection, problem diagnosis and market share analysis.
When combined with other information the `User-Agent` field value could be used to track specific
user agents and therefore might represent a risk to people's privacy. This problem is most severe
when content is served over insecure HTTP where access providers can view the information. Privacy
concerns are mitigated to some extent when secure protocols such as HTTPS are used. Only parties
known to the user or the organization whose domain is displayed in the address bar of the user
agent will have access to the `User-Agent` field value.
[[RFC7231]] does not mandate the structure of the information contained in the field value. It has
evolved over several decades by multiple browser vendors and often contains information that is not
needed. Robust solutions ([[51Degrees]], [[DeviceAtlas]], [[Scientiamobile]]) for parsing
`User-Agent` field values know which segments to ignore or focus on and perform with over 99%
accuracy in practice.
For example, a recent version of Chrome on iOS identifies itself as:
``` http
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X)
AppleWebKit/605.1.15 (KHTML, like Gecko)
CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1
```
While a recent version of Edge identifies itself as:
``` http
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.2704.79
Safari/537.36 Edge/18.014
```
There's quite a bit of information packed into those strings (along with a fair number of lies
which are ignored in practice).
Use cases for the information contained in `User-Agent` field values include:
1. Brand and version information (e.g. "Chrome 69") allows websites to work around known bugs in
specific releases that aren't otherwise detectable. For example, implementations of Content
Security Policy have varied wildly between vendors, and it's difficult to know what policy to
send in an HTTP response without knowing what browser is responsible for its parsing and
execution.
2. Developers will often negotiate the content to send based on the user agent and platform. Some
application frameworks, for instance, will style an application on iOS differently from the same
application on Android in order to match each platform's aesthetic and design patterns.
3. Similarly to #1, OS revisions and architecture can be responsible for specific bugs which can
be worked around in website's code, and useful for things like selecting the appropriate
executable for download (32 vs 64 bit, ARM vs Intel, etc).
4. Sophisticated developers use model/make to tailor their sites to the capabilities of the
device (e.g. [[FacebookYearClass]]) and to pinpoint performance bugs and regressions which
sometimes are specific to model/make.
5. Difference models of device perform very differently [[AlexRussell]]. Developers wishing to
improve performance require this insight in analytics tools and in real time to optimise their
web site. The ability to optimise on first request is particularly important to authors targeting
people living in emerging economies where lower end device models and features are more widely
used than affluent western democracies.
6. Vendors of devices and browsers use the information transmitted in `User-Agent` field values to
measure the active install base of their products. This information in aggregate informs product
development decisions.
7. Web analytics solutions and search engine tools such as those developed by Google
[[Google-Analytics]] require the `User-Agent` field value to be present to provide insights into
device classifications, models, browser and operating system versions.
8. Identifying legitimate non human web traffic for the purposes of improving web sites based on
human interactions only, and other purposes where including non human activity in analysis is
undesirable, but where reliable identification of humans via sign in methods is either not
possible or desirable.
9. Fraud detection uses the version numbers, platform details, model information, and layout engine
versions, among others and form the basis for fingerprinting schemes for the identification and
prevention of fraud or to track people.
This document proposes a mechanism which will address the following distinct problems:
1. Address historic structural issues with the `User-Agent` field value by introducing new HTTP
header fields and values.
2. Reduce the amount of information sent on every request.
The document introduces seven new Client Hints ([[I-D.draft-ietf-httpbis-client-hints]]) that can
provide the client's branding and version information, the underlying operating system's branding
and major version, as well as details about the underlying device. Rather than broadcasting this
data all the time, user agents can provide this information on request.
Prior to deployment this approach will be compared with adopting a simpler and more efficient
convention for the existing `User-Agent` field values as a comparison.
Out of Scope {#out-of-scope}
------------
The following are out of scope for this document.
1. Understanding how the `User-Agent` field values are used in practice and the work involved in
migrating to Client Hints.
2. How the use cases for `User-Agent` field values will be migrated to make use of Client Hints.
These considerations will need to be addressed following incubation prior to deployment
following experiments.
ISSUE(wicg/ua-client-hints): Engage with a wide group of stakeholders prior to progression.
3. In this draft the identification and mitigation of privacy issues associated with the
deployment of Client-Hints is not in scope.
ISSUE: Align other work on privacy such as the introduction of personal identifiers,
requiring per install or upgrade privacy notices and defaults separate to user agent vendors other
notices [[CMA-UK]], or the concept of privacy budgets [[PRIVACY-BUDGET]].
4. Policy issues such as anti-trust or privacy which are not matters for technical specifications.
5. Modifications to existing `User-Agent` field values and practices.
Examples {#examples}
--------
A user navigates to `https://example.com/` for the first time. Their user agent sends the following
header along with the HTTP request:
``` http
Sec-CH-UA: "Examplary Browser"; v="73"
```
The server is interested in rendering content consistent with the user's underlying platform, and
asks for a little more information by sending an `Accept-CH` header (Section 2.2.1 of
[[I-D.draft-ietf-httpbis-client-hints]]) along with the initial response:
``` http
Accept-CH: UA-Full-Version, UA-Platform
```
In response, the user agent includes more detailed version information, as well as information about
the underlying platform in the next request:
``` http
Sec-CH-UA: "Examplary Browser"; v="73"
Sec-CH-UA-Full-Version: "73.3R8.2H.1"
Sec-CH-UA-Platform: "Windows"
```
User Agent Hints {#http-ua-hints}
================
The following sections define a number of HTTP request header fields that expose detail about a
given [=user agent=], which servers can opt-into receiving via the Client Hints infrastructure
defined in [[I-D.draft-ietf-httpbis-client-hints]]. The definitions below assume that each [=user agent=]
has defined a number of properties for itself:
* <dfn for="user agent" export>brand</dfn> - The [=user agent=]'s commercial name (for example:
"cURL", "Edge", "The World's Best Web Browser")
* <dfn for="user agent" export>significant version</dfn> - The [=user agent=]'s marketing version,
which includes distinguishable web-exposed features (for example: "72", "3", or "12.1")
* <dfn for="user agent" export>full version</dfn> - The [=user agent=]'s build version (for
example: "72.0.3245.12", "3.14159", or "297.70E04154A")
* <dfn for="user agent" export>platform brand</dfn> - The [=user agent=]'s operating system's
commercial name. (for example: "Windows", "iOS", or "AmazingOS")
* <dfn for="user agent" export>platform version</dfn> - The [=user agent=]'s operating system's
version. (for example: "NT 6.0", "15", or "17G")
* <dfn for="user agent" export>platform architecture</dfn> - The [=user agent=]'s underlying CPU
architecture (for example: "ARM64", or "ia32")
* <dfn for="user agent" export>model</dfn> - The [=user agent=]'s device model (for example: "",
or "Pixel 2 XL")
* <dfn for="user agent" export>mobileness</dfn> - A boolean indicating if the [=user agent=]'s
device is a mobile device. (for example: ?0 or ?1)
[=User agents=] SHOULD keep these strings short and to the point, but servers MUST accept arbitrary
values for each, as they are all values constructed at the [=user agent=]'s whim.
ISSUE: One of the problems that this document is attempting to solve is the unstructured nature of the
`User-Agent` field value. The document does not currently provide sufficient guidance to implementors
concerning the structure of each field value. The document should aim to be as explicit as those related
to other HTTP header values if it is to be successful in solving this problem.
[=User agents=] MUST map higher-entropy [=platform architecture=] values to the following buckets:
* x86 CPU architectures => "x86"
* ARM CPU architectures => "arm"
Other CPU architectures could be mapped into one of these values in case that makes sense, or be
mapped to the empty string.
ISSUE: There might be use-cases for higher-entropy, more specific CPU architectures (e.g. 32
vs. 64 bit architectures, or specific instruction sets for the download of highly optimized
executable binaries). If necessary, we could support those use-cases through one or more separate
hints.
[=User agents=] SHOULD return the empty string or a fictitious value for [=platform architecture=]
unless the user's platform is one where both the following conditions apply:
* Binary download of an executable is likely.
* Different CPU architectures are likely to require different binary executable resources, and
different binary executable resources are likely to be available.
[=User Agents=] MUST return the empty string for [=model=] if [=mobileness=] is false. [=User
Agents=] MUST return the empty string for [=model=] even if [=mobileness=] is true, except on
platforms where the model is typically exposed.
[=User agents=] MAY return the empty string or a fictitious value for [=full version=], [=platform
architecture=] or [=model=], for privacy, compatibility, or other reasons.
The 'Sec-CH-UA-Arch' Header Field {#sec-ch-arch}
------------------------------
The <dfn http-header>`Sec-CH-UA-Arch`</dfn> request header field gives a server information about
the architecture of the platform on which a given [=user agent=] is executing. It is a
[=Structured Header=] whose value MUST be a [=structured header/string=]
[[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
~~~ abnf
Sec-CH-UA-Arch = sh-string
~~~
The 'Sec-CH-UA-Model' Header Field {#sec-ch-model}
-------------------------------
The <dfn http-header>`Sec-CH-UA-Model`</dfn> request header field gives a server information about
the device on which a given [=user agent=] is executing. It is a [=Structured Header=] whose value MUST
be a [=structured header/string=] [[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
``` abnf
Sec-CH-UA-Model = sh-string
```
Where the model code may be shared among multiple model vendors the vendor MUST include a prefix prior
to the model code to identify the vendor.
The 'Sec-CH-UA-Platform' Header Field {#sec-ch-platform}
----------------------------------
The <dfn http-header>`Sec-CH-UA-Platform`</dfn> request header field gives a server information about
the platform on which a given [=user agent=] is executing. It is a [=Structured Header=] whose value
MUST be a [=structured header/string=] [[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
``` abnf
Sec-CH-UA-Platform = sh-string
```
The 'Sec-CH-UA-Platform-Version' Header Field {#sec-ch-platform-version}
----------------------------------
The <dfn http-header>`Sec-CH-UA-Platform-Version`</dfn> request header field gives a server
information about the platform version on which a given [=user agent=] is executing. It is a
[=Structured Header=] whose value MUST be a [=structured header/string=]
[[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
``` abnf
Sec-CH-UA-Platform-Version = sh-string
```
The 'Sec-CH-UA' Header Field {#sec-ch-ua}
----------------------------
The <dfn http-header>`Sec-CH-UA`</dfn> request header field gives a server information about a
[=user agent=]'s branding and version. It is a [=Structured Header=] whose value MUST be a
[=structured header/list=] [[I-D.ietf-httpbis-header-structure]]. The list's items MUST be
[=structured header/string=]. The value of each item SHOULD include a "v" parameter, indicating the
[=user agent=]'s version.
The header's ABNF is:
``` abnf
Sec-CH-UA = sh-list
```
Note: Unlike most Client Hints, since it's included in the <a
href="https://wicg.github.io/client-hints-infrastructure/#low-entropy-table">low-entropy table</a>,
the `Sec-CH-UA` header will be sent by default, whether or not the server opted-into
receiving the header via an `Accept-CH` header (although it can still be controlled by it's
<a href="https://wicg.github.io/client-hints-infrastructure/#policy-controlled-features">policy-controlled feature</a>.
It is considered low entropy because it includes only the [=user agent=]'s branding information,
and the significant version number (both of which are fairly clearly sniffable by "examining the
structure of other headers and by testing for the availability and semantics of the features
introduced or modified between releases of a particular browser" [[Janc2014]]).
ISSUE: What is the policy for classifying some Client Hints as being sent by default? Either all Client
Hints should be sent on every request, or no Client Hints sent on first request. If the rationale for
the specification is to limit entropy then sending a value will increase entropy for minority browser
vendors, whilst decrease it for dominate browser vendors. If the rationale is to address historic
issues with the `User-Agent` field value construction this could be better addressed via a simpler
specification to introduce a more modern convention for the field.
To <dfn abstract-op local-lt="set-ua">return the `Sec-CH-UA` value for a request</dfn>, [=user agents=] MUST:
1. Let |list| be a [=/list=], initially empty.
2. For each |brandVersion| in [=user agent/brands=]:
1. Let |parameter| be a [=dictionary=], initially empty.
2. Set |parameter|["param_name"] to "v".
3. Set |parameter|["param_value"] to |brandVersion|'s {{NavigatorUABrandVersion/version}}.
2. Let |pair| be a tuple comprised of |brandVersion|'s {{NavigatorUABrandVersion/brand}} and |parameter|.
3. Append |pair| to |list|.
3. Return the output of running <a href="https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html#ser-list">serializing a list</a> with |list| as input.
The 'Sec-CH-UA-Full-Version' Header Field {#sec-ch-full-version}
--------------------------------
The <dfn http-header>`Sec-CH-UA-Full-Version`</dfn> request header field gives a server information
about the user agent's [=user agent/full version=]. It is a [=Structured Header=]
whose value MUST be a [=structured header/string=] [[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
``` abnf
Sec-CH-UA-Full-Version = sh-string
```
The 'Sec-CH-UA-Mobile' Header Field {#sec-ch-mobile}
--------------------------------
The <dfn http-header>`Sec-CH-UA-Mobile`</dfn> request header field gives a server information about
whether or not a [=user agent=] prefers a "mobile" user experience. It is a [=Structured Header=]
whose value MUST be a [=structured header/boolean=] [[I-D.ietf-httpbis-header-structure]].
The header's ABNF is:
``` abnf
Sec-CH-UA-Mobile = sh-boolean
```
Note: Like `Sec-CH-UA` above, since it's included in the <a
href="https://wicg.github.io/client-hints-infrastructure/#low-entropy-table">low-entropy table</a>,
the `Sec-CH-UA-Mobile` header will be sent by default, whether or not the server opted-into
receiving the header via an `Accept-CH` header (although it can still be controlled by it's
<a href="https://wicg.github.io/client-hints-infrastructure/#policy-controlled-features">policy-controlled feature</a>.
It is considered low enropy because it is a single bit of information directly controllable
by the user.
Interface {#interface}
=================
<pre class="idl">
dictionary NavigatorUABrandVersion {
DOMString brand;
DOMString version;
};
dictionary UADataValues {
DOMString platform;
DOMString platformVersion;
DOMString architecture;
DOMString model;
DOMString uaFullVersion;
};
[Exposed=(Window,Worker)]
interface NavigatorUAData {
readonly attribute FrozenArray<NavigatorUABrandVersion> brands;
readonly attribute boolean mobile;
Promise<UADataValues> getHighEntropyValues(sequence<DOMString> hints);
};
interface mixin NavigatorUA {
[SecureContext] readonly attribute NavigatorUAData userAgentData;
};
Navigator includes NavigatorUA;
WorkerNavigator includes NavigatorUA;
</pre>
Note: The high-entropy portions of the user agent information are retrieved through a {{Promise}}, in order to give [=user agents=] the opportunity to gate their exposure behind potentially time-consuming checks (e.g. by asking the user for their permission).
Processing model {#processing}
--------------
<h3 id="monkeypatch-html-windoworworkerglobalscope"><code>WindowOrWorkerGlobalScope</code></h3>
Each [=user agent=] has an associated <dfn for="user agent">brands</dfn>, which is a [=/list=] created by running [=create brands=].
Every {{WindowOrWorkerGlobalScope}} object has an associated <dfn for="WindowOrWorkerGlobalScope">brands frozen array</dfn>, which is a <code><a interface>FrozenArray</a><<a dictionary>NavigatorUABrandVersion</a>></code>. It is initially the result of [=create a frozen array|creating a frozen array=] from the [=user agent=]'s [=brands=].
<h3 id="create-ua-list-section">Create brands</h3>
When asked to run the <dfn>create brands</dfn> algorithm, the [=user agent=] MUST run the following steps:
1. Let |list| be a [=/list=].
2. Collect pairs of [=user agent/brand=] and [=user agent/significant version=] which represent the [=user agent=],
its equivalence class and/or its rendering engine.
3. For each pair:
1. Let |dict| be a new {{NavigatorUABrandVersion}} dictionary,
with [=user agent/brand=] as {{NavigatorUABrandVersion/brand}} and [=user agent/significant version=] as {{NavigatorUABrandVersion/version}}.
2. Append |dict| to |list|.
4. The [=user agent=] SHOULD execute the following steps:
1. [=list/Append=] additional items to |list| containing {{NavigatorUABrandVersion}} objects,
initialized with arbitrary {{NavigatorUABrandVersion/brand}} and {{NavigatorUABrandVersion/version}} combinations.
2. Randomize the order of the items in |list|.
5. Return |list|.
<h3 id="getters">Getters</h3>
On getting, the {{NavigatorUAData/brands}} attribute MUST return [=this=]'s [=relevant global object=]'s [=WindowOrWorkerGlobalScope/brands frozen array=].
On getting, the {{NavigatorUAData/mobile}} attribute must return the [=user agent=]'s [=user agent/mobileness=].
<h3 id="getHighEntropyValues"><code>getHighEntropyValues</code> method</h3>
The <dfn method for="NavigatorUA"><code>getHighEntropyValues(|hints|)</code></dfn> method MUST run these steps:
1. Let |p| be a [=a new promise=] created in <a href="https://tc39.es/ecma262/#current-realm">the current realm</a>.
2. Run the following steps [=in parallel=]:
1. Let |uaData| be a new {{UADataValues}}.
2. If |hints| [=list/contains=] "platform", set |uaData|["{{UADataValues/platform}}"] to the [=user agent=]'s [=user agent/platform brand=].
3. If |hints| [=list/contains=] "platformVersion", set |uaData|["{{UADataValues/platformVersion}}"] to the [=user agent=]'s [=user agent/platform version=].
4. If |hints| [=list/contains=] "architecture", set |uaData|["{{UADataValues/architecture}}"] to the [=user agent=]'s [=user agent/platform architecture=].
5. If |hints| [=list/contains=] "model", set |uaData|["{{UADataValues/model}}"] to the [=user agent=]'s [=user agent/model=].
6. If |hints| [=list/contains=] "uaFullVersion", let |uaData|["{{UADataValues/uaFullVersion}}"] be the the user agent's [=user agent/full version=].
7. [=Queue a task=] on the [=permission task source=] to [=resolve=] |p| with |uaData|.
3. Return |p|.
Security and Privacy Considerations {#security-privacy}
===================================
Secure Transport {#secure-transport}
----------------
Client Hints will not be delivered to non-secure endpoints (see the secure transport requirements in
Section 2.2.1 of [[I-D.draft-ietf-httpbis-client-hints]]). This means that [=user agent=] information will not
be leaked over plaintext channels, reducing the opportunity for network attackers to build a profile
of a given agent's behavior over time.
Delegation {#delegation}
----------
Client Hints will be delegated from top-level pages via Feature Policy. This reduces the likelihood that [=user agent=]
information will be delivered along with sub-resource requests, which reduces the potential for
passive fingerprinting.
ISSUE: Reference Feature Policy on which this document relies.
That delegation is defined as part of <a href="https://wicg.github.io/client-hints-infrastructure/#abstract-opdef-append-client-hints-to-request">append client hints to request</a>.
Access Restrictions {#access}
-------------------
The information in the Client Hints defined above reveals quite a bit of information about the user
agent and the platform/device upon which it runs. [=User agents=] ought to exercise judgement before
granting access to this information, and MAY impose restrictions above and beyond the secure
transport and delegation requirements noted above. For instance, [=user agents=] could choose to reveal
[=user agent/platform architecture=] only on requests it intends to download, giving the server the
opportunity to serve the right binary. Likewise, they could offer users control over the values
revealed to servers, or gate access on explicit user interaction via a permission prompt or via a
settings interface.
ISSUE(https://www.w3.org/Consortium/mission): Is this compatible with the W3C One Web objective?
Restriction of access to information vital to the provision of some services seems problematic.
ISSUE: Some method of providing people control of the defaults they accept is needed to inform the
implementation of this feature [[CMA-UK]].
Implementation Considerations {#impl-considerations}
=============================
The 'User-Agent' Header {#user-agent}
-----------------------
[=User agents=] MUST NOT deprecate the `User-Agent` header in favor of the Client Hints model described in
this document until such time as Client Hints and all related specifications are ratified recommendations
of the W3C and/or IETF and all implementation and migration issues have been identified, the impacts to web
interoperability agreed, and mitigation options implemented.
The 'Sec-CH-' prefix {#sec-ch}
--------------------
Restricting user-land JavaScript code from influencing and modifying UA-CH headers has various
security related advantages. At the same time, there don't seem to be any legitimate
[use-cases](https://github.com/WICG/ua-client-hints#use-cases) which require such user-land rewriting.
As such and based on [discussions with the TAG](https://github.com/w3ctag/design-reviews/issues/320),
it seems reasonable to forbid write access to these headers from JavaScript (e.g. through `fetch` or
Service Workers), and demarcate them as browser-controlled client hints so they can be documented and
included in requests without triggering CORS preflights.
Therefore, request headers defined in this specification include a `Sec-CH-` prefix.
ISSUE: Expand specification to make the information available in this document available via JavaScript.
IANA Considerations {#iana}
===================
This document intends to define the `Sec-CH-UA-Arch`, `Sec-CH-UA-Model`, `Sec-CH-UA-Platform`,
`Sec-CH-UA-Platform-Version`, `Sec-CH-UA-Mobile` and `Sec-CH-UA` HTTP request header fields, and
register them in the permanent message header field registry ([[RFC3864]]).
'Sec-CH-UA-Arch' Header Field {#iana-arch}
--------------------------
Header field name:
: Sec-CH-UA-Arch
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-arch]])
'Sec-CH-UA-Model' Header Field {#iana-model}
---------------------------
Header field name:
: Sec-CH-UA-Model
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-ua]])
'Sec-CH-UA-Platform' Header Field {#iana-platform}
------------------------------
Header field name:
: Sec-CH-UA-Platform
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-platform]])
'Sec-CH-UA-Platform-Version' Header Field {#iana-platform-version}
------------------------------
Header field name:
: Sec-CH-UA-Platform-Version
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-platform]])
'Sec-CH-UA' Header Field {#iana-ua}
------------------------
Header field name:
: Sec-CH-UA
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-ua]])
'Sec-CH-UA-Mobile' Header Field {#iana-mobile}
----------------------------
Header field name:
: Sec-CH-UA-Mobile
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-mobile]])
'Sec-CH-UA-Full-Version' Header Field {#iana-full-version}
----------------------------
Header field name:
: Sec-CH-UA-Full-Version
Applicable protocol:
: http
Status:
: standard
Author/Change controller:
: IETF
Specification document:
: this specification ([[#sec-ch-full-version]])