forked from w3c/webauthn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.bs
9288 lines (7161 loc) · 553 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 3 - 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 3</h1>
<pre class='metadata'>
Title: Web Authentication: An API for accessing Public Key Credentials - Level 3
Status: ED
Prepare for TR: true
TR: https://www.w3.org/TR/webauthn-3/
ED: https://w3c.github.io/webauthn/
Previous Version: https://www.w3.org/TR/2021/REC-webauthn-2-20210408/
Previous Version: https://www.w3.org/TR/2019/REC-webauthn-1-20190304/
Shortname: webauthn
Level: 3
Include MDN Panels: maybe
Editor: Tim Cappalli, w3cid 111190, Okta, tim.cappalli@okta.com
Editor: Michael B. Jones, w3cid 38745, Self-Issued Consulting, michael_b_jones@hotmail.com
Editor: Akshay Kumar, w3cid 99318, Microsoft, akshayku@microsoft.com
Editor: Emil Lundberg, w3cid 102508, Yubico, emil@yubico.com
Editor: Matthew Miller, w3cid 129314, Cisco, mattmil3@cisco.com
Former Editor: Dirk Balfanz, w3cid 47648, Google, balfanz@google.com
Former Editor: Vijay Bharadwaj, w3cid 55440, Microsoft, vijay.bharadwaj@microsoft.com
Former Editor: Arnar Birgisson, w3cid 87332, Google, arnarb@google.com
Former Editor: Alexei Czeskis, w3cid 87258, Google, aczeskis@google.com
Former Editor: Jeff Hodges, w3cid 43843, formerly Google
Former Editor: J.C. Jones, w3cid 87240, formerly Mozilla
Former Editor: Hubert Le Van Gong, w3cid 84817, PayPal, hlevangong@paypal.com
Former Editor: Angelo Liao, w3cid 94342, Microsoft, huliao@microsoft.com
Former Editor: Rolf Lindemann, w3cid 84447, Nok Nok Labs, rolf@noknok.com
!Contributors: <a href="mailto:WebAuthn@ve7jtb.com">John Bradley</a> (Yubico)
!Contributors: <a href="mailto:cbrand@google.com">Christiaan Brand</a> (Google)
!Contributors: <a href="mailto:agl@google.com">Adam Langley</a> (Google)
!Contributors: <a href="mailto:mandyam@qti.qualcomm.com">Giridhar Mandyam</a> (Qualcomm)
!Contributors: <a href="mailto:pascoe@apple.com">Pascoe</a> (Apple)
!Contributors: <a href="mailto:nsatragno@google.com">Nina Satragno</a> (Google)
!Contributors: <a href="mailto:kieun.shin@sk.com">Ki-Eun Shin</a> (SK Telecom)
!Contributors: <a href="mailto:nick.steele@agilebits.com">Nick Steele</a> (1Password)
!Contributors: <a href="mailto:jiewen_tan@apple.com">Jiewen Tan</a> (Apple)
!Contributors: <a href="mailto:sweeden@au1.ibm.com">Shane Weeden</a> (IBM)
!Contributors: <a href="mailto:mkwst@google.com">Mike West</a> (Google)
!Contributors: <a href="mailto:jyasskin@google.com">Jeffrey Yasskin</a> (Google)
!Contributors: <a href="mailto:aaberg@bitwarden.com">Anders Åberg</a> (Bitwarden)
group: webauthn
Issue Tracking: GitHub https://github.com/w3c/webauthn/issues
!Tests: <a href=https://github.com/web-platform-tests/wpt/tree/master/webauthn>web-platform-tests webauthn/</a> (<a href=https://github.com/web-platform-tests/wpt/labels/webauthn>ongoing work</a>)
Text Macro: FALSE <code>false</code>
Text Macro: PII personally identifying information
Text Macro: RP Relying Party
Text Macro: RPS Relying Parties
Text Macro: INFORMATIVE <em>This section is not normative.</em>
Text Macro: TRUE <code>true</code>
Text Macro: WAA WebAuthn Authenticator
Text Macro: WAC WebAuthn Client
Text Macro: WRP WebAuthn Relying Party
Text Macro: WRPS WebAuthn Relying Parties
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 [=WebAuthn Relying Party=], are created by and [=bound credential|bound=] to
[=authenticators=] as requested by the web application. The user agent mediates access to [=authenticators=] and their [=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
Implementation Report: https://www.w3.org/2020/12/webauthn-report.html
</pre>
<style type="text/css">
body {
counter-reset: table;
}
/* For some reason, doing the counter-increment on the figcaption like Bikeshed does with figures does not seem to work here. */
figure.table {
counter-increment: table;
}
figure.table figcaption {
counter-increment: none;
}
figure.table figcaption:not(.no-marker)::before {
content: "Table " counter(table) " ";
}
figure.table .overlarge {
max-width: 50em;
}
.figure-num-following::before {
counter-increment: figure;
content: counter(figure)
}
.figure-num-following::after {
counter-increment: figure -1;
content: ""
}
.figure-num-previous::before {
content: counter(figure);
}
.table-ref-previous::before {
content: counter(table);
}
.table-ref-following::before {
counter-increment: table;
content: counter(table);
}
.table-ref-following::after {
counter-increment: table -1;
content: "";
}
</style>
<pre class="link-defaults">
spec: dom; type: interface; for:/; text: Document
</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
text: own property; url: sec-own-property
spec: RFC9052; urlPrefix: https://tools.ietf.org/html/rfc9052
type: dfn; for: RFC9052
text: COSE key; url: name-key-objects
text: kty; url: name-cose-key-common-parameters
text: section 7; url: section-7
spec: RFC9053; urlPrefix: https://tools.ietf.org/html/rfc9053
type: dfn; for: RFC9053
text: crv; url: name-double-coordinate-curves
text: section 2.1; url: section-2.1
text: section 2; url: section-2
text: section 7.1; url: section-7.1
spec: RFC8230; urlPrefix: https://tools.ietf.org/html/rfc8230
type: dfn; for: RFC8230
text: Section 4; url: section-4
text: Section 2; url: section-2
spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
type: dfn
urlPrefix: dom.html
for: Document; url: concept-document-permissions-policy; text: permissions policy
urlPrefix: browsers.html
text: browsing context; url: browsing-context
urlPrefix: origin.html
text: origin; url: concept-origin
text: opaque origin; url: concept-origin-opaque
text: tuple origin; url: concept-origin-tuple
text: document.domain; url:dom-document-domain
urlPrefix: form-control-infrastructure.html
text: autofill detail token; url: autofill-detail-tokens
text: non-autofill credential type; url: non-autofill-credential-type
spec: url; urlPrefix: https://url.spec.whatwg.org
type: dfn
text: scheme; url: concept-url-scheme
text: port; url: concept-url-port
spec: TokenBinding; urlPrefix: https://tools.ietf.org/html/rfc8471#
type: dfn
text: Token Binding; url: section-1
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: 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://w3c.github.io/geolocation-api/
type: interface
text: GeolocationCoordinates; 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: WHATWG URL; urlPrefix: https://url.spec.whatwg.org/
type: dfn
text: same site; url: host-same-site
spec: FIDO-CTAP; urlPrefix: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html
type: dfn
text: CTAP2 canonical CBOR encoding form; url: ctap2-canonical-cbor-encoding-form
text: §6. Authenticator API; url: authenticator-api
text: large, per-credential blobs; url: authenticatorLargeBlobs
spec: FIDO-APPID; urlPrefix: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.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
spec: FIDO-U2F-Message-Formats; urlPrefix: https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
type: dfn; for: FIDO-U2F-Message-Formats
text: application parameter; url: authentication-request-message---u2f_authenticate
text: Section 4.3; url: registration-response-message-success
text: Section 5.4; url: authentication-response-message-success
spec: FIDO-Registry; urlPrefix: https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html
type: dfn; for: FIDO-Registry
text: Section 3.1 User Verification Methods; url: user-verification-methods
text: Section 3.2 Key Protection Types; url: key-protection-types
text: Section 3.3 Matcher Protection Types; url: matcher-protection-types
text: Section 3.6.2 Public Key Representation Formats; url: public-key-representation-formats
spec: RFC4949; urlPrefix: https://tools.ietf.org/html/rfc4949
type: dfn
text: leap of faith; url: page-182
text: man-in-the-middle attack; url: page-186
text: salt; url: page-258
text: salted; url: page-258
spec: SP800-800-63r3; urlPrefix: https://pages.nist.gov/800-63-3/sp800-63-3.html
type: dfn
text: authentication factor; url: af
text: multi-factor; url: af
text: second-factor; url: af
text: single-factor; url: sf
text: something you know; url: af
text: something you have; url: af
text: something you are; url: af
spec: webdriver; urlPrefix: https://w3c.github.io/webdriver/
type: dfn
text: WebDriver error; url: dfn-error
text: WebDriver error code; url: dfn-error-code
text: endpoint node; url: dfn-endpoint-node
text: extension capability; url: dfn-extension-capability
text: extension command; url: dfn-extension-commands
text: getting a property; url: dfn-getting-properties
text: set a property; url: dfn-set-a-property
text: invalid argument; url: dfn-invalid-argument
text: matching capabilities; url: dfn-matching-capabilities
text: remote end steps; url: dfn-remote-end-steps
text: success; url: dfn-success
text: unsupported operation; url: dfn-unsupported-operation
text: validating capabilities; url: dfn-validate-capabilities
spec: RFC5280; urlPrefix: https://tools.ietf.org/html/rfc5280
type: dfn
text: SubjectPublicKeyInfo; url: section-4.1.2.7
spec: RFC8610; urlPrefix: https://tools.ietf.org/html/rfc8610
type: dfn
text: group sockets; url: section-3.9
spec: BCP47; urlPrefix: https://tools.ietf.org/html/bcp47
type: dfn
text: language tag; url: section-2.1
</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:html; type:dfn; for:/; text:same site
spec:infra; type:dfn; for:/; text:set
spec:infra; type:dfn; text:list
spec:infra; type:dfn; for:struct; text:item
spec:infra; type:dfn; for:map; text:exists
spec:url; type:dfn; text:domain
spec:url; type:dfn; for:url; text:host
spec:url; type:dfn; text:valid domain;
spec:webidl; type:dfn; text:DOMString
spec:webidl; type:dfn; text:USVString
spec:webidl; type:interface; text:Promise
</pre>
# Introduction # {#sctn-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 a <em>[=[WAA]=]</em> at the behest of a <em>[=[WRP]=]</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 [=scoped=] to a [=[RP]=]
with the present user's account (the account might already exist or might 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=].
Implementing compliant authenticators is possible in software executing
(a) on a general-purpose computing device,
(b) on an on-device Secure Execution Environment, Trusted Platform Module (TPM), or a Secure Element (SE), or
(c) off device.
Authenticators being implemented on device are called [=platform authenticators=].
Authenticators being implemented off device ([=roaming authenticators=]) can be accessed over a transport such
as Universal Serial Bus (USB), Bluetooth Low Energy (BLE), or Near Field Communications (NFC).
## Specification Roadmap ## {#sctn-spec-roadmap}
While many W3C specifications are directed primarily to user agent developers and also to web application developers
(i.e., "Web authors"), the nature of Web Authentication requires that this specification be correctly used by multiple audiences,
as described below.
**All audiences** ought to begin with [[#sctn-use-cases]], [[#sctn-sample-scenarios]], and [[#sctn-terminology]], and should also
refer to [[WebAuthnAPIGuide]] for an overall tutorial.
Beyond that, the intended audiences for this document are the following main groups:
- [=[RP]=] web application developers, especially those responsible for [=[RP]=] [=web application=] login flows, account recovery flows,
user account database content, etc.
- Web framework developers
- The above two audiences should in particular refer to [[#sctn-rp-operations]].
The introduction to [[#sctn-api]] may be helpful, though readers should realize that the [[#sctn-api]] section is targeted specifically
at user agent developers, not web application developers.
Additionally, if they intend to verify [=authenticator=] [=attestations=], then
[[#sctn-attestation]] and [[#sctn-defined-attestation-formats]] will also be relevant.
[[#sctn-extensions]], and [[#sctn-defined-extensions]] will be of interest if they wish to make use of extensions.
Finally, they should read [[#sctn-security-considerations-rp]] and [[#sctn-privacy-considerations-rp]]
and consider which challenges apply to their application and users.
- User agent developers
- OS platform developers, responsible for OS platform API design and implementation in regards to platform-specific
[=authenticator=] APIs, platform [=WebAuthn Client=] instantiation, etc.
- The above two audiences should read [[#sctn-api]] very carefully, along with [[#sctn-extensions]] if they intend to support extensions.
They should also carefully read
<!-- no sec cons for clients enumerated at this time
[[#sctn-security-considerations-client]] and
-->
[[#sctn-privacy-considerations-client]].
- [=Authenticator=] developers. These readers will want to pay particular attention to [[#sctn-authenticator-model]],
[[#sctn-defined-attestation-formats]], [[#sctn-extensions]], and [[#sctn-defined-extensions]].
They should also carefully read [[#sctn-security-considerations-authenticator]] and [[#sctn-privacy-considerations-authenticator]].
<div class="note">
Note: Along with the [[#sctn-api|Web Authentication API]] itself, this specification defines a
request-response <em>cryptographic protocol</em>—the
<dfn export>WebAuthn/FIDO2 protocol</dfn>—between
a [=[WRP]=] server and an [=authenticator=], where the [=[RP]=]'s request consists of a
[[#sctn-cryptographic-challenges|challenge]] and other
input data supplied by the [=[RP]=] and sent to the [=authenticator=].
The request is conveyed via the
combination of HTTPS, the [=[RP]=] [=web application=], the [[#sctn-api|WebAuthn API]], and the platform-specific communications channel
between the user agent and the [=authenticator=].
The [=authenticator=] replies with a digitally signed [=authenticator data=] message and other output data, which is conveyed back to the
[=[RP]=] server via the same path in reverse. Protocol details vary according to whether an [=authentication=] or
[=registration=] operation is invoked by the [=[RP]=].
See also [Figure 1](#fig-registration) and [Figure 2](#fig-authentication).
<strong>It is important for Web Authentication deployments' end-to-end security</strong> that the role of each
component—the [=[RP]=] server, the [=client=], and the [=authenticator=]—
as well as [[#sctn-security-considerations]] and [[#sctn-privacy-considerations]], are understood <em>by all audiences</em>.
</div>
## Use Cases ## {#sctn-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 [[#sctn-sample-scenarios]].
### Registration ### {#sctn-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 ### {#sctn-usecase-authentication}
- On a laptop or desktop:
* User pairs their phone with the laptop or desktop via Bluetooth.
* User navigates to example.com in a browser and initiates signing in.
* User 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 Mohamed / Sign in as 张三".
* 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.
### New Device Registration ### {#sctn-usecase-new-device-registration}
This use case scenario illustrates how a [=[RP]=] can leverage a combination of a [=roaming authenticator=] (e.g., a USB security
key fob) and a [=platform authenticator=] (e.g., a built-in fingerprint sensor) such that the user has:
- a "primary" [=roaming authenticator=] that they use to authenticate on new-to-them [=client devices=] (e.g., laptops,
desktops) or on such [=client devices=] that lack a [=platform authenticator=], and
- a low-friction means to strongly re-authenticate on [=client devices=] having [=platform authenticators=].
Note: This approach of registering multiple [=authenticators=] for an account is also useful in account recovery use cases.
- First, on a desktop computer (lacking a [=platform authenticator=]):
* 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.
* User navigates to account security settings and selects "Register security key".
* Website prompts the user to plug in a USB security key fob; the user does.
* The USB security key blinks to indicate the user should press the button on it; the user does.
* Website shows message, "Registration complete."
Note: Since this computer lacks a [=platform authenticator=], the website may require the user to present their USB security
key from time to time or each time the user interacts with the website. This is at the website's discretion.
- Later, on their laptop (which features a [=platform authenticator=]):
* User navigates to example.com in a browser and initiates signing in.
* Website prompts the user to plug in their USB security key.
* User plugs in the previously registered USB security key and presses the button.
* Website shows that the user is signed in, and navigates to the signed-in page.
* Website prompts, "Do you want to register this computer with example.com?"
* User agrees.
* Laptop prompts the user for a previously configured [=authorization gesture=] (PIN, biometric, etc.); the user provides this.
* Website shows message, "Registration complete."
* User signs out.
- Later, again on their laptop:
* User navigates to example.com in a browser and initiates signing in.
* Website shows message, "Please follow your computer's prompts to complete sign in."
* Laptop prompts the user for an [=authorization gesture=] (PIN, biometric, etc.); the user provides this.
* Website shows that the user is signed in, and navigates to the signed-in page.
### Other Use Cases and Configurations ### {#sctn-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 through 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.
## Sample API Usage Scenarios ## {#sctn-sample-scenarios}
[INFORMATIVE]
In this section, we walk through some events in the lifecycle of a [=public key credential=], along with the corresponding
sample code for using this API. Note that this is an example flow and does not limit the scope of how the API can be used.
As was the case in earlier sections, this flow focuses on a use case involving a [=passkey roaming authenticator=]
with its own display. One example of such an authenticator would be a smart phone. Other authenticator types are also supported
by this API, subject to implementation by the [=client platform=]. For instance, this flow also works without modification for the case of
an authenticator that is embedded in the [=client device=]. The flow also works for the case of an authenticator without
its own display (similar to a smart card) subject to specific implementation considerations. Specifically, the [=client platform=]
needs to display any prompts that would otherwise be shown by the authenticator, and the authenticator needs to allow the [=client
platform=] to enumerate all the authenticator's credentials so that the client can have information to show appropriate prompts.
### Registration ### {#sctn-sample-registration}
This is the first-time flow, in which a new credential is created and registered with the server.
In this flow, the [=[WRP]=] does not have a preference for [=platform authenticator=] or [=roaming authenticators=].
1. The user visits example.com, which serves up a script. At this point, the user may already be logged in using a legacy
username and password, or additional authenticator, or other means acceptable to the [=[RP]=].
Or the user may be in the process of creating a new account.
1. The [=[RP]=] script runs the code snippet below.
1. The [=client platform=] searches for and locates the authenticator.
1. The [=client=] connects to the authenticator, performing any pairing actions if necessary.
1. The authenticator shows appropriate UI for the user to provide a biometric or other [=authorization gesture=].
1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. If
the user declined to select an authenticator or provide authorization, an appropriate error is returned.
1. If a new credential was created,
- The [=[RP]=] script sends the newly generated [=credential public key=] to the server, along with additional information
such as attestation regarding the provenance and characteristics of the authenticator.
- The server stores the [=credential public key=] in its database and associates it with the user as well as with the
characteristics of authentication indicated by attestation, also storing a friendly name for later use.
- The script may store data such as the [=credential ID=] in local storage, to improve future UX by narrowing the choice of
credential for the user.
The sample code for generating and registering a new key follows:
<pre class="example" highlight="js">
if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
var publicKey = {
// The challenge is produced by the server; see the Security Considerations
challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),
// Relying Party:
rp: {
name: "ACME Corporation"
},
// User:
user: {
id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
name: "alex.mueller@example.com",
displayName: "Alex Müller",
},
// This Relying Party will accept either an ES256 or RS256 credential, but
// prefers an ES256 credential.
pubKeyCredParams: [
{
type: "public-key",
alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
},
{
type: "public-key",
alg: -257 // Value registered by this specification for "RS256"
}
],
authenticatorSelection: {
// Try to use UV if possible. This is also the default.
userVerification: "preferred"
},
timeout: 300000, // 5 minutes
excludeCredentials: [
// Don't re-register any authenticator that has one of these credentials
{"id": Uint8Array.from(window.atob("ufJWp8YGlibm1Kd9XQBWN1WAw2jy5In2Xhon9HAqcXE="), c=>c.charCodeAt(0)), "type": "public-key"},
{"id": Uint8Array.from(window.atob("E/e1dhZc++mIsz4f9hb6NifAzJpF1V4mEtRlIPBiWdY="), c=>c.charCodeAt(0)), "type": "public-key"}
],
// Make excludeCredentials check backwards compatible with credentials registered with U2F
extensions: {"appidExclude": "https://acme.example.com"}
};
// Note: The following call will cause the authenticator to display UI.
navigator.credentials.create({ publicKey })
.then(function (newCredentialInfo) {
// Send new credential info to server for verification and registration.
}).catch(function (err) {
// No acceptable authenticator or user refused consent. Handle appropriately.
});
</pre>
### Registration Specifically with User-Verifying Platform Authenticator ### {#sctn-sample-registration-with-platform-authenticator}
This is an example flow for when the [=[WRP]=] is specifically interested in creating a [=public key credential=] with
a [=user-verifying platform authenticator=].
1. The user visits example.com and clicks on the login button, which redirects the user to login.example.com.
1. The user enters a username and password to log in. After successful login, the user is redirected back to example.com.
1. The [=[RP]=] script runs the code snippet below.
1. The user agent checks if a [=user-verifying platform authenticator=] is available. If not, terminate this flow.
1. The [=[RP]=] asks the user if they want to create a credential with it. If not, terminate this flow.
1. The user agent and/or operating system shows appropriate UI and guides the user in creating a credential
using one of the available platform authenticators.
1. Upon successful credential creation, the [=[RP]=] script conveys the new credential to the server.
<pre class="example" highlight="js">
if (!window.PublicKeyCredential) { /* Client not capable of the API. Handle error. */ }
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
.then(function (uvpaAvailable) {
// If there is a user-verifying platform authenticator
if (uvpaAvailable) {
// Render some RP-specific UI and get a Promise for a Boolean value
return askIfUserWantsToCreateCredential();
}
}).then(function (userSaidYes) {
// If there is a user-verifying platform authenticator
// AND the user wants to create a credential
if (userSaidYes) {
var publicKeyOptions = { /* Public key credential creation options. */};
return navigator.credentials.create({ "publicKey": publicKeyOptions });
}
}).then(function (newCredentialInfo) {
if (newCredentialInfo) {
// Send new credential info to server for verification and registration.
}
}).catch(function (err) {
// Something went wrong. Handle appropriately.
});
</pre>
### Authentication ### {#sctn-sample-authentication}
This is the flow when a user with an already registered credential visits a website and wants to authenticate using the
credential.
1. The user visits example.com, which serves up a script.
1. The script asks the [=client=] for an Authentication Assertion, providing as much information as possible to narrow
the choice of acceptable credentials for the user. This can be obtained from the data that was stored locally after
registration, or by other means such as prompting the user for a username.
1. The [=[RP]=] script runs one of the code snippets below.
1. The [=client platform=] searches for and locates the authenticator.
1. The [=client=] connects to the authenticator, performing any pairing actions if necessary.
1. The authenticator presents the user with a notification that their attention is needed. On opening the
notification, the user is shown a friendly selection menu of acceptable credentials using the account information provided
when creating the credentials, along with some information on the [=origin=] that is requesting these keys.
1. The authenticator obtains a biometric or other [=authorization gesture=] from the user.
1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script.
If the user declined to select a credential or provide an authorization, an appropriate error is returned.
1. If an assertion was successfully generated and returned,
- The script sends the assertion to the server.
- The server examines the assertion, extracts the [=credential ID=], looks up the registered
credential public key in its database, and verifies the [=assertion signature=].
If valid, it looks up the identity associated with the assertion's [=credential ID=]; that
identity is now authenticated. If the [=credential ID=] is not recognized by the server (e.g.,
it has been deregistered due to inactivity) then the authentication has failed; each [=[RP]=]
will handle this in its own way.
- The server now does whatever it would otherwise do upon successful authentication -- return a success page, set
authentication cookies, etc.
If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of
credentials, then the sample code for performing such an authentication might look like this:
<pre class="example" highlight="js">
if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
// credentialId is generated by the authenticator and is an opaque random byte array
var credentialId = new Uint8Array([183, 148, 245 /* more random bytes previously generated by the authenticator */]);
var options = {
// The challenge is produced by the server; see the Security Considerations
challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
timeout: 300000, // 5 minutes
allowCredentials: [{ type: "public-key", id: credentialId }]
};
navigator.credentials.get({ "publicKey": options })
.then(function (assertion) {
// Send assertion to server for verification
}).catch(function (err) {
// No acceptable credential or user refused consent. Handle appropriately.
});
</pre>
On the other hand, if the [=[RP]=] script has some hints to help it narrow the list of credentials, then the sample code for
performing such an authentication might look like the following. Note that this sample also demonstrates how to use the [=credProps|Credential Properties Extension=].
<pre class="example" highlight="js">
if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
var encoder = new TextEncoder();
var acceptableCredential1 = {
type: "public-key",
id: encoder.encode("BA44712732CE")
};
var acceptableCredential2 = {
type: "public-key",
id: encoder.encode("BG35122345NF")
};
var options = {
// The challenge is produced by the server; see the Security Considerations
challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
timeout: 300000, // 5 minutes
allowCredentials: [acceptableCredential1, acceptableCredential2],
extensions: { 'credProps': true }
};
navigator.credentials.get({ "publicKey": options })
.then(function (assertion) {
// Send assertion to server for verification
}).catch(function (err) {
// No acceptable credential or user refused consent. Handle appropriately.
});
</pre>
### Aborting Authentication Operations ### {#sctn-sample-aborting}
The below example shows how a developer may use the AbortSignal parameter to abort a
credential registration operation. A similar procedure applies to an authentication operation.
<pre class="example" highlight="js">
const authAbortController = new AbortController();
const authAbortSignal = authAbortController.signal;
authAbortSignal.onabort = function () {
// Once the page knows the abort started, inform user it is attempting to abort.
}
var options = {
// A list of options.
}
navigator.credentials.create({
publicKey: options,
signal: authAbortSignal})
.then(function (attestation) {
// Register the user.
}).catch(function (error) {
if (error == "AbortError") {
// Inform user the credential hasn't been created.
// Let the server know a key hasn't been created.
}
});
// Assume widget shows up whenever authentication occurs.
if (widget == "disappear") {
authAbortController.abort();
}
</pre>
### Decommissioning ### {#sctn-sample-decommissioning}
The following are possible situations in which decommissioning a credential might be desired. Note that all of these are
handled on the server side and do not need support from the API specified here.
- Possibility #1 -- user reports the credential as lost.
* User goes to server.example.net, authenticates and follows a link to report a lost/stolen [=authenticator=].
* Server returns a page showing the list of registered credentials with friendly names as configured during registration.
* User selects a credential and the server deletes it from its database.
* In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions
signed by this credential are rejected.
- Possibility #2 -- server deregisters the credential due to inactivity.
* Server deletes credential from its database during maintenance activity.
* In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions
signed by this credential are rejected.
- Possibility #3 -- user deletes the credential from the [=authenticator=].
* User employs a [=authenticator=]-specific method (e.g., device settings UI) to delete a credential from their [=authenticator=].
* From this point on, this credential will not appear in any selection prompts, and no assertions can be generated with it.
* Sometime later, the server deregisters this credential due to inactivity.
## Platform-Specific Implementation Guidance ## {#sctn-platform-impl-guidance}
This specification defines how to use Web Authentication in the general case. When using Web
Authentication in connection with specific platform support (e.g. apps), it is recommended to see
platform-specific documentation and guides for additional guidance and limitations.
# Conformance # {#sctn-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 ## {#sctn-conforming-user-agents}
A User Agent MUST behave as described by [[#sctn-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]]
### Enumerations as DOMString types ### {#sct-domstring-backwards-compatibility}
Enumeration types are not referenced by other parts of the Web IDL because that
would preclude other values from being used without updating this specification
and its implementations. It is important for backwards compatibility that
[=client platforms=] and [=[RPS]=] handle unknown values. Enumerations for this
specification exist here for documentation and as a registry. Where the
enumerations are represented elsewhere, they are typed as {{DOMString}}s, for
example in {{PublicKeyCredentialDescriptor/transports}}.
## Authenticators ## {#sctn-conforming-authenticators}
A [=[WAA]=] 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 [[#sctn-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 ### {#sctn-conforming-authenticators-u2f}
[=Authenticators=] that only support the [[#sctn-fido-u2f-attestation]] have no mechanism to store a
[=user handle=], so the returned {{AuthenticatorAssertionResponse/userHandle}} will always be null.
## [WRPS] ## {#sctn-conforming-relying-parties}
A [=[WRP]=] MUST behave as described in [[#sctn-rp-operations]] to obtain all the security benefits offered by this specification. See
[[#sctn-rp-benefits]] for further discussion of this.
## All Conformance Classes ## {#sctn-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 # {#sctn-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>) [[!RFC8949]],
as defined in [[!FIDO-CTAP]].
: CDDL
:: This specification describes the syntax of all [=CBOR=]-encoded data using the CBOR Data Definition Language (<dfn>CDDL</dfn>) [[!RFC8610]].
: COSE
:: CBOR Object Signing and Encryption (COSE) [[!RFC9052]] [[!RFC9053]].
The IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]] originally established by [[!RFC8152 obsolete]] and updated by these specifications 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]].
: URL
:: The concepts of [=domain=], [=host=], [=port=], [=scheme=], [=valid domain=] and [=valid domain string=] are defined in [[!URL]].
: Web IDL
:: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL]]. 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|AppID extension=]) are defined by [[!FIDO-APPID]].
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",
"NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in
BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capitals, as shown here.
# Terminology # {#sctn-terminology}
: <dfn>Attestation</dfn>
:: Generally, <em>attestation</em> is a statement that serves to bear witness, confirm, or authenticate.
In the WebAuthn context, [=attestation=] is employed to provide verifiable evidence as to the origin of an [=authenticator=]
and the data it emits. This includes such things as [=credential IDs=], [=credential key pairs=], [=signature counters=], etc.
An [=attestation statement=] is provided within an [=attestation object=] during a [=registration=] ceremony. See also [[#sctn-attestation]]
and [Figure 6](#fig-attStructs). Whether or how the [=client=] conveys the [=attestation statement=] and [=authData/attestedCredentialData/aaguid=]
portions of the [=attestation object=] to the [=[RP]=] is described by [=attestation conveyance=].
: <dfn>Attestation Certificate</dfn>
:: An 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>
: <dfn>Authentication Ceremony</dfn>
:: The [=ceremony=] where a user, and the user's [=client platform=] (containing or connected to at least one [=authenticator=]) work in
concert to cryptographically prove to a [=[RP]=] that the user controls the [=credential private key=] of a
previously-registered [=public key credential=] (see [=Registration=]). Note that this includes a [=test of user presence=] or
[=user verification=].
The WebAuthn [=authentication ceremony=] is defined in [[#sctn-verifying-assertion]],
and is initiated by the [=[RP]=] invoking a <code>{{CredentialsContainer/get()|navigator.credentials.get()}}</code> operation
with a {{CredentialRequestOptions/publicKey}} argument.
See [[#sctn-api]] for an introductory overview and [[#sctn-sample-authentication]] for implementation examples.
: <dfn>Authentication Assertion</dfn>
: <dfn>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>
: <dfn>[WAA]</dfn>
:: A cryptographic entity, existing in hardware or software, that can [=registration|register=] a user with a given [=[RP]=]
and later [=Authentication Assertion|assert possession=] of the registered [=public key credential=], and optionally
[=user verification|verify the user=] to the [=[RP]=]. [=Authenticators=] can report information
regarding their [=authenticator types|type=] and security characteristics via [=attestation=] during [=registration=]
and [=assertion=].
A [=[WAA]=] could be a [=roaming authenticator=], a dedicated hardware subsystem integrated into the [=client device=],
or a software component of the [=client=] or [=client device=]. A [=[WAA]=] is not necessarily confined to operating in
a local context, and can generate or store a [=credential key pair=] in a server outside of [=client-side=] hardware.
In general, an [=authenticator=] is assumed to have only one user.
If multiple natural persons share access to an [=authenticator=],
they are considered to represent the same user in the context of that [=authenticator=].
If an [=authenticator=] implementation supports multiple users in separated compartments,
then each compartment is considered a separate [=authenticator=]
with a single user with no access to other users' [=credentials=].
: <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>Backed Up</dfn>
:: [=Public Key Credential Sources=] may be backed up in some fashion such that they may become present on an authenticator other
than their [=generating authenticator=]. Backup can occur via mechanisms including but not limited to peer-to-peer sync,
cloud sync, local network sync, and manual import/export. See also [[#sctn-credential-backup]].
: <dfn>Backup Eligibility</dfn>
: <dfn>Backup Eligible</dfn>
:: A [=Public Key Credential Source=]'s [=generating authenticator=] determines at creation time whether the [=public key credential source=]
is allowed to be [=backed up=]. Backup eligibility is signaled in [=authenticator data=]'s [=flags=] along with the current [=backup state=].
Backup eligibility is a [=credential property=] and is permanent for a given [=public key credential source=].
A backup eligible [=public key credential source=] is referred to as a <dfn>multi-device credential</dfn> whereas one that is not
backup eligible is referred to as a <dfn>single-device credential</dfn>. See also [[#sctn-credential-backup]].
: <dfn>Backup State</dfn>
:: The current backup state of a [=multi-device credential=] as determined by the current [=managing authenticator=]. Backup state is
signaled in [=authenticator data=]'s [=flags=] and can change over time. See also [=backup eligibility=] and [[#sctn-credential-backup]].
: <dfn>Biometric Authenticator</dfn>
:: Any [=authenticator=] that implements [=biometric recognition=].
: <dfn>Biometric Recognition</dfn>
:: The automated recognition of individuals based on their biological and behavioral characteristics [[ISOBiometricVocabulary]].
: <dfn>Bound credential</dfn>
: "Authenticator [=contains=] a credential"
: "Credential [=created on=] an authenticator"
:: A [=public key credential source=] or [=public key credential=] is said to be [=bound credential|bound=] to its [=managing
authenticator=]. This means that only the [=managing authenticator=] can generate [=assertions=] for the [=public key
credential sources=] [=bound credential|bound=] to it.
This may also be expressed as "the [=managing authenticator=] <dfn>contains</dfn> the [=bound credential=]",
or "the [=bound credential=] was <dfn>created on</dfn> its [=managing authenticator=]".
Note, however, that a [=server-side credential=] might not be physically stored in persistent memory inside the authenticator,
hence "[=bound credential|bound to=]" is the primary term.