forked from w3c/webauthn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
5056 lines (3904 loc) · 283 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/2018/WD-webauthn-20180306/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20171205/
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: Dirk Balfanz, w3cid 47648, Google, [email protected]
Editor: Alexei Czeskis, w3cid 87258, Google, [email protected]
Editor: Jeff Hodges, w3cid 43843, PayPal, [email protected]
Editor: J.C. Jones, w3cid 87240, Mozilla, [email protected]
Editor: Michael B. Jones, w3cid 38745, Microsoft, [email protected]
Editor: Akshay Kumar, w3cid 99318, Microsoft, [email protected]
Editor: Angelo Liao, w3cid 94342, Microsoft, [email protected]
Editor: Rolf Lindemann, w3cid 84447, Nok Nok Labs, [email protected]
Editor: Emil Lundberg, Yubico, [email protected]
Former Editor: Vijay Bharadwaj, w3cid 55440, Microsoft, [email protected]
Former Editor: Arnar Birgisson, w3cid 87332, Google, [email protected]
Former Editor: Hubert Le Van Gong, w3cid 84817, PayPal, [email protected]
!Contributors: <a href="mailto:[email protected]">Christiaan Brand</a> (Google)
!Contributors: <a href="mailto:[email protected]">Adam Langley</a> (Google)
!Contributors: <a href="mailto:[email protected]">Giridhar Mandyam</a> (Qualcomm)
!Contributors: <a href="mailto:[email protected]">Mike West</a> (Google)
!Contributors: <a href="mailto:[email protected]">Johan Verrept</a> (VASCO Data Security)
!Contributors: <a href="mailto:[email protected]">Jeffrey Yasskin</a> (Google)
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>
<!-- TODO: Clean out these anchor lists once they appear in Shepherd -->
<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
url: sec-object-internal-methods-and-internal-slots
text: internal method
text: internal slot
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: 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: [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
text: [[Create]](origin, options, sameOriginWithAncestors)
text: [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
text: [[Store]](credential, sameOriginWithAncestors)
for: CredentialsContainer
type: method
text: create(); url: dom-credentialscontainer-create
type: dfn
text: signal
text: same-origin with its ancestors; url: same-origin-with-its-ancestors
spec: Geolocation-API; urlPrefix: https://dev.w3.org/geo/api/spec-source.html
type: interface
text: Coordinates; url: coordinates_interface
spec: mixed-content; urlPrefix: www.w3.org/TR/mixed-content/
type: dfn
text: a priori authenticated
spec: page-visibility; urlPrefix: https://www.w3.org/TR/page-visibility/
type: dfn
text: visibility states
spec: WHATWG HTML; urlPrefix: https://html.spec.whatwg.org/
type: dfn
text: focus
text: username; url: attr-fe-autocomplete-username
spec: FIDO-CTAP; urlPrefix: https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
type: dfn
text: CTAP2 canonical CBOR encoding form; url: ctap2-canonical-cbor-encoding-form
spec: FIDO-APPID; urlPrefix: https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-appid-and-facets-v1.2-ps-20170411.html
type: dfn
text: determining the FacetID of a calling application; url: determining-the-facetid-of-a-calling-application
text: determining if a caller's FacetID is authorized for an AppID; url: determining-if-a-caller-s-facetid-is-authorized-for-an-appid
</pre> <!-- class=anchors -->
<!-- L128 spec:webappsec-credential-management-1; type:dictionary; for:/; text:CredentialRequestOptions -->
<pre class="link-defaults">
spec:credential-management; type:dfn; text:credentials
spec:html; type:dfn; for:environment settings object; text:global object
spec:infra; type:dfn; for:/; text:set
spec:infra; type:dfn; text:list
spec:infra; type:dfn; for:struct; text:item
spec:url; type:dfn; text:domain
spec:url; type:dfn; for:url; text:host
spec:url; type:dfn; text:valid domain;
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"
},
"Feature-Policy": {
"href": "https://wicg.github.io/feature-policy/",
"title": "Feature Policy",
"publisher": "WICG: Web Incubator Community Group",
"status": "Draft Community Group Report"
}
}
</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 [=user consent|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 a 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 three conformance classes. Each of these classes is specified so that conforming members of the class
are secure against non-conforming or hostile members of the other classes.
## User Agents ## {#conforming-user-agents}
A User Agent MUST behave as described by [[#api]] 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]]
## Authenticators ## {#conforming-authenticators}
An [=authenticator=] MUST provide the operations defined by [[#sctn-authenticator-model]], and those operations MUST behave as
described there. 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.
### Backwards Compatibility with FIDO U2F ### {#conforming-authenticators-u2f}
[=Authenticators=] that only support the [[#fido-u2f-attestation]] have no mechanism to store a
[=user handle=], so the returned {{AuthenticatorAssertionResponse/userHandle}} will always be null.
## [RPS] ## {#conforming-relying-parties}
A [=[RP]=] MUST behave as described in [[#rp-operations]] to obtain the security benefits offered by this specification.
## All Conformance Classes ## {#conforming-all-classes}
All [=CBOR=] encoding performed by the members of the above conformance classes MUST be done using the
[=CTAP2 canonical CBOR encoding form=].
All decoders of the above conformance classes SHOULD reject CBOR that is not validly encoded
in the [=CTAP2 canonical CBOR encoding form=] and SHOULD reject messages with duplicate map keys.
# 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
[=CTAP2 canonical CBOR encoding form=] of the Compact Binary Object Representation (<dfn>CBOR</dfn>) [[!RFC7049]],
as defined in [[!FIDO-CTAP]].
: 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.
: FIDO AppID
:: The algorithms for [=determining the FacetID of a calling application=] and
[=determining if a caller's FacetID is authorized for an AppID=] (used only in
the `appid` extension) are defined by [[!FIDO-APPID]].
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). Whether or how the client platform conveys the [=attestation statement=] and [=AAGUID=]
portions of the [=attestation object=] to the [=[RP]=] is described by [=attestation conveyance=].
: <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 a [=[RP]=] that the user controls the [=credential private key=] associated with a
previously-registered [=public key credential=] (see [=Registration=]). Note that this includes 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 an
[=authenticatorGetAssertion=] operation.
This corresponds to the [[CREDENTIAL-MANAGEMENT-1]] specification's single-use <a
spec="credential-management">credentials</a>.
: <dfn>Authenticator</dfn>
:: A cryptographic entity used by a [=[WAC]=] to (i) generate a [=public key credential=] and register it with a [=[RP]=],
and (ii) [=authentication|authenticate=] by potentially [=user verification|verifying the user=], and then
cryptographically signing and returning, in the form of an [=Authentication Assertion=],
a challenge and other data presented by a [=[RP]=] (in concert with the [=[WAC]=]).
: <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>Biometric Authenticator</dfn>
:: Any [=authenticator=] that implements [=biometric recognition=].
: <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 [=WebAuthn Client=], [=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 ID</dfn>
:: A probabilistically-unique [=byte sequence=] identifying a [=public key credential source=] and its [=authentication assertions=].
Credential IDs are generated by [=authenticators=] in two forms:
1. At least 16 bytes that include at least 100 bits of entropy, or
1. The [=public key credential source=], without its [=Credential ID=], encrypted so only its [=managing authenticator=] can
decrypt it. This form allows the [=authenticator=] to be nearly stateless, by having the [=[RP]=] store any necessary
state.
Note: [[FIDO-UAF-AUTHNR-CMDS]] includes guidance on encryption techniques under "Security Guidelines".
[=[RPS]=] do not need to distinguish these two [=Credential ID=] forms.
: <dfn>Credential Public Key</dfn>
:: The public key portion of a [=[RP]=]-specific <dfn>credential key pair</dfn>, generated by an [=authenticator=] and
returned to a [=[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>Human Palatability</dfn>
:: An identifier that is [=human palatability|human-palatable=] is intended to be rememberable and reproducible by typical human
users, in contrast to identifiers that are, for example, randomly generated sequences of bits [[EduPersonObjectClassSpec]].
: <dfn>Public Key Credential Source</dfn>
:: A [=credential source=] ([[CREDENTIAL-MANAGEMENT-1]]) used by an [=authenticator=] to generate [=authentication assertions=]. A [=public key credential source=] consists of a [=struct=] with the following [=struct/items=]:
<dl dfn-for="public key credential source">
: <dfn>type</dfn>
:: whose value is of {{PublicKeyCredentialType}}, defaulting to {{public-key}}.
: <dfn>id</dfn>
:: A [=Credential ID=].
: <dfn>privateKey</dfn>
:: The [=credential private key=].
: <dfn>rpId</dfn>
:: The [=Relying Party Identifier=], for the [=[RP]=] this [=public key credential source=] is associated with.
: <dfn>userHandle</dfn>
:: The [=user handle=] associated when this [=public key credential source=] was created. This [=struct/item=] is
nullable.
: <dfn>otherUI</dfn>
:: Optional other information used by the [=authenticator=] to inform its UI. For example, this might include the user's
{{displayName}}.
</dl>
The [=authenticatorMakeCredential=] operation creates a [=public key credential source=] bound to a <dfn for="public key
credential source">managing authenticator</dfn> and returns the [=credential public key=] associated with its [=credential
private key=]. The [=[RP]=] can use this [=credential public key=] to verify the [=authentication assertions=] created by
this [=public key credential source=].
: <dfn>Public Key Credential</dfn>
:: Generically, a *credential* is data one entity presents to another in order to *authenticate* the former to the latter
[[RFC4949]]. The term [=public key credential=] refers to one of: a [=public key credential source=], the
possibly-[=attestation|attested=] [=credential public key=] corresponding to a [=public key credential source=], or an
[=authentication assertion=]. Which one is generally determined by context.
<div class="note">
Note: This is a [=willful violation=] of [[RFC4949]]. In English, a "credential" is both a) the thing presented to prove
a statement and b) intended to be used multiple times. It's impossible to achieve both criteria securely with a single
piece of data in a public key system. [[RFC4949]] chooses to define a credential as the thing that can be used multiple
times (the public key), while this specification gives "credential" the English term's flexibility. This specification
uses more specific terms to identify the data related to an [[RFC4949]] credential:
: "Authentication information" (possibly including a private key)
:: [=Public key credential source=]
: "Signed value"
:: [=Authentication assertion=]
: [[RFC4949]] "credential"
:: [=Credential public key=] or [=attestation object=]
</div>
At [=registration=] time, the [=authenticator=] creates an asymmetric key pair, and stores its [=credential private
key|private key portion=] and information from the [=[RP]=] into a [=public key credential source=]. The [=credential public
key|public key portion=] is returned to the [=[RP]=], who then stores it in conjunction with the present user's account.
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>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 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>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 Handle</dfn>
:: The user handle is specified by a [=[RP]=] and is a unique identifier for a user account with that [=[RP]=]. A user handle is
an opaque [=byte sequence=] with a maximum size of 64 bytes.
The user handle is not meant to be displayed to the user, but is used by the [=[RP]=] to control the number of credentials - an
authenticator will never contain more than one credential for a given [=[RP]=] under the same user handle.
: <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=]. A [=[WAC]=] is an intermediary entity typically implemented in the user agent (in whole, or in part). Conceptually, it underlies the [=Web Authentication API=] and embodies the implementation of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=]. It is responsible for both marshalling the inputs for the underlying [=authenticator operations=], and for returning the results of the latter operations to the [=Web Authentication API=]'s callers.
# <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 consent|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, Exposed=Window]
interface PublicKeyCredential : Credential {
[SameObject] readonly attribute ArrayBuffer rawId;
[SameObject] readonly attribute AuthenticatorResponse response;
AuthenticationExtensionsClientOutputs getClientExtensionResults();
};
</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}}.
: {{PublicKeyCredential/getClientExtensionResults()}}
:: This operation returns the value of {{PublicKeyCredential/[[clientExtensionsResults]]}}, which is 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 the [=credential ID=], chosen by the platform with help from the authenticator.
The [=credential ID=] 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.
Note: 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.
: <dfn>\[[clientExtensionsResults]]</dfn>
:: This [=internal slot=] contains the results of processing client extensions requested by the [=[RP]=] upon the
[=[RP]=]'s invocation of either {{CredentialsContainer/create()|navigator.credentials.create()}} or
{{CredentialsContainer/get()|navigator.credentials.get()}}.
</dl>
{{PublicKeyCredential}}'s [=interface object=] inherits {{Credential}}'s implementation of
{{Credential/[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)}}, and defines its own
implementation of {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}, {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}, and
{{Credential/[[Store]](credential, sameOriginWithAncestors)}}.
### `CredentialCreationOptions` Dictionary 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 {
PublicKeyCredentialCreationOptions publicKey;
};
</pre>
### `CredentialRequestOptions` Dictionary 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]](origin, options, sameOriginWithAncestors)` method ### {#createCredential}
<div link-for-hint="PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)">
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the
<dfn for="PublicKeyCredential" method>\[[Create]](origin, options, sameOriginWithAncestors)</dfn> [=internal method=] [[CREDENTIAL-MANAGEMENT-1]] allows
[=[RP]=] scripts to call {{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new
[=public key credential source=], bound to an [=authenticator=]. This
{{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}};
see [[dom#abortcontroller-api-integration]] for detailed instructions.
This [=internal method=] accepts three arguments:
<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)">
: <dfn>origin</dfn>
:: This argument is the [=relevant settings object=]'s [=environment settings object/origin=], as determined by the
calling {{CredentialsContainer/create()}} implementation.
: <dfn>options</dfn>
:: This argument is a {{CredentialCreationOptions}} object whose
<code>|options|.{{CredentialCreationOptions/publicKey}}</code> member contains a {{PublicKeyCredentialCreationOptions}}
object specifying the desired attributes of the to-be-created [=public key credential=].
: <dfn>sameOriginWithAncestors</dfn>
:: This argument is a boolean which is true if and only if the caller's [=environment settings object=] is
[=same-origin with its ancestors=].
</dl>
Note: <strong>This algorithm is synchronous:</strong> the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/create()|navigator.credentials.create()}}.
When this method is invoked, the user agent MUST execute the following algorithm:
1. Assert: <code>|options|.{{CredentialCreationOptions/publicKey}}</code> is [=present=].
1. If <var ignore>sameOriginWithAncestors</var> is `false`, return a "{{NotAllowedError}}" {{DOMException}}.
Note: This "sameOriginWithAncestors" restriction aims to address the concern raised in the
[[CREDENTIAL-MANAGEMENT-1#security-origin-confusion|Origin Confusion]] section of [[CREDENTIAL-MANAGEMENT-1]],
while allowing [=[RP]=] script access to Web Authentication functionality, e.g., when running in
a [=secure context=] framed document that is [=same-origin with its ancestors=].
However, in the future, this specification (in conjunction with
[[CREDENTIAL-MANAGEMENT-1]]) may provide [=[RPS]=] with more fine-grained control--e.g., ranging
from allowing only top-level access to Web Authentication functionality,
to allowing cross-origin embedded cases--by leveraging
[[Feature-Policy]] once the latter specification becomes stably implemented in user agents.
1. Let |options| be the value of <code>|options|.{{CredentialCreationOptions/publicKey}}</code>.
1. If the {{PublicKeyCredentialCreationOptions/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 a timer
|lifetimeTimer| to this adjusted value. If the {{PublicKeyCredentialCreationOptions/timeout}} member of |options| is [=present|not
present=], then set |lifetimeTimer| to a platform-specific default.
1. Let |callerOrigin| be {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)/origin}}. 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.
<!-- 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 <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code>
<dl class="switch">
: Is [=present=]
:: If <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> [=is not a
registrable domain suffix of and is not equal to=] |effectiveDomain|, return a {{DOMException}} whose name
is "{{SecurityError}}", and terminate this algorithm.
: Is [=present|not present=]
:: Set <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> to
|effectiveDomain|.
</dl>
Note: <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> 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
<code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> 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 <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>:
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 <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>
[=list/is not empty=], 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 {{PublicKeyCredentialCreationOptions/extensions}} member of |options| is [=present=], then [=map/for each=]
|extensionId| → |clientExtensionInput| of <code>|options|.{{PublicKeyCredentialCreationOptions/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/type}}
:: The string "webauthn.create".
: {{CollectedClientData/challenge}}
:: The [=base64url encoding=] of |options|.{{PublicKeyCredentialCreationOptions/challenge}}.
: {{CollectedClientData/origin}}
:: The [=ascii serialization of an origin|serialization of=] |callerOrigin|.
: {{CollectedClientData/tokenBinding}}
:: The status of [=Token Binding=] between the client and the |callerOrigin|, as well as the [=Token Binding ID=] associated with |callerOrigin|, if one is available.
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. If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
[=AbortSignal/aborted flag=] is set to true, return a {{DOMException}} whose name is "{{AbortError}}"
and terminate this algorithm.
1. Start |lifetimeTimer|.
1. Let |issuedRequests| be a new [=ordered set=].
1. [=set/For each=] |authenticator| that becomes available on this platform during the lifetime of |lifetimeTimer|, do the
following:
Issue: The definitions of "lifetime of" and "becomes available" are intended to represent how
devices are hot-plugged into (USB) or discovered by (NFC) browsers, and are underspecified.
Resolving this with good definitions or some other means will be addressed by resolving
[Issue #613](https://github.com/w3c/webauthn/issues/613).
1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}</code> is [=present=]:
1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{authenticatorAttachment}}</code> is
[=present|present=] and its value is not equal to |authenticator|'s attachment modality, [=iteration/continue=].
1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}</code> is set to
`true` and the |authenticator| is not capable of storing a [=Client-Side-Resident Credential Private Key=],
[=iteration/continue=].
1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}</code> is
set to {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user
verification=], [=iteration/continue=].
1. Let |userVerification| be the <dfn>effective user verification requirement for credential creation</dfn>, a Boolean value,
as follows. If
<code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}</code>
<dl class="switch">
: is set to {{UserVerificationRequirement/required}}
:: Let |userVerification| be `true`.
: is set to {{UserVerificationRequirement/preferred}}
:: If the |authenticator|
<dl class="switch">
: is capable of [=user verification=]
:: Let |userVerification| be `true`.
: is not capable of [=user verification=]
:: Let |userVerification| be `false`.
</dl>
: is set to {{UserVerificationRequirement/discouraged}}
:: Let |userVerification| be `false`.
</dl>
1. Let |userPresence| be a Boolean value set to the inverse of |userVerification|.
1. Let |excludeCredentialDescriptorList| be a new [=list=].
1. [=list/For each=] credential descriptor |C| in <code>|options|.{{PublicKeyCredentialCreationOptions/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|.
<!-- @@EDITOR-ANCHOR-01A: KEEP THIS LIST SYNC'D WITH THE LIST UP AT @@EDITOR-ANCHOR-01B -->
1. Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with
|clientDataHash|,
<code>|options|.{{PublicKeyCredentialCreationOptions/rp}}</code>, <code>|options|.{{PublicKeyCredentialCreationOptions/user}}</code>,
<code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/requireResidentKey}}</code>,
|userPresence|,
|userVerification|,
|credTypesAndPubKeyAlgs|,
|excludeCredentialDescriptorList|,
and |authenticatorExtensions| as parameters.
1. [=set/Append=] |authenticator| to |issuedRequests|.
1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer| and responses from the
authenticators:
<dl class="switch">
: If |lifetimeTimer| expires,
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
and [=set/remove=] |authenticator| from |issuedRequests|.
: If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
[=AbortSignal/aborted flag=] is set to true,
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=]
operation on |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. Then return a {{DOMException}}
whose name is "{{AbortError}}" and terminate this algorithm.
: If any |authenticator| returns a status indicating that the user cancelled the operation,
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
Note: [=Authenticators=] may return an indication of "the user cancelled the entire operation".
How a user agent manifests this state to users is unspecified.
: If any |authenticator| returns an error status equivalent to "{{InvalidStateError}}",
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] it from |issuedRequests|.
1. Return a {{DOMException}} whose name is "{{InvalidStateError}}" and terminate this algorithm.
Note: This error status is handled separately because the |authenticator| returns it only if
|excludeCredentialDescriptorList| identifies a credential bound to the |authenticator| and the user has [=user
consent|consented=] to the operation. Given this explicit consent, it is acceptable for this case to be
distinguishable to the [=[RP]=].
: If any |authenticator| returns an error status not equivalent to "{{InvalidStateError}}",
:: [=set/Remove=] |authenticator| from |issuedRequests|.
Note: This case does not imply [=user consent=] for the operation, so details about the error must be hidden from the
[=[RP]=] in order to prevent leak of potentially identifying information. See [[#sec-make-credential-privacy]] for
details.
: If any |authenticator| indicates success,
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
1. Let |credentialCreationData| be a [=struct=] whose [=items=] are:
: <code><dfn for="credentialCreationData">attestationObjectResult</dfn></code>
:: whose value is the bytes returned from the successful [=authenticatorMakeCredential=] operation.
Note: this value is <code>attObj</code>, as defined in [[#generating-an-attestation-object]].
: <code><dfn for="credentialCreationData">clientDataJSONResult</dfn></code>
:: whose value is the bytes of |clientDataJSON|.
: <code><dfn for="credentialCreationData">attestationConveyancePreferenceOption</dfn></code>
:: whose value is the value of |options|.{{PublicKeyCredentialCreationOptions/attestation}}.
: <code><dfn for="credentialCreationData">clientExtensionResults</dfn></code>
:: whose value is an {{AuthenticationExtensionsClientOutputs}} object containing [=extension identifier=] →
[=client extension output=] entries. The entries are created by running each extension's
[=client extension processing=] algorithm to create the [=client extension outputs=], for each
[=client extension=] in <code>{{AuthenticatorResponse/clientDataJSON}}.clientExtensions</code>.
1. Let |constructCredentialAlg| be an algorithm that takes a [=global object=]
|global|, and whose steps are:
1. If <code>|credentialCreationData|.[=attestationConveyancePreferenceOption=]</code>'s value is
<dl class="switch">
: "none"
:: Replace potentially uniquely identifying information with non-identifying versions of the
same:
1. If the [=AAGUID=] in the [=attested credential data=] is 16 zero bytes, <code>|credentialCreationData|.[=attestationObjectResult=].fmt</code> is "packed", and "x5c" & "ecdaaKeyId" are both absent from <code>|credentialCreationData|.[=attestationObjectResult=]</code>, then [=self attestation=] is being used and no further action is needed.
1. Otherwise
1. Replace the [=AAGUID=] in the [=attested credential data=] with 16 zero bytes.
1. Set the value of <code>|credentialCreationData|.[=attestationObjectResult=].fmt</code> to "none", and set the value of <code>|credentialCreationData|.[=attestationObjectResult=].attStmt</code> to be an empty [=CBOR=] map. (See [[#none-attestation]] and [[#generating-an-attestation-object]]).
: "indirect"
:: The client MAY replace the [=AAGUID=] and [=attestation statement=] with a more privacy-friendly
and/or more easily verifiable version of the same data (for example, by employing an [=Anonymization CA=]).
: "direct"
:: Convey the [=authenticator=]'s [=AAGUID=] and [=attestation statement=], unaltered, to the RP.
Issue: @balfanz wishes to add to the "direct" case:
If the [=authenticator=] violates the privacy requirements of the [=attestation type=] it is using,
the client SHOULD terminate this algorithm with an "AttestationNotPrivateError".
</dl>
1. Let |attestationObject| be a new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the
bytes of <code>|credentialCreationData|.[=attestationObjectResult=]</code>'s value.