forked from w3c/webauthn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.bs
3679 lines (2841 loc) · 205 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
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!-- *********** Web Authentication - Level 1 - Spec source file ***********
Notes:
* the h1 tag is spec title that is rendered within the document window. Wrapping
may be controlled with break tags. The spec 'Level' value is not appended.
* the Title metadata value is what is rendered in the browser's titlebar, any break
tags will be rendered. It also has the spec 'Level' value (gratuitously) appended.
-->
<h1>Web Authentication:<br>An API for accessing Public Key Credentials<br>Level 1</h1>
<pre class='metadata'>
Title: Web Authentication: An API for accessing Public Key Credentials - Level
Status: ED
Prepare for TR: true
TR: https://www.w3.org/TR/webauthn/
ED: https://w3c.github.io/webauthn/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170811/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170505/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170216/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20161207/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160928/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160902/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160531/
Shortname: webauthn
Level: 1
Editor: Vijay Bharadwaj, w3cid 55440, Microsoft, [email protected]
Editor: Hubert Le Van Gong, w3cid 84817, PayPal, [email protected]
Editor: Dirk Balfanz, w3cid 47648, Google, [email protected]
Editor: Alexei Czeskis, w3cid 87258, Google, [email protected]
Editor: Arnar Birgisson, w3cid 87332, Google, [email protected]
Editor: Jeff Hodges, w3cid 43843, PayPal, [email protected]
Editor: Michael B. Jones, w3cid 38745, Microsoft, [email protected]
Editor: Rolf Lindemann, w3cid 84447, Nok Nok Labs, [email protected]
Editor: J.C. Jones, w3cid 87240, Mozilla, [email protected]
group: webauthn
Issue Tracking: Github https://github.com/w3c/webauthn/issues
!Tests: <a href=https://github.com/w3c/web-platform-tests/tree/master/webauthn>web-platform-tests webauthn/</a> (<a href=https://github.com/w3c/web-platform-tests/labels/webauthn>ongoing work</a>)
Text Macro: RP Relying Party
Text Macro: RPS Relying Parties
Text Macro: INFORMATIVE <em>This section is not normative.</em>
Text Macro: WAC WebAuthn Client
Ignored Vars: op, alg, type, algorithm
Abstract: This specification defines an API enabling the creation and use of strong, attested, scoped, public key-based
credentials by web applications, for the purpose of strongly authenticating users. Conceptually, one or more [=public key
credentials=], each scoped to a given [=Relying Party=], are created and stored on an [=authenticator=] by the user agent in
conjunction with the web application. The user agent mediates access to [=public key credentials=] in order to preserve user
privacy. [=Authenticators=] are responsible for ensuring that no operation is performed without [=user consent=].
[=Authenticators=] provide cryptographic proof of their properties to [=relying parties=] via [=attestation=]. This
specification also describes the functional model for WebAuthn conformant [=authenticators=], including their signature and
[=attestation=] functionality.
Boilerplate: omit conformance, omit feedback-header, omit abstract-header
Markup Shorthands: css off, markdown on
</pre>
<pre class="anchors">
spec: ECMAScript; urlPrefix: https://tc39.github.io/ecma262/#
type: method
for: JSON; text: stringify; url: sec-json.stringify
type: dfn
text: %ArrayBuffer%; url: sec-arraybuffer-constructor
text: internal slot; url: sec-object-internal-methods-and-internal-slots
<!-- spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/ -->
spec: HTML52; urlPrefix: https://w3c.github.io/html/
type: dfn
urlPrefix: browsers.html
text: origin; url: concept-cross-origin
text: opaque origin; url: opaque-origin
text: tuple origin
text: document.domain; url:dom-document-domain
spec: TokenBinding; urlPrefix: https://tools.ietf.org/html/draft-ietf-tokbind-protocol#
type: dfn
text: Token Binding
text: Token Binding ID; url: section-3.2
spec: WebCryptoAPI; urlPrefix: https://www.w3.org/TR/WebCryptoAPI/
type: dfn
text: recognized algorithm name
<!-- Remove these once Shepherd picks up the changes -->
spec: credential-management-1; urlPrefix: https://w3c.github.io/webappsec-credential-management/
type: dictionary
text: CredentialCreationOptions; url: dictdef-credentialcreationoptions
type: dictionary
text: CredentialRequestOptions; url: dictdef-credentialrequestoptions
for: Credential
type: method
text: [[Create]](options)
for: CredentialsContainer
type: method
text: create(); url: dom-credentialscontainer-create
</pre> <!-- class=anchors -->
<pre class="link-defaults">
spec:html; type:dfn; for:environment settings object; text:global object
spec:infra; type:dfn; text:list
spec:url; type:dfn; text:domain
spec:url; type:dfn; for:url; text:host
spec:url; type:dfn; text:valid domain;
<!-- spec:webappsec-credential-management-1; type:dictionary; for:/; text:CredentialRequestOptions -->
spec:webidl; type:interface; text:Promise
</pre>
<pre class=biblio>
{
"IANA-COSE-ALGS-REG": {
"href": "https://www.iana.org/assignments/cose/cose.xhtml#algorithms",
"title": "IANA CBOR Object Signing and Encryption (COSE) Algorithms Registry",
"publisher": "IANA"
}
}
</pre>
# Introduction # {#intro}
[INFORMATIVE]
This specification defines an API enabling the creation and use of strong, attested, scoped, public key-based
credentials by web applications, for the purpose of strongly authenticating users. A [=public key credential=] is
created and stored by an <em>[=authenticator=]</em> at the behest of a <em>[=[RP]=]</em>, subject to <em>[=user
consent=]</em>. Subsequently, the [=public key credential=] can only be accessed by [=origins=] belonging to that [=[RP]=].
This scoping is enforced jointly by <em>[=conforming User Agents=]</em> and <em>[=authenticators=]</em>.
Additionally, privacy across [=[RPS]=] is maintained; [=[RPS]=] are not able to detect any properties, or even
the existence, of credentials scoped to other [RPS].
[=[RPS]=] employ the [=Web Authentication API=] during two distinct, but related, [=ceremonies=] involving a user. The first
is [=Registration=], where a [=public key credential=] is created on an [=authenticator=], and associated by a [=[RP]=]
with the present user's account (the account may already exist or may be created at this time). The second is
[=Authentication=], where the [=[RP]=] is presented with an <em>[=Authentication Assertion=]</em> proving the presence
and consent of the user who registered the [=public key credential=]. Functionally, the [=Web Authentication API=] comprises
a {{PublicKeyCredential}} which extends the Credential Management API [[CREDENTIAL-MANAGEMENT-1]], and infrastructure which
allows those credentials to be used with {{CredentialsContainer/create()|navigator.credentials.create()}} and
{{CredentialsContainer/get()|navigator.credentials.get()}}. The former is used during [=Registration=], and the
latter during [=Authentication=].
Broadly, compliant [=authenticators=] protect [=public key credentials=], and interact with user agents to implement the
[=Web Authentication API=]. Some authenticators may run on the same computing device (e.g., smart phone, tablet, desktop PC) as
the user agent is running on. For instance, such an authenticator might consist of a Trusted Execution Environment (TEE) applet,
a Trusted Platform Module (TPM), or a Secure Element (SE) integrated into the computing device in conjunction with some means
for [=user verification=], along with appropriate platform software to mediate access to these components' functionality. Other
authenticators may operate autonomously from the computing device running the user agent, and be accessed over a transport such
as Universal Serial Bus (USB), Bluetooth Low Energy (BLE) or Near Field Communications (NFC).
## Use Cases ## {#use-cases}
The below use case scenarios illustrate use of two very different types of [=authenticators=], as well as outline further
scenarios. Additional scenarios, including sample code, are given later in [[#sample-scenarios]].
### Registration ### {#usecase-registration}
- On a phone:
* User navigates to example.com in a browser and signs in to an existing account using whatever method they have been using
(possibly a legacy method such as a password), or creates a new account.
* The phone prompts, "Do you want to register this device with example.com?"
* User agrees.
* The phone prompts the user for a previously configured [=authorization gesture=] (PIN, biometric, etc.); the user
provides this.
* Website shows message, "Registration complete."
### Authentication ### {#usecase-authentication}
- On a laptop or desktop:
* User navigates to example.com in a browser, sees an option to "Sign in with your phone."
* User chooses this option and gets a message from the browser, "Please complete this action on your phone."
- Next, on their phone:
* User sees a discrete prompt or notification, "Sign in to example.com."
* User selects this prompt / notification.
* User is shown a list of their example.com identities, e.g., "Sign in as Alice / Sign in as Bob."
* User picks an identity, is prompted for an [=authorization gesture=] (PIN, biometric, etc.) and provides this.
- Now, back on the laptop:
* Web page shows that the selected user is signed-in, and navigates to the signed-in page.
### Other use cases and configurations ### {#other-configurations}
A variety of additional use cases and configurations are also possible, including (but not limited to):
- A user navigates to example.com on their laptop, is guided through a flow to create and register a credential on their phone.
- A user obtains an discrete, [=roaming authenticator=], such as a "fob" with USB or USB+NFC/BLE connectivity options, loads
example.com in their browser on a laptop or phone, and is guided though a flow to create and register a credential on the
fob.
- A [=[RP]=] prompts the user for their [=authorization gesture=] in order to authorize a single transaction, such as a payment
or other financial transaction.
# Conformance # {#conformance}
This specification defines criteria for a [=Conforming User Agent=]: A User Agent MUST behave as described in this
specification in order to be considered conformant. [=Conforming User Agents=] MAY implement algorithms given in this
specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the
specification's algorithms. A conforming User Agent MUST also be a conforming implementation of the IDL fragments of this
specification, as described in the “Web IDL” specification. [[!WebIDL-1]]
This specification also defines a model of a conformant [=authenticator=] (see [[#authenticator-model]]). This is a set of
functional and security requirements for an authenticator to be usable by a [=Conforming User Agent=]. As described in
[[#use-cases]], an authenticator may be implemented in the operating system underlying the User Agent, or in external hardware,
or a combination of both.
## Dependencies ## {#dependencies}
This specification relies on several other underlying specifications, listed
below and in [[#index-defined-elsewhere]].
: Base64url encoding
:: The term <dfn>Base64url Encoding</dfn> refers to the base64 encoding using the URL- and filename-safe character set defined
in Section 5 of [[!RFC4648]], with all trailing '=' characters omitted (as permitted by Section 3.2) and without the
inclusion of any line breaks, whitespace, or other additional characters.
: CBOR
:: A number of structures in this specification, including attestation statements and extensions, are encoded using the Compact
Binary Object Representation (<dfn>CBOR</dfn>) [[!RFC7049]].
: CDDL
:: This specification describes the syntax of all CBOR-encoded data using the CBOR Data Definition Language (CDDL) [[!CDDL]].
: COSE
:: CBOR Object Signing and Encryption (COSE) [[!RFC8152]]. The IANA COSE Algorithms registry established by this specification is also used.
: Credential Management
:: The API described in this document is an extension of the {{Credential}} concept defined in [[!CREDENTIAL-MANAGEMENT-1]].
: DOM
:: {{DOMException}} and the DOMException values used in this specification are defined in [[!DOM4]].
: ECMAScript
:: [=%ArrayBuffer%=] is defined in [[!ECMAScript]].
: HTML
:: The concepts of [=relevant settings object=], [=origin=],
[=opaque origin=], and [=is a registrable domain suffix of or is equal to=] are defined in [[!HTML52]].
: Web IDL
:: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL-1]]. This updated version of
the Web IDL standard adds support for {{Promise}}s, which are now the preferred mechanism for asynchronous
interaction in all new web APIs.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in [[!RFC2119]].
# Terminology # {#terminology}
: <dfn>Assertion</dfn>
:: See [=Authentication Assertion=].
: <dfn>Attestation</dfn>
:: Generally, <em>attestation</em> is a statement serving to bear witness, confirm, or authenticate.
In the WebAuthn context, [=attestation=] is employed to <em>attest</em> to the <em>provenance</em> of an [=authenticator=]
and the data it emits; including, for example: credential IDs, [=credential key pairs=], signature counters, etc. An
[=attestation statement=] is conveyed in an [=attestation object=] during [=registration=]. See also [[#sctn-attestation]]
and [Figure 3](#fig-attStructs).
: <dfn>Attestation Certificate</dfn>
:: A X.509 Certificate for the <dfn>attestation key pair</dfn> used by an [=authenticator=] to attest to its manufacture
and capabilities. At [=registration=] time, the [=authenticator=] uses the <dfn>attestation private key</dfn> to sign
the [=[RP]=]-specific [=credential public key=] (and additional data) that it generates and returns via the
[=authenticatorMakeCredential=] operation. [=[RPS]=] use the <dfn>attestation public key</dfn> conveyed in the [=attestation
certificate=] to verify the [=attestation signature=]. Note that in the case of [=self attestation=], the
[=authenticator=] has no distinct [=attestation key pair=] nor [=attestation certificate=], see [=self
attestation=] for details.
: <dfn>Authentication</dfn>
:: The [=ceremony=] where a user, and the user's computing device(s) (containing at least one [=authenticator=]) work in
concert to cryptographically prove to an [=[RP]=] that the user controls the [=credential private key=] associated with a
previously-registered [=public key credential=] (see [=Registration=]). Note that this typically includes employing a [=test
of user presence=] or [=user verification=].
: <dfn>Authentication Assertion</dfn>
:: The cryptographically signed {{AuthenticatorAssertionResponse}} object returned by an [=authenticator=] as the result of a
[=authenticatorGetAssertion=] operation.
: <dfn>Authenticator</dfn>
:: A cryptographic device used by a [=[WAC]=] to (i) generate a [=public key credential=] and register it with a [=[RP]=],
and (ii) subsequently used to cryptographically sign and return, in the form of an [=Authentication Assertion=], a
challenge and other data presented by a [=[RP]=] (in concert with the [=[WAC]=]) in order to effect
[=authentication=].
: <dfn>Authorization Gesture</dfn>
:: An [=authorization gesture=] is a physical interaction performed by a user with an authenticator as part of a [=ceremony=],
such as [=registration=] or [=authentication=]. By making such an [=authorization gesture=], a user [=user consent|provides
consent=] for (i.e., <em>authorizes</em>) a [=ceremony=] to proceed. This may involve [=user verification=] if the
employed [=authenticator=] is capable, or it may involve a simple [=test of user presence=].
: <dfn>Biometric Recognition</dfn
:: The automated recognition of individuals based on their biological and behavioral characteristics [[ISOBiometricVocabulary]].
: <dfn>Ceremony</dfn>
:: The concept of a [=ceremony=] [[Ceremony]] is an extension of the concept of a network protocol, with human nodes alongside
computer nodes and with communication links that include user interface(s), human-to-human communication, and transfers of
physical objects that carry data. What is out-of-band to a protocol is in-band to a ceremony. In this specification,
[=Registration=] and [=Authentication=] are ceremonies, and an [=authorization gesture=] is often a component of
those [=ceremonies=].
: <dfn>Client</dfn>
:: See [=Conforming User Agent=].
: <dfn>Client-Side</dfn>
:: This refers in general to the combination of the user's platform device, user agent, authenticators, and everything gluing
it all together.
: <dfn>Client-side-resident Credential Private Key</dfn>
:: A [=Client-side-resident Credential Private Key=] is stored either on the client platform, or in some cases on the
authenticator itself, e.g., in the case of a discrete first-factor roaming authenticator. Such <dfn>client-side credential
private key storage</dfn> has the property that the authenticator is able to select the [=credential private key=] given
only an [=RP ID=], possibly with user assistance (e.g., by providing the user a pick list of credentials associated with the RP
ID). By definition, the private key is always exclusively controlled by the Authenticator. In the case of a
[=Client-side-resident Credential Private Key=], the Authenticator might offload storage of wrapped key material to the
client platform, but the client platform is not expected to offload the key storage to remote entities (e.g. RP Server).
: <dfn>Conforming User Agent</dfn>
:: A user agent implementing, in conjunction with the underlying platform, the [=Web Authentication API=] and algorithms
given in this specification, and handling communication between [=authenticators=] and [=[RPS]=].
: <dfn>Credential Public Key</dfn>
:: The public key portion of an [=[RP]=]-specific <dfn>credential key pair</dfn>, generated by an [=authenticator=] and
returned to an [=[RP]=] at [=registration=] time (see also [=public key credential=]). The private key portion of the
[=credential key pair=] is known as the <dfn>credential private key</dfn>. Note that in the case of [=self
attestation=], the [=credential key pair=] is also used as the [=attestation key pair=], see [=self attestation=]
for details.
: <dfn>Rate Limiting</dfn>
:: The process (also known as throttling) by which an authenticator implements controls against brute force attacks by limiting
the number of consecutive failed authentication attempts within a given period of time. If the limit is reached, the
authenticator should impose a delay that increases exponentially with each successive attempt, or disable the current
authentication modality and offer a different authentication factor if available. Rate limiting is often implemented as an
aspect of [=user verification=].
: <dfn>Registration</dfn>
:: The [=ceremony=] where a user, a [=[RP]=], and the user's computing device(s) (containing at least one
[=authenticator=]) work in concert to create a [=public key credential=] and associate it with the user's [=[RP]=] account.
Note that this typically includes employing a [=test of user presence=] or [=user verification=].
: <dfn>[RP]</dfn>
:: The entity whose web application utilizes the [=Web Authentication API=] to register and authenticate users. See
[=Registration=] and [=Authentication=], respectively.
Note: While the term [=[RP]=] is used in other contexts (e.g., X.509 and OAuth), an entity acting as a [=[RP]=] in one
context is not necessarily a [=[RP]=] in other contexts.
: <dfn>Relying Party Identifier</dfn>
: <dfn>RP ID</dfn>
:: A [=valid domain string=] that identifies the [=[RP]=] on whose behalf a given [=registration=] or
[=authentication|authentication ceremony=] is being performed. A [=public key credential=] can only be used for
[=authentication=] with the same entity (as identified by [=RP ID=]) it was registered with. By default, the [=RP ID=] for a
WebAuthn operation is set to the caller's [=environment settings object/origin=]'s [=effective domain=]. This default MAY be
overridden by the caller, as long as the caller-specified [=RP ID=] value [=is a registrable domain suffix of or is equal
to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#createCredential]] and
[[#getAssertion]].
<div class="note" id="note-pkcredscope">
Note: A [=Public key credential=]'s scope is for a [=[RP]=]'s [=origin=], with the following <em>restrictions</em> and
<em>relaxations</em>:
- The scheme is always `https` (i.e., <em>a restriction</em>), and,
- the host may be equal to the [=[RP]=]'s [=origin=]'s [=effective domain=], or it may be equal to a registrable
domain suffix of the [=[RP]=]'s [=origin=]'s [=effective domain=] (i.e., <em>an available relaxation</em>), and,
- all (TCP) ports on that host (i.e., <em>a relaxation</em>).
This is done in order to match the behavior of pervasively deployed ambient credentials (e.g., cookies, [[RFC6265]]).
Please note that this is a greater relaxation of "same-origin" restrictions than what
[=document.domain=]'s setter provides.
</div>
: <dfn>Public Key Credential</dfn>
:: Generically, a <em>credential</em> is data one entity presents to another in order to <em>authenticate</em> the former to the
latter [[RFC4949]]. A WebAuthn <em>[=public key credential=]</em> is a <code>{ identifier, type }</code> pair identifying
authentication information established by the [=authenticator=] and the [=[RP]=], together, at [=registration=] time. The
authentication information consists of an asymmetric key pair, where the [=credential public key|public key portion=] is
returned to the [=[RP]=], who then stores it in conjunction with the present user's account. The [=authenticator=] maps the
[=credential private key|private key portion=] to the [=[RP]=]'s [=RP ID=] and stores it. Subsequently, only that [=[RP]=],
as identified by its [=RP ID=], is able to employ the [=public key credential=] in [=authentication|authentication
ceremonies=], via the {{CredentialsContainer/get()}} method. The [=[RP]=] uses its stored copy of the [=credential public
key=] to verify the resultant [=authentication assertion=].
: <dfn>Test of User Presence</dfn>
:: A [=test of user presence=] is a simple form of [=authorization gesture=] and technical process where a user interacts with
an [=authenticator=] by (typically) simply touching it (other modalities may also exist), yielding a boolean result. Note
that this does not constitute [=user verification=] because a [=test of user presence|user presence test=], by definition,
is not capable of [=biometric recognition=], nor does it involve the presentation of a shared secret such as a password or
PIN.
: <dfn>User Consent</dfn>
:: User consent means the user agrees with what they are being asked, i.e., it encompasses reading and understanding prompts.
An [=authorization gesture=] is a [=ceremony=] component often employed to indicate [=user consent=].
: <dfn>User Verification</dfn>
:: The technical process by which an [=authenticator=] <em>locally authorizes</em> the invocation of the
[=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations. [=User verification=] may be instigated
through various [=authorization gesture=] modalities; for example, through a touch plus pin code, password entry, or
[=biometric recognition=] (e.g., presenting a fingerprint) [[ISOBiometricVocabulary]]. The intent is to be able to
distinguish individual users. Note that invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=]
operations implies use of key material managed by the authenticator. Note that for security, [=user verification=] and use
of [=credential private keys=] must occur within a single logical security boundary defining the [=authenticator=].
: <dfn id=concept-user-present>User Present</dfn>
: <dfn>UP</dfn>
:: Upon successful completion of a [=test of user presence|user presence test=], the user is said to be
"[=user present|present=]".
: <dfn id=concept-user-verified>User Verified</dfn>
: <dfn>UV</dfn>
:: Upon successful completion of a [=user verification=] process, the user is said to be "[=user verified|verified=]".
: <dfn>[WAC]</dfn>
:: Also referred to herein as simply a [=client=]. See also [=Conforming User Agent=].
# <dfn>Web Authentication API</dfn> # {#api}
This section normatively specifies the API for creating and using [=public key credentials=]. The basic
idea is that the credentials belong to the user and are managed by an authenticator, with which the [=[RP]=] interacts through the
client (consisting of the browser and underlying OS platform). Scripts can (with the user's consent) request the browser to
create a new credential for future use by the [=[RP]=]. Scripts can also request the user’s permission to perform authentication
operations with an existing credential. All such operations are performed in the authenticator and are mediated by the browser
and/or platform on the user's behalf. At no point does the script get access to the credentials themselves; it only gets
information about the credentials in the form of objects.
In addition to the above script interface, the authenticator may implement (or come with client software that implements) a user
interface for management. Such an interface may be used, for example, to reset the authenticator to a clean state or to inspect
the current state of the authenticator. In other words, such an interface is similar to the user interfaces provided by browsers
for managing user state such as history, saved passwords and cookies. Authenticator management actions such as credential
deletion are considered to be the responsibility of such a user interface and are deliberately omitted from the API exposed to
scripts.
The security properties of this API are provided by the client and the authenticator working together. The authenticator, which
holds and manages credentials, ensures that all operations are scoped to a particular [=origin=], and cannot be replayed against
a different [=origin=], by incorporating the [=origin=] in its responses. Specifically, as defined in [[#authenticator-ops]],
the full [=origin=] of the requester is included, and signed over, in the [=attestation object=] produced when a new credential
is created as well as in all assertions produced by WebAuthn credentials.
Additionally, to maintain user privacy and prevent malicious [=[RPS]=] from probing for the presence of [=public key
credentials=] belonging to other [=[RPS]=], each [=public key credential|credential=] is also associated with a [=Relying Party
Identifier=], or [=RP ID=]. This [=RP ID=] is provided by the client to the [=authenticator=] for all operations, and the
[=authenticator=] ensures that [=public key credential|credentials=] created by a [=[RP]=] can only be used in operations
requested by the same [=RP ID=]. Separating the [=origin=] from the [=RP ID=] in this way allows the API to be used in cases
where a single [=[RP]=] maintains multiple [=origins=].
The client facilitates these security measures by providing the [=[RP]=]'s [=origin=] and [=RP ID=] to the [=authenticator=] for
each operation. Since this is an integral part of the WebAuthn security model, user agents only expose this API to callers in
[=secure contexts=].
The Web Authentication API is defined by the union of the Web IDL fragments presented in the following sections. A combined IDL
listing is given in the [[#idl-index]].
## <dfn interface>PublicKeyCredential</dfn> Interface ## {#iface-pkcredential}
The {{PublicKeyCredential}} interface inherits from {{Credential}} [[!CREDENTIAL-MANAGEMENT-1]], and contains the attributes
that are returned to the caller when a new credential is created, or a new assertion is requested.
<xmp class="idl">
[SecureContext]
interface PublicKeyCredential : Credential {
[SameObject] readonly attribute ArrayBuffer rawId;
[SameObject] readonly attribute AuthenticatorResponse response;
[SameObject] readonly attribute AuthenticationExtensions clientExtensionResults;
};
</xmp>
<dl dfn-type="attribute" dfn-for="PublicKeyCredential">
: {{Credential/id}}
:: This attribute is inherited from {{Credential}}, though {{PublicKeyCredential}} overrides {{Credential}}'s getter,
instead returning the [=base64url encoding=] of the data contained in the object's
{{PublicKeyCredential/[[identifier]]}} [=internal slot=].
: {{PublicKeyCredential/rawId}}
:: This attribute returns the {{ArrayBuffer}} contained in the {{PublicKeyCredential/[[identifier]]}} internal slot.
: <dfn>response</dfn>
:: This attribute contains the [=authenticator=]'s response to the client's request to either create a [=public key
credential=], or generate an [=authentication assertion=]. If the {{PublicKeyCredential}} is created in response to
{{CredentialsContainer/create()}}, this attribute's value will be an {{AuthenticatorAttestationResponse}}, otherwise,
the {{PublicKeyCredential}} was created in response to {{CredentialsContainer/get()}}, and this attribute's value
will be an {{AuthenticatorAssertionResponse}}.
: <dfn>clientExtensionResults</dfn>
:: This attribute contains a [=map=] containing [=extension identifier=] → [=client extension output=] entries
produced by the extension's [=client extension processing=].
: <dfn>\[[type]]</dfn>
:: The {{PublicKeyCredential}} [=interface object=]'s {{Credential/[[type]]}} [=internal slot=]'s value is the string
"`public-key`".
Note: This is reflected via the {{Credential/type}} attribute getter inherited from {{Credential}}.
: <dfn>\[[discovery]]</dfn>
:: The {{PublicKeyCredential}} [=interface object=]'s {{Credential/[[discovery]]}} [=internal slot=]'s value is
"{{Credential/[[discovery]]/remote}}".
: <dfn>\[[identifier]]</dfn>
:: This [=internal slot=] contains an identifier for the credential, chosen by the platform with help from the
authenticator. This identifier is used to look up credentials for use, and is therefore expected to be globally unique
with high probability across all credentials of the same type, across all authenticators. This API does not constrain
the format or length of this identifier, except that it must be sufficient for the platform to uniquely select a key.
For example, an authenticator without on-board storage may create identifiers containing a [=credential private key=]
wrapped with a symmetric key that is burned into the authenticator.
</dl>
{{PublicKeyCredential}}'s [=interface object=] inherits {{Credential}}'s implementation of
{{Credential/[[CollectFromCredentialStore]](options)}} and {{Credential/[[Store]](credential)}}, and defines its own
implementation of {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} and
{{PublicKeyCredential/[[Create]](options)}}.
### `CredentialCreationOptions` Extension ### {#credentialcreationoptions-extension}
To support registration via {{CredentialsContainer/create()|navigator.credentials.create()}}, this document extends
the {{CredentialCreationOptions}} dictionary as follows:
<pre class="idl">
partial dictionary CredentialCreationOptions {
MakePublicKeyCredentialOptions publicKey;
};
</pre>
### `CredentialRequestOptions` Extension ### {#credentialrequestoptions-extension}
To support obtaining assertions via {{CredentialsContainer/get()|navigator.credentials.get()}}, this document extends the
{{CredentialRequestOptions}} dictionary as follows:
<pre class="idl">
partial dictionary CredentialRequestOptions {
PublicKeyCredentialRequestOptions publicKey;
};
</pre>
### Create a new credential - PublicKeyCredential's `[[Create]](options)` method ### {#createCredential}
<div link-for-hint="PublicKeyCredential/[[Create]](options)">
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the
<dfn for="PublicKeyCredential" method>\[[Create]](options)</dfn> method allows scripts to call
{{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new [=credential key pair=]
and {{PublicKeyCredential}}, managed by an [=authenticator=]. The user agent will prompt the user for [=user consent|consent=].
On success, the returned {{promise}} will be resolved with a {{PublicKeyCredential}} containing an
{{AuthenticatorAttestationResponse}} object.
Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/create()|navigator.credentials.create()}}.
This method accepts a single argument:
<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[Create]](options)">
: <dfn>options</dfn>
:: This argument is a {{CredentialCreationOptions}} object whose
<code>|options|.{{CredentialCreationOptions/publicKey}}</code> member contains a {{MakePublicKeyCredentialOptions}} object
specifying the desired attributes of the to-be-created [=public key credential=].
</dl>
When this method is invoked, the user agent MUST execute the following algorithm:
1. Assert: <code>|options|.{{CredentialCreationOptions/publicKey}}</code> is [=present=].
1. Let |options| be the value of <code>|options|.{{CredentialCreationOptions/publicKey}}</code>.
1. If any of the {{PublicKeyCredentialEntity/name}} member of |options|.{{MakePublicKeyCredentialOptions/rp}}, the
{{PublicKeyCredentialEntity/name}} member of |options|.{{MakePublicKeyCredentialOptions/user}},
the {{PublicKeyCredentialUserEntity/displayName}} member of |options|.{{MakePublicKeyCredentialOptions/user}},
or the {{PublicKeyCredentialEntity/id}}
member of |options|.{{MakePublicKeyCredentialOptions/user}} are [=present|not present=], return a {{TypeError}} [=simple exception=].
1. If the {{MakePublicKeyCredentialOptions/timeout}} member of |options| is [=present=], check if its value lies within a
reasonable range as defined by the platform and if not, correct it to the closest value lying within that range. Set
|adjustedTimeout| to this adjusted value. If the {{MakePublicKeyCredentialOptions/timeout}} member of |options| is [=present|not
present=], then set |adjustedTimeout| to a platform-specific default.
1. Let |global| be the {{PublicKeyCredential}}'s [=interface object=]'s [=global object|environment settings object's global
object=].
1. Let |callerOrigin| be the [=environment settings object/origin=] specified by this {{PublicKeyCredential}} [=interface
object=]'s [=relevant settings object=]. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is
"{{NotAllowedError}}", and terminate this algorithm.
1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=].
If [=effective domain=] is not a [=valid domain=], then return a
{{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm.
Note: An [=effective domain=] may resolve to a [=host=], which can be represented in various manners,
such as [=domain=], [=ipv4 address=], [=ipv6 address=], [=opaque host=], or [=empty host=].
Only the [=domain=] format of [=host=] is allowed here.
1. Let |rpId| be |effectiveDomain|.
<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to compile w/o errors
-->
<li id='CreateCred-DetermineRpId'>
If |options|.{{MakePublicKeyCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} is [=present=]:
1. If |options|.{{MakePublicKeyCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} [=is not a registrable domain suffix of
and is not equal to=] |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate
this algorithm.
1. Set |rpId| to |options|.{{MakePublicKeyCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}}.
Note: |rpId| represents the caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment settings
object/origin=]'s [=effective domain=] unless the caller has explicitly set
|options|.{{MakePublicKeyCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} when calling
{{CredentialsContainer/create()}}.
</li>
1. Let |credTypesAndPubKeyAlgs| be a new [=list=] whose [=list/items=] are pairs of {{PublicKeyCredentialType}} and
a {{COSEAlgorithmIdentifier}}.
1. [=list/For each=] |current| of |options|.{{MakePublicKeyCredentialOptions/pubKeyCredParams}}:
1. If <code>|current|.{{PublicKeyCredentialParameters/type}}</code> does not contain a {{PublicKeyCredentialType}} supported
by this implementation, then [=continue=].
1. Let |alg| be <code>|current|.{{PublicKeyCredentialParameters/alg}}</code>.
1. [=list/Append=] the pair of <code>|current|.{{PublicKeyCredentialParameters/type}}</code> and |alg| to
|credTypesAndPubKeyAlgs|.
1. If |credTypesAndPubKeyAlgs| [=list/is empty=] and |options|.{{MakePublicKeyCredentialOptions/pubKeyCredParams}}
[=list/is not empty=], cancel the timer started in step 2, return a {{DOMException}} whose name is "{{NotSupportedError}}",
and terminate this algorithm.
1. Let |clientExtensions| be a new [=map=] and let |authenticatorExtensions| be a new [=map=].
1. If the {{MakePublicKeyCredentialOptions/extensions}} member of |options| is [=present=], then [=map/for each=]
|extensionId| → |clientExtensionInput| of <code>|options|.{{MakePublicKeyCredentialOptions/extensions}}</code>:
1. If |extensionId| is not supported by this client platform or is not a [=registration extension=], then [=continue=].
1. [=map/Set=] |clientExtensions|[|extensionId|] to |clientExtensionInput|.
1. If |extensionId| is not an [=authenticator extension=], then [=continue=].
1. Let |authenticatorExtensionInput| be the ([=CBOR=]) result of running |extensionId|'s [=client extension processing=]
algorithm on |clientExtensionInput|. If the algorithm returned an error, [=continue=].
1. [=map/Set=] |authenticatorExtensions|[|extensionId|] to the [=base64url encoding=] of |authenticatorExtensionInput|.
1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are:
: {{CollectedClientData/challenge}}
:: The [=base64url encoding=] of |options|.{{MakePublicKeyCredentialOptions/challenge}}.
: {{CollectedClientData/origin}}
:: The [=ascii serialization of an origin|serialization of=] |callerOrigin|.
: {{CollectedClientData/hashAlgorithm}}
:: The [=recognized algorithm name=] of the hash algorithm selected by the client for generating the
[=hash of the serialized client data=].
: {{CollectedClientData/tokenBindingId}}
:: The [=Token Binding ID=] associated with |callerOrigin|, if one is available.
: {{CollectedClientData/clientExtensions}}
:: |clientExtensions|
: {{CollectedClientData/authenticatorExtensions}}
:: |authenticatorExtensions|
1. Let |clientDataJSON| be the [=JSON-serialized client data=] constructed from |collectedClientData|.
1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.
1. Let |currentlyAvailableAuthenticators| be a new [=ordered set=] consisting of all [=authenticators=]
currently available on this platform.
1. Let |selectedAuthenticators| be a new [=ordered set=].
1. If |currentlyAvailableAuthenticators| [=list/is empty=], return a {{DOMException}} whose name is
"{{NotFoundError}}", and terminate this algorithm.
1. If |options|.{{MakePublicKeyCredentialOptions/authenticatorSelection}} is [=present|present=], iterate through
|currentlyAvailableAuthenticators| and do the following [=set/for each=] |authenticator|:
1. If {{AuthenticatorSelectionCriteria/aa}} is [=present|present=] and its value is not equal
to |authenticator|'s attachment modality, [=iteration/continue=].
1. If {{AuthenticatorSelectionCriteria/rk}} is set to |true| and the |authenticator|
is not capable of storing a [=Client-Side-Resident Credential Private Key=], [=iteration/continue=].
1. If {{AuthenticatorSelectionCriteria/uv}} is set to |true| and the
|authenticator| is not capable of performing [=user verification=], [=iteration/continue=].
1. [=set/Append=] |authenticator| to |selectedAuthenticators|.
1. If |selectedAuthenticators| [=list/is empty=], return a {{DOMException}} whose name is
"{{ConstraintError}}", and terminate this algoritm.
1. Let |issuedRequests| be a new [=ordered set=].
1. [=set/For each=] |authenticator| in |currentlyAvailableAuthenticators|:
1. Let |excludeCredentialDescriptorList| be a new [=list=].
1. [=list/For each=] credential descriptor |C| in <code>|options|.{{MakePublicKeyCredentialOptions/excludeCredentials}}</code>:
1. If <code>|C|.{{transports}}</code> [=list/is not empty=], and |authenticator| is connected over a transport not
mentioned in <code>|C|.{{transports}}</code>, the client MAY [=continue=].
1. Otherwise, [=list/Append=] |C| to |excludeCredentialDescriptorList|.
1. [=In parallel=], invoke the [=authenticatorMakeCredential=] operation on |authenticator| with |rpId|,
|clientDataHash|, |options|.{{MakePublicKeyCredentialOptions/rp}}, |options|.{{MakePublicKeyCredentialOptions/user}},
<code>|options|.{{MakePublicKeyCredentialOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/rk}}</code>,
|credTypesAndPubKeyAlgs|, |excludeCredentialDescriptorList|, and |authenticatorExtensions| as parameters.
1. [=set/Append=] |authenticator| to |issuedRequests|.
1. Start a timer for |adjustedTimeout| milliseconds. Then execute the following steps [=in parallel=]. The [=task source=] for
these [=tasks=] is the [=dom manipulation task source=].
1. While |issuedRequests| [=list/is not empty=], perform the following actions depending upon the |adjustedTimeout| timer and
responses from the authenticators:
<dl class="switch">
<dt>If the |adjustedTimeout| timer expires,</dt>
<dd>[=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
and [=set/remove=] |authenticator| from |issuedRequests|.</dd>
<dt>If any |authenticator| returns a status indicating that the user cancelled the operation,</dt>
<dd>
1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
</dd>
<dt>If any |authenticator| returns an error status,</dt>
<dd>[=set/Remove=] |authenticator| from |issuedRequests|.</dd>
<dt>If any |authenticator| indicates success,</dt>
<dd>
1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. Let |attestationObject| be a new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the
bytes of the value returned from the successful [=authenticatorMakeCredential=] operation (which is
<code>attObj</code>, as defined in [[#generating-an-attestation-object]]).
3. Let |id| be |attestationObject|<code>.authData.attestation data.credential ID</code> (see [[#sec-attestation-data]]
and [[#sec-authenticator-data]]).
4. Let |value| be a new {{PublicKeyCredential}} object associated with |global| whose fields are:
: {{PublicKeyCredential/[[identifier]]}}
:: |id|
: {{PublicKeyCredential/response}}
:: A new {{AuthenticatorAttestationResponse}} object associated with |global| whose fields are:
: {{AuthenticatorResponse/clientDataJSON}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of |clientDataJSON|.
: {{AuthenticatorAttestationResponse/attestationObject}}
:: |attestationObject|
: {{PublicKeyCredential/clientExtensionResults}}
:: A new {{AuthenticationExtensions}} object containing the [=extension identifier=] → [=client extension output=]
entries created by running each extension's [=client extension processing=] algorithm to create the [=client
extension outputs=], for each [=client extension=] in {{AuthenticatorResponse/clientDataJSON}}.clientExtensions.
5. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
6. Return |value| and terminate this algorithm.
</dd>
</dl>
1. Return a {{DOMException}} whose name is "{{NotAllowedError}}".
During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
authorizing an authenticator.
</div>
### Use an existing credential to make an assertion - PublicKeyCredential's `[[DiscoverFromExternalSource]](options)` method ### {#getAssertion}
<div link-for-hint="PublicKeyCredential/[[DiscoverFromExternalSource]](options)">
The <dfn for="PublicKeyCredential" method>\[[DiscoverFromExternalSource]](options)</dfn> method is used to discover and use an
existing [=public key credential=], with the user's consent. The script optionally specifies some criteria to indicate what
credentials are acceptable to it. The user agent and/or platform locates credentials matching the specified criteria, and guides
the user to pick one that the script will be allowed to use. The user may choose not to provide a credential even if one is
present, for example to maintain privacy.
Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/get()|navigator.credentials.get()}}.
This method accepts a single argument:
<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[DiscoverFromExternalSource]](options)">
: <dfn>options</dfn>
:: This argument is a {{CredentialRequestOptions}} object whose
<code>|options|.{{CredentialRequestOptions/publicKey}}</code> member contains a challenge and additional options as
described in [[#assertion-options]]. The selected authenticator signs the challenge along with other collected data in
order to produce an assertion. See [[#op-get-assertion]].
</dl>
When this method is invoked, the user agent MUST execute the following algorithm:
1. Assert: <code>|options|.{{CredentialRequestOptions/publicKey}}</code> is [=present=].
1. Let |options| be the value of <code>|options|.{{CredentialRequestOptions/publicKey}}</code>.
1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| is [=present=], check if its value lies
within a reasonable range as defined by the platform and if not, correct it to the closest value lying within that range.
Set |adjustedTimeout| to this adjusted value. If the {{PublicKeyCredentialRequestOptions/timeout}} member of
|options| is [=present|not present=], then set |adjustedTimeout| to a platform-specific default.
1. Let |global| be the {{PublicKeyCredential}}'s [=interface object=]'s [=global object|environment settings object's global
object=].
1. Let |callerOrigin| be the [=environment settings object/origin=] specified by this {{PublicKeyCredential}} [=interface
object=]'s [=relevant settings object=]. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is
"{{NotAllowedError}}", and terminate this algorithm.
1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=].
If [=effective domain=] is not a [=valid domain=], then return a
{{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm.
Note: An [=effective domain=] may resolve to a [=host=], which can be represented in various manners,
such as [=domain=], [=ipv4 address=], [=ipv6 address=], [=opaque host=], or [=empty host=].
Only the [=domain=] format of [=host=] is allowed here.
<li id='GetAssn-DetermineRpId'>
If |options|.{{PublicKeyCredentialRequestOptions/rpId}} is [=present|not present=], then set |rpId| to
|effectiveDomain|.
Otherwise:
1. If |options|.{{PublicKeyCredentialRequestOptions/rpId}} [=is not a registrable domain suffix of and is not
equal to=] |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate
this algorithm.
1. Set |rpId| to |options|.{{PublicKeyCredentialRequestOptions/rpId}}.
Note: |rpId| represents the caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment
settings object/origin=]'s [=effective domain=] unless the caller has explicitly set
|options|.{{PublicKeyCredentialRequestOptions/rpId}} when calling {{CredentialsContainer/get()}}.
</li>
1. Let |clientExtensions| be a new [=map=] and let |authenticatorExtensions| be a new [=map=].
1. If the {{PublicKeyCredentialRequestOptions/extensions}} member of |options| is [=present=], then [=map/for each=]
|extensionId| → |clientExtensionInput| of <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>:
1. If |extensionId| is not supported by this client platform or is not an [=authentication extension=], then [=continue=].
1. [=map/Set=] |clientExtensions|[|extensionId|] to |clientExtensionInput|.
1. If |extensionId| is not an [=authenticator extension=], then [=continue=].
1. Let |authenticatorExtensionInput| be the ([=CBOR=]) result of running |extensionId|'s [=client extension processing=]
algorithm on |clientExtensionInput|. If the algorithm returned an error, [=continue=].
1. [=map/Set=] |authenticatorExtensions|[|extensionId|] to the [=base64url encoding=] of |authenticatorExtensionInput|.
1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are:
: {{CollectedClientData/challenge}}
:: The [=base64url encoding=] of |options|.{{PublicKeyCredentialRequestOptions/challenge}}
: {{CollectedClientData/origin}}
:: The [=ascii serialization of an origin|serialization of=] |callerOrigin|.
: {{CollectedClientData/hashAlgorithm}}
:: The [=recognized algorithm name=] of the hash algorithm selected by the client for generating the
[=hash of the serialized client data=]
: {{CollectedClientData/tokenBindingId}}
:: The [=Token Binding ID=] associated with |callerOrigin|, if one is available.
: {{CollectedClientData/clientExtensions}}
:: |clientExtensions|
: {{CollectedClientData/authenticatorExtensions}}
:: |authenticatorExtensions|
1. Let |clientDataJSON| be the [=JSON-serialized client data=] constructed from |collectedClientData|.
1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.
1. Let |issuedRequests| be a new [=ordered set=].
1. If there are no [=authenticators=] currently available on this platform, return a {{DOMException}} whose name is
"{{NotFoundError}}", and terminate this algorithm.
1. Let |authenticator| be a platform-specific handle whose value identifies an [=authenticator=].
1. For each |authenticator| currently available on this platform, perform the following steps:
1. Let |allowCredentialDescriptorList| be a new [=list=].
1. If <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> [=list/is not empty=], execute a
platform-specific procedure to determine which, if any, [=public key credentials=] described by
<code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> are bound to this |authenticator|, by
matching with |rpId|,
<code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}</code>, and
<code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}</code>.
Set |allowCredentialDescriptorList| to this filtered list.
1. If |allowCredentialDescriptorList|
<dl class="switch">
: [=list/is not empty=]
:: 1. Let |distinctTransports| be a new [=ordered set=].
1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|,
[=set/append=] each value, if any, of <code>|C|.{{transports}}</code> to |distinctTransports|.
Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
|distinctTransports| due to the properties of [=ordered sets=].
1. If |distinctTransports|
<dl class="switch">
: [=list/is not empty=]
:: The client selects one |transport| value from |distinctTransports|, possibly incorporating local
configuration knowledge of the appropriate transport to use with |authenticator| in making its
selection.
Then, using |transport|, invoke [=in parallel=] the [=authenticatorGetAssertion=] operation on
|authenticator|, with |rpId|, |clientDataHash|, |allowCredentialDescriptorList|, and
|authenticatorExtensions| as parameters.
: [=list/is empty=]
:: Using local configuration knowledge of the appropriate transport to use with |authenticator|,
invoke [=in parallel=] the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|,
|clientDataHash|, |allowCredentialDescriptorList|, and |clientExtensions| as parameters.
</dl>
: [=list/is empty=]
:: Using local configuration knowledge of the appropriate transport to use with |authenticator|, invoke
[=in parallel=] the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, |clientDataHash|,
and |clientExtensions| as parameters.
Note: In this case, the [=[RP]=] did not supply a list of acceptable credential descriptors. Thus the
authenticator is being asked to exercise any credential it may possess that is bound to
the [=[RP]=], as identified by |rpId|.
</dl>
1. [=set/Append=] |authenticator| to |issuedRequests|.
1. Start a timer for |adjustedTimeout| milliseconds. Then execute the following steps [=in parallel=]. The [=task source=] for
these [=tasks=] is the [=dom manipulation task source=].
1. While |issuedRequests| [=list/is not empty=], perform the following actions depending upon the |adjustedTimeout| timer and
responses from the authenticators:
<dl class="switch">
<dt>If the |adjustedTimeout| timer expires,</dt>
<dd>[=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
and [=set/remove=] |authenticator| from |issuedRequests|.</dd>
<dt>If any |authenticator| returns a status indicating that the user cancelled the operation,</dt>
<dd>
1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
</dd>
<dt>If any |authenticator| returns an error status,</dt>
<dd>[=set/Remove=] |authenticator| from |issuedRequests|.</dd>
<dt>If any |authenticator| indicates success,</dt>
<dd>
1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. Let |value| be a new {{PublicKeyCredential}} associated with |global| whose fields are:
: {{PublicKeyCredential/[[identifier]]}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of the credential ID
returned from the successful [=authenticatorGetAssertion=] operation, as defined in [[#op-get-assertion]].
: {{PublicKeyCredential/response}}
:: A new {{AuthenticatorAssertionResponse}} object associated with |global| whose fields are:
: {{AuthenticatorResponse/clientDataJSON}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of |clientDataJSON|
: {{AuthenticatorAssertionResponse/authenticatorData}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of the returned
{{authenticatorData}}
: {{AuthenticatorAssertionResponse/signature}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of the returned
{{signature}}
: {{PublicKeyCredential/clientExtensionResults}}
:: A new {{AuthenticationExtensions}} object containing the [=extension identifier=] → [=client extension output=]
entries created by running each extension's [=client extension processing=] algorithm to create the [=client
extension outputs=], for each [=client extension=] in {{AuthenticatorResponse/clientDataJSON}}.clientExtensions.
3. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
4. Return |value| and terminate this algorithm.
</dd>
</dl>
1. Return a {{DOMException}} whose name is "{{NotAllowedError}}".
During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
authorizing an authenticator with which to complete the operation.
</div>
### Platform Authenticator Availability - PublicKeyCredential's `isPlatformAuthenticatorAvailable()` method ### {#isPlatformAuthenticatorAvailable}
<div link-for-hint="WebAuthentication/isPlatformAuthenticatorAvailable">
[=[RPS]=] use this method to determine whether they can create a new credential using a [=platform authenticator=].
Upon invocation, the [=client=] employs a platform-specific procedure to discover available [=platform authenticators=].
If successful, the [=client=] then assesses whether the user is willing to create a credential using one of the available [=platform authenticators=].
This assessment may include various factors, such as:
- Whether the user is running in private or incognito mode.
- Whether the user has configured the [=client=] to not create such credentials.
- Whether the user has previously expressed an unwillingness to create a new credential for this [=[RP]=],
either through configuration or by declining a user interface prompt.
- The user's explicitly stated intentions, determined through user interaction.
If this assessment is affirmative, the promise is resolved with the value of <i>True</i>.
Otherwise, the promise is resolved with the value of <i>False</i>.
Based on the result, the [=[RP]=] can take further actions to guide the user to create a credential.
This method has no arguments and returns a boolean value.
If the promise will return <i>False</i>,
the [=client=] SHOULD wait a fixed period of time from the invocation of the method before returning <i>False</i>.
This is done so that callers can not distinguish between
the case where the user was unwilling to create a credential using one of the available [=platform authenticators=] and
the case where no [=platform authenticator=] exists.
Trying to make these cases indistinguishable is done in an attempt to not provide additional information that could be used for fingerprinting.
A timeout value on the order of 10 minutes is recommended;
this is enough time for successful user interactions to be performed
but short enough that the dangling promise will still be resolved in a reasonably timely fashion.
<pre class="idl">
[SecureContext]
partial interface PublicKeyCredential {
[Unscopable] Promise < boolean > isPlatformAuthenticatorAvailable();
};
</pre>
</div>