-
Notifications
You must be signed in to change notification settings - Fork 1
/
draft-thornburgh-fwk-dc-token-iss.xml
932 lines (737 loc) · 37.6 KB
/
draft-thornburgh-fwk-dc-token-iss.xml
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
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='rfc7749.xslt' ?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc ipr="trust200902" docName="draft-thornburgh-fwk-dc-token-iss-01"
submissionType="independent" category="exp" version="3"
xmlns:xi="http://www.w3.org/2001/XInclude">
<front>
<title abbrev="Decentralized Token Issuance">A Framework For Decentralized Bearer Token Issuance in HTTP</title>
<seriesInfo name="Internet-Draft" status="experimental" stream="independent" value="draft-thornburgh-fwk-dc-token-iss-01"/>
<author initials="M" surname="Thornburgh" fullname="Michael C. Thornburgh">
<address>
<postal>
<city>Santa Cruz</city>
<region>CA</region>
<code>95060-1950</code>
<country>US</country>
</postal>
<email>zenomt@zenomt.com</email>
<uri>https://zenomt.zenomt.com/card.ttl#me</uri>
</address>
</author>
<workgroup>Independent Submission</workgroup>
<abstract><t>
This memo describes a protocol framework for HTTP clients to
obtain bearer tokens for accessing restricted resources, where
in some applications the client may not have prior knowledge
of, or a direct relationship with, the resource server's
authorization infrastructure (such as in decentralized identity
systems). Semi-concrete applications of the framework using
proof-of-possession and TLS client certificate mechanisms are
also described.
</t></abstract>
</front>
<middle>
<section title="Introduction">
<t>This memo describes a general protocol framework for HTTP clients to obtain
bearer tokens (<relref section="1.2" target="RFC6750" displayFormat="of" />)
from a resource server's authorization service in order to access protected
resources on the server. This framework is especially intended for systems
(such as decentralized identity systems like <xref target="WebID"/>, and
decentralized social or mashup data systems like the
<eref target="https://solidproject.org">Solid project</eref>) where
the client might not have prior knowledge of, or a preexisting direct
relationship with, the authorization service for the resource server; however,
it can be applied in other use cases as well.</t>
<t>The protocol includes a method for the client to discover the nature(s)
of principals (such as identities, capabilities, sender-constrained access
tokens, or verifiable credentials) that the server expects to interact with,
and methods for the client to discover the API endpoint URIs for multiple potential
mechanisms for obtaining bearer tokens. The framework is constructed to mitigate
man-in-the-middle token-stealing attacks.</t>
<t>This memo defines two mechanisms within the framework for a client to
obtain a bearer token: one using a cryptographic proof-of-possession, and one
using <xref target="RFC8446">TLS</xref> client certificates. These mechanisms
retain generality, and must be further refined in other specifications according
to the application and the nature of the principals expected by the servers.
Other mechanisms within the framework are also possible.</t>
<section title="Motivation">
<t>This work was originally motivated by a desire to address security, semantic,
and operational shortcomings in an experimental, decentralized, application-layer
authentication scheme for the
<eref target="https://solidproject.org">Solid project</eref> that was based on
<xref target="WebID" />,
<xref target="OpenID.Core">OpenID Connect</xref>, and
<xref target="RFC7800">proof-of-possession key semantics</xref>.</t>
<t>An explicit goal of the solution is to leverage the benefits of bearer
tokens for accessing restricted resources:</t>
<ul>
<li>The token can encapsulate (by direct encoding or by reference)
exactly and only the implementation-specific and deployment-specific
properties needed to make access control decisions in the
resource server;</li>
<li><t>The effort (including computational, cryptographic, and network)
required to establish a client's identity and authorizations
can be done once by the client and the authorization service,
compiled to a token, and this effort amortized over many
requests to the same resource server, with simple revalidation
and lifetime semantics that can be influenced by both parties;
specifically:</t>
<ul>
<li>The server's authorization system chooses an expiration
period for the token, and can also revoke it at any time,
to cause a reauthentication and revalidation;</li>
<li>The client can forget the token at any time and acquire a new
one to cause a reauthentication and revalidation;
this can be particularly advantageous if the
client acquires new privileges, authorizations,
or endorsements that might otherwise be subject
to unknown caching policies in an access
controller;</li>
</ul></li>
<li>The representation of the token can be optimized for network
transmission and for decoding, verification, and processing
according to the server's implementation;</li>
<li>HTTP header compression schemes such as
<xref target="RFC7541">HPACK</xref> can reduce network resource
consumption when a token is reused for multiple requests in
the same origin.</li>
</ul>
<t>As work progressed, a general form emerged that could address multiple use
cases beyond the original motivator.</t>
<section title="Use Cases">
<t>It is envisioned that the framework described in this memo can be used in
at least the following cases, with appropriate further specification, to
realize the benefits listed above:</t>
<ul>
<li>Decentralized identity systems such as WebID and
<xref target="DID">Decentralized Identifiers</xref>;</li>
<li>Centralized or decentralized authorization systems based on
<xref target="VC">Verifiable Credentials</xref>;</li>
<li>Authenticated access to a multitude of decentralized, uncoordinated
resource servers, such as for social or mashup data
applications;</li>
<li>Identity systems based on aspects of a TLS client certificate,
without requiring use of that certificate for all accesses
to a resource server (particularly in browser-based applications,
to allow selective unauthenticated access to non-protected
resources within the limitations of negotiating client
certificates in TLS);</li>
<li>Obtaining an audience-constrained bearer token given a
sender-constrained access credential or capability issued by
a central authority;</li>
<li>Obtaining an audience-constrained bearer token in a centralized,
federated, or confederated identity system given an identity
bound with a pre-shared public key.</li>
</ul>
<t>This list of use cases should not be construed as exhaustive or limiting.
Other effective applications of this framework are possible.</t>
</section> <!-- Use Cases -->
</section> <!-- Motivation -->
<section title="Terminology">
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
"<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>",
"<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>",
"<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>"
in this document are to be interpreted as described in BCP 14
<xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
<t>The term "bearer token" in this document has the meaning described in
<xref target="RFC6750" />.</t>
<t>The term "protection space" in this document has the meaning described in
<relref section="2.2" target="RFC7235" displayFormat="of"/>.</t>
</section> <!-- Terminology -->
</section> <!-- Introduction -->
<section title="General Framework">
<t>The server challenges an unauthenticated client
(<relref section="2.1" target="RFC7235" displayFormat="of" />) with an HTTP
<tt>401</tt> response, including a <tt>WWW-Authenticate</tt> response header
with the <tt>Bearer</tt> <em>auth-scheme</em>
(<relref section="3" target="RFC6750" displayFormat="of" />),
and comprising parameters including how to use one or more token acquisition
mechanisms.
The client examines the challenge and determines which mechanisms, if any,
it is able to use to acquire a bearer token. If possible, the client uses a
compatible mechanism, including attributes of the original request and the
challenge, to request a bearer token. The token will have a stated lifetime
and will be valid for accesses within the same protection space as the original
request, until the token expires or is revoked.
</t>
<t>A <tt>WWW-Authenticate</tt> challenge for any mechanism includes at least
these <em>auth-params</em>:</t>
<dl>
<dt><tt>scope</tt></dt><dd><bcp14>REQUIRED</bcp14>: A space-delimited
list of case-sensitive strings, each a well-known or
server-defined value indicating the nature(s) of the principal
expected to be used when requesting a bearer token. To avoid
ambiguity, server-defined scopes <bcp14>SHOULD</bcp14> be
URIs.</dd>
<dt><tt>nonce</tt></dt><dd><bcp14>REQUIRED</bcp14>: An opaque (to the
client) string to be included unmodified when requesting a
bearer token. See <xref target="nonce_considerations" /> for
considerations on constructing the challenge nonce.</dd>
<dt><tt>error</tt></dt><dd><t>If present, a reason code indicating that
the request had a problem other than not presenting an access
token. The following reason codes are initially defined:</t>
<dl>
<dt><tt>invalid_token</tt></dt><dd>A bearer token
was presented, but it was expired, revoked,
or otherwise not recognized as valid.</dd>
<dt><tt>proof_required</tt></dt><dd>An access token
requiring proof-of-possession of a key (but
potentially otherwise valid) was presented.</dd>
</dl></dd>
</dl>
<t>Additionally, one or more mechanism-specific <em>auth-params</em> are
included in the challenge to indicate the availability of that mechanism and
its unique parameters (usually the URI at which to use the mechanism). This
memo defines two mechanism-specific <em>auth-params</em>:</t>
<dl>
<dt><tt>token_pop_endpoint</tt></dt><dd>If present, the
<xref target="token_pop_mechanism">Proof-of-Possession
mechanism</xref> is available. The parameter value is the URI
at which to exchange a proof-of-possession for a bearer
token.</dd>
<dt><tt>client_cert_endpoint</tt></dt><dd>If present, the
<xref target="client_cert_mechanism">TLS Client Certificate
mechanism</xref> is available. The parameter value is the URI
at which to request a bearer token.</dd>
</dl>
<t>The challenge can include other <em>auth-params</em> (such as <tt>realm</tt>),
including ones for other mechanisms. Unrecognized <em>auth-params</em>
<bcp14>SHOULD</bcp14> be ignored.</t>
<t>If a request is made for a resource within a protection space and that
request includes an <tt>Authorization</tt> header with an invalid <tt>Bearer</tt>
token, the resource server <bcp14>SHOULD</bcp14> reply with an HTTP <tt>401</tt>
response and <tt>WWW-Authenticate</tt> header as above, even if processing
the request doesn't otherwise require authorization. This is to allow a
client to obtain a fresh bearer token proactively (for example, before the
current token expires, to avoid delaying a real request by the user).</t>
<section title="Nonce Considerations" anchor="nonce_considerations">
<t>The nonce in the <tt>WWW-Authenticate</tt> challenge <bcp14>SHOULD</bcp14>
have the following properties:</t>
<ul>
<li>Be cryptographically strong and unguessable;</li>
<li>Be recognizable when returned in a token request as having been
issued for this protection space (for example, by recording
the nonce in a database, or including a cryptographic
signature);</li>
<li>Be valid for a limited (short) time;</li>
<li>Be redeemable at most once;</li>
<li>Be coupled to the original request URI in a recognizable way.</li>
</ul>
</section> <!-- Nonce Considerations -->
<section title="Common Token Response" anchor="common_response">
<t>It is anticipated that most mechanisms (especially ones that use an HTTP
API) will respond to a token request using a common response format. Both of
the mechanisms described in this memo use the common format described in this
section, which is substantially the same as the format described in
<relref section="5" target="RFC6749" displayFormat="of" />.</t>
<t>A successful common response is an HTTP <tt>200</tt> response with
Content-Type <tt>application/json</tt>, and having a response body in
<xref target="RFC8259">JSON</xref> format encoding a JSON object with at least
the following members:</t>
<dl>
<dt><tt>access_token</tt></dt><dd>An opaque (to the client) string;
a bearer access token
(<relref section="1.1" target="RFC6750" displayFormat="of"/>)
which can be used for requests in the same protection space
as the original request;</dd>
<dt><tt>expires_in</tt></dt><dd>The number of seconds from the
<tt>Date</tt> of this response after which the <tt>access_token</tt>
will no longer be valid;</dd>
<dt><tt>token_type</tt></dt><dd>A case-insensitive string identifying
the kind of token returned in this response. This value
<bcp14>MUST</bcp14> be <tt>Bearer</tt>.</dd>
</dl>
<t>If there is a problem with the request, the response <bcp14>SHALL</bcp14>
be an HTTP <tt>400</tt> response with Content-Type <tt>application/json</tt>,
and having a response body in JSON format encoding a JSON object with at least
an <tt>error</tt> member, and others as appropriate, whose keys and values
are defined in <relref section="5.2" target="RFC6749" displayFormat="of"/>.</t>
<t>Additional members <bcp14>MAY</bcp14> be included in a successful or
unsuccessful response object depending on the scope(s) from the
challenge, the mechanism used, and the implementation. Unrecognized response
object members <bcp14>SHOULD</bcp14> be ignored.</t>
</section> <!-- Common Response -->
<section title="Common Mechanism Flow">
<t>It is anticipated that most mechanisms will comprise a simple mechanism-specific
API endpoint and respond with a <xref target="common_response">Common
Response</xref>. The abstract flow for a client to acquire a bearer token
in the common way is illustrated in <xref target="common_sequence"/>.</t>
<figure anchor="common_sequence">
<name>Common Protocol Flow Sequence Diagram</name>
<artwork align="center" type="call-flow"><![CDATA[
Client Mechanism Endpoint Resource Server
| | |
|-- request URI ------------------------------------------->|
|<------------------------------ 401 Bearer nonce, scope, --|
| | endpoints |
|determine compatibility, | |
|prepare token request | |
|-- POST token request------->| |
| |validate request, |
| |issue token |
|<--------- Common Response --| |
| | |
| |
|-- request URI with access_token ------------------------->|
| validate & translate token,|
| apply access controls|
| |
|<--------------------------------------- answer resource --|
]]></artwork>
</figure>
<t>Note that the "validate request" step can involve complex operations and
include fetching supplemental information from external sources, depending
on the semantics of the mechanism, scopes, and principal.</t>
</section> <!-- Common Flow -->
</section> <!-- General Framework -->
<section title="Proof-of-Possession Mechanism" anchor="token_pop_mechanism">
<t>The client recognizes the availability of, and its compatibility with,
this mechanism, by recognizing combinations of challenge scopes with
which it is compatible, the presence of the <tt>token_pop_endpoint</tt>, and
control of an appropriate principal having proof-of-possession semantics (for
example, an access token bound to a proof-of-possession key, or a
<xref target="RFC7519">JSON Web Token (JWT)</xref> with a <tt>cnf</tt> claim
<xref target="RFC7800"/>) and compatibility with the same combination of
challenge scopes.</t>
<t>The client constructs and signs a
<xref target="proof_token"> <em>proof-token</em> </xref>.</t>
<t>The client sends the <em>proof-token</em> to the
<xref target="pop_api"> <tt>token_pop_endpoint</tt> API URI with HTTP
<tt>POST</tt> </xref>. The API endpoint validates the request including the
<em>proof-token</em>, and if appropriate, it responds with a bearer token.</t>
<section title="Proof Token" anchor="proof_token">
<t>The <em>proof-token</em> is a <xref target="RFC7519">JWT</xref>, with a
signature proving possesion of the key bound to the client's principal, and having
the following claims:</t>
<dl>
<dt><tt>sub</tt></dt><dd><bcp14>REQUIRED</bcp14>: The
client's principal (having proof-of-possession semantics and
compatible with a combination of the challenge scopes);</dd>
<dt><tt>aud</tt></dt><dd><bcp14>REQUIRED</bcp14>: The absolute URI
(<relref section="4.3" target="RFC3986" displayFormat="of"/>),
including scheme, authority (host and optional port), path,
and query, but not including fragment identifier, corresponding
to the original request that resulted in the HTTP <tt>401</tt>
challenge; if this claim is an array, it <bcp14>MUST</bcp14>
have exactly one element;</dd>
<dt><tt>nonce</tt></dt><dd><bcp14>REQUIRED</bcp14>: The nonce from
the <tt>WWW-Authenticate</tt> challenge;</dd>
<dt><tt>jti</tt></dt><dd><bcp14>RECOMMENDED</bcp14>: Use of this
claim is recommended so that the client can salt the
<em>proof-token</em>'s signature; the verifier can ignore
this claim, if present;</dd>
<dt><tt>exp</tt></dt><dd><bcp14>OPTIONAL</bcp14>: If present, this
claim <bcp14>MUST NOT</bcp14> be after the expiration time
of the <tt>sub</tt> (if it has one), and <bcp14>MUST
NOT</bcp14> be before the current time on the verifier;
ordinarily the validity of the nonce is sufficient to establish
not-before and not-after constraints on the proof, so this
claim isn't usually necessary (and clocks on end-user devices,
where <em>proof-tokens</em> are likely to be generated, are
notoriously inaccurate). The issuer <bcp14>MAY</bcp14> take the
expiration periods of the <em>proof-token</em> and the
<tt>sub</tt> into account when determining the expiration
period of the bearer token it issues, but it is not required
to do so and is free to issue bearer tokens with any expiration
period.</dd>
</dl>
<t>Additional claims can appear in the <em>proof-token</em> according to, and
conditioned on, the semantics of the scope(s). Unrecognized or
incompatible claims <bcp14>SHOULD</bcp14> be ignored.</t>
</section> <!-- Proof Token -->
<section title="Proof-of-Possession API" anchor="pop_api">
<t>This API endpoint is implemented by the authorization server
(<relref section="1.1" target="RFC6749" displayFormat="of"/>)
for the protection space of the original request.</t>
<t>The client uses this API by making an HTTP <tt>POST</tt> request to the
<tt>token_pop_endpoint</tt> URI. The request body has Content-Type
<tt>application/x-www-form-urlencoded</tt> and includes at least the following
parameter:</t>
<dl>
<dt><tt>proof_token</tt></dt><dd><bcp14>REQUIRED</bcp14>: A
<xref target="proof_token"> <em>proof-token</em> </xref>
as described above.</dd>
</dl>
<t>Additional parameters can be sent according to, and conditioned on, the
semantics of the scope(s). Unrecognized or incompatible parameters
<bcp14>SHOULD</bcp14> be ignored.</t>
<t>The authorization server verifies the request:</t>
<ol>
<li>Parse the <tt>proof_token</tt> parameter and find its claims;</li>
<li>Verify that the <tt>proof_token</tt>'s signature matches the
proof-of-possession key associated with the <tt>sub</tt>
claim, and that it hasn't expired;</li>
<li>Verify that the <tt>aud</tt> claim is an absolute URI for a
resource in a protection space for which this endpoint is
responsible;</li>
<li>Verify the <tt>nonce</tt> claim (for example, by confirming that
it was really issued by this system and not too far in the
past, that it hasn't been redeemed yet, and that it was issued
for a request for the <tt>aud</tt> claim);</li>
<li>Verify the validity and authenticity of the <tt>sub</tt> claim
according to its kind and the semantics of the relevant
scope(s);</li>
<li>Perform any other processing, verification, and validation
appropriate to the relevant scope(s), additional claims, or
additional parameters.</li>
</ol>
<t>If the request is verified, the authorization server issues a bearer
<tt>access_token</tt> valid for the protection space of the original request
and for a limited time. The authorization server responds using the common
response format
(<xref target="common_response"/>).</t>
</section> <!-- POP API -->
<section title="Proof-of-Possession Example" anchor="token_pop_example">
<t>Note: This section is not normative.</t>
<t>A client (for example, an in-browser application working on behalf of a
user) attempts an HTTP request to a resource server for an access-restricted
URI initially without presenting any special credentials:</t>
<sourcecode>
GET /some/restricted/resource HTTP/1.1
Host: www.example
Origin: https://app.example
</sourcecode>
<t>The resource server does not allow this request without authorization. It
generates an unguessable, opaque nonce that the server will be able to later
recognize as having generated. The server responds with an HTTP <tt>401</tt>
Unauthorized message, and includes the protection space identifier (realm),
the nonce, the appropriate scopes, and at least the <tt>token_pop_endpoint</tt>
in the <tt>WWW-Authenticate</tt> response header with the <tt>Bearer</tt>
method. The server also includes an HTML response body to allow the user to
perform a first-party login using another method, for cases where the resource
was navigated to directly in the browser:</t>
<sourcecode><![CDATA[
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="/auth/",
scope="webid openid",
nonce="j16C4SOLQWFor3VYUtZWnrUr5AG5uwDF7q9RFsDk",
token_pop_endpoint="/auth/webid-pop",
client_cert_endpoint="https://webid-tls.example/auth/webid-tls"
Access-Control-Allow-Origin: https://app.example
Access-Control-Expose-Headers: WWW-Authenticate
Date: Mon, 6 May 2019 01:48:48 GMT
Content-type: text/html
<html>Human first-party login page...</html>
]]></sourcecode>
<t>The client recognizes the response as compatible with this mechanism by
recognizing the scheme as <tt>Bearer</tt>, compatible scopes (in this example,
<tt>openid</tt> and <tt>webid</tt>), and the presence of the <tt>nonce</tt>
and the <tt>token_pop_endpoint</tt>.</t>
<t>The client controls a principal appropriate to the scopes (in this example,
a JWT substantially similar to an
<xref target="OpenID.Core">OpenID Connect ID Token</xref>
and containing a <xref target="RFC7800">confirmation key</xref>) and determines
to use the proof-of-possession mechanism.</t>
<t>The client creates a new <em>proof-token</em> JWT as described above
(<xref target="proof_token"/>), setting its <tt>aud</tt> claim to the absolute
URI of the original request, the <tt>nonce</tt> claim to the <tt>nonce</tt>
parameter from the <tt>WWW-Authenticate</tt> response header, the <tt>sub</tt>
claim to its ID Token, includes other claims as appropriate to the scopes
(<tt>iss</tt> in this example), and signs this <em>proof-token</em> with the
proof-of-possession key bound to its principal and with a signing algorithm
compatible with the signing key and the scopes:</t>
<sourcecode type="json"><![CDATA[
{
"typ": "JWT",
"alg": "RS256"
}
.
{
"sub": "eyJhbGciOiJ...",
"aud": "https://www.example/some/restricted/resource",
"nonce": "j16C4SOLQWFor3VYUtZWnrUr5AG5uwDF7q9RFsDk",
"jti": "1C49A92C-C260-4F76-9D7B-E81AE13037B8",
"iss": "https://app.example/oauth/code"
}
.
RS256-signature-here
]]></sourcecode>
<t>The client sends a request to the <tt>token_pop_endpoint</tt> URI and
includes the <em>proof-token</em>:</t>
<sourcecode><![CDATA[
POST /auth/webid-pop
Host: www.example
Origin: https://app.example
Content-type: application/x-www-form-urlencoded
proof_token=eyJ0eXAiOiJKV1QiCg...
]]></sourcecode>
<t>The <tt>token_pop_endpoint</tt> verifies the request as described in
<xref target="pop_api"/>, determines that the request is good, and issues a
bearer token:</t>
<sourcecode><![CDATA[
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Cache-control: no-cache, no-store
Pragma: no-cache
Access-Control-Allow-Origin: https://app.example
Date: Mon, 6 May 2019 01:48:50 GMT
{
"access_token": "RPAOmgrWb5wD7DzloDjZ7Ain",
"expires_in": 1800,
"token_type": "Bearer"
}
]]></sourcecode>
<t>The client can now use the <tt>access_token</tt> in an <tt>Authorization</tt>
header for requests to resources in the same protection space as the original
request until the access token expires or is revoked:</t>
<sourcecode><![CDATA[
GET /some/restricted/resource HTTP/1.1
Host: www.example
Origin: https://app.example
Authorization: Bearer RPAOmgrWb5wD7DzloDjZ7Ain
]]></sourcecode>
<t>The server validates and translates the bearer token in its
implementation-specific way, and makes a determination whether to grant the
requested access.</t>
</section> <!-- POP Example -->
</section> <!-- Proof-of-Possession -->
<section title="TLS Client Certificate Mechanism" anchor="client_cert_mechanism">
<t>The client recognizes the availability of, and its compatibility with,
this mechanism, by recognizing combinations of challenge scopes with which
it is compatible, the presence of the <tt>client_cert_endpoint</tt> and the
<tt>nonce</tt>, and either direct control of an appropriate
<xref target="RFC8446">TLS</xref> client certificate and its signing key, or
in the case of browser-based Javascript applications, an assumption that such
a certificate is configured into the browser and that it will be selected by
the user.</t>
<t>The client constructs and sends a token request to the
<xref target="client_cert_api"> <tt>client_cert_endpoint</tt> API URI with
HTTP <tt>POST</tt></xref>, using its TLS client certificate.</t>
<t>The API endpoint validates the request, including aspects of the client
certificate, and if appropriate, it responds with a bearer token.</t>
<section title="Client Certificate API" anchor="client_cert_api">
<t>This API endpoint is implemented by the authorization server for the
protection space of the original request.</t>
<t>The client uses this API by making an HTTP <tt>POST</tt> request to the
<tt>client_cert_endpoint</tt> URI. The request body has Content-Type
<tt>application/x-www-form-urlencoded</tt> and includes at least the following
parameters:</t>
<dl>
<dt><tt>uri</tt></dt><dd><bcp14>REQUIRED</bcp14>: The absolute URI,
including scheme, authority (host and optional port), path,
and query, but not including fragment identifier, corresponding
to the original request that resulted in the HTTP <tt>401</tt>
response;</dd>
<dt><tt>nonce</tt></dt><dd><bcp14>REQUIRED</bcp14>: The nonce from
the <tt>WWW-Authenticate</tt> challenge.</dd>
</dl>
<t>Additional parameters can be sent according to, and conditioned on, the
semantics of the scope(s). Unrecognized or incompatible parameters
<bcp14>SHOULD</bcp14> be ignored.</t>
<t>A TLS client certificate is <bcp14>REQUIRED</bcp14> when communicating
with this API endpoint. That means the origin of this API endpoint will
probably be different from that of the original request URI so that the server
can request a client certificate in a distinct TLS connection handshake
(<relref section="4.3.2" target="RFC8446" displayFormat="of" />).</t>
<t>The authorization server verifies the request:</t>
<ol>
<li>Verify that <tt>uri</tt> is an absolute URI and is in a protection
space for which this endpoint is responsible;</li>
<li>Verify the <tt>nonce</tt> (for example, confirming that it was
really generated by this system, not too far in the past,
that it hasn't been redeemed yet, and if possible that it
corresponds to a request for <tt>uri</tt>);</li>
<li>Verify the validity and authenticity of the client certificate
(beyond those validations required for the TLS connection)
according to the semantics of the relevant scope(s);</li>
<li>Perform any other processing, verification, and validation
appropriate to the relevant scope(s) or additional parameters.</li>
</ol>
<t>If the request is acceptable, the authorization server issues a bearer
<tt>access_token</tt> valid for the protection space of the original request
and for a limited time. The authorization server responds using the
<xref target="common_response">common response format</xref>.</t>
</section> <!-- cert API -->
<section title="Client Certificate Example">
<t>Note: This section is not normative.</t>
<t>A client (for example, an in-browser application working on behalf of a
user) attempts an HTTP request to a resource server for an access-restricted
URI initially without presenting any special credentials:</t>
<sourcecode>
GET /some/restricted/resource HTTP/1.1
Host: www.example
Origin: https://app.example
</sourcecode>
<t>The resource server does not allow this request without authorization. It
generates an unguessable, opaque nonce that the authorization server will be
able to later recognize as having generated. The server responds with an HTTP
<tt>401</tt> Unauthorized message, and includes the protection space identifier
(realm), the nonce, the appropriate scopes, and at least the
<tt>client_cert_endpoint</tt> in the <tt>WWW-Authenticate</tt> response header
with the <tt>Bearer</tt> method. The server also includes an HTML response
body to allow the user to perform a first-party login using another method,
for cases where the resource was navigated to directly in the browser:</t>
<sourcecode><![CDATA[
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="/auth/",
scope="webid openid",
nonce="j16C4SOLQWFor3VYUtZWnrUr5AG5uwDF7q9RFsDk",
token_pop_endpoint="/auth/webid-pop",
client_cert_endpoint="https://webid-tls.example/auth/webid-tls"
Access-Control-Allow-Origin: https://app.example
Access-Control-Expose-Headers: WWW-Authenticate
Date: Mon, 6 May 2019 01:48:48 GMT
Content-type: text/html
<html>Human first-party login page...</html>
]]></sourcecode>
<t>The client recognizes the response as compatible with this mechanism by
recognizing the scheme as <tt>Bearer</tt>, compatible scopes (in this example,
<tt>webid</tt>), and the presence of the <tt>nonce</tt> and the
<tt>client_cert_endpoint</tt>.</t>
<t>The client determines to use the client certificate mechanism (for example,
by being configured by the user to do so when available, with the assumption
the user will choose an appropriate certificate when prompted by the browser).</t>
<t>The client sends, using its TLS client certificate, a token request to the
<tt>client_cert_endpoint</tt> URI and includes the required parameters:</t>
<sourcecode><![CDATA[
POST /auth/webid-tls HTTP/1.1
Host: webid-tls.example
Origin: https://app.example
Content-type: application/x-www-form-urlencoded
uri=https://www.example/some/restricted/resource
&nonce=j16C4SOLQWFor3VYUtZWnrUr5AG5uwDF7q9RFsDk
]]></sourcecode>
<t>The <tt>client_cert_endpoint</tt> verifies the request as described in
<xref target="client_cert_api" /> (in this example, with scope <tt>webid</tt>,
the validation and processing steps further comprise establishing and validating
the user's WebID according to <xref target="WebID-TLS" />). The endpoint
determines that the request is good, and issues a bearer token:</t>
<sourcecode><![CDATA[
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Cache-control: no-cache, no-store
Pragma: no-cache
Access-Control-Allow-Origin: https://app.example
Date: Mon, 6 May 2019 01:48:50 GMT
{
"access_token": "RPAOmgrWb5wD7DzloDjZ7Ain",
"expires_in": 1800,
"token_type": "Bearer"
}
]]></sourcecode>
<t>The client can now use the <tt>access_token</tt> in an <tt>Authorization</tt>
header for requests to resources in the same protection space as the original
request until the bearer token expires or is revoked:</t>
<sourcecode><![CDATA[
GET /some/restricted/resource HTTP/1.1
Host: www.example
Origin: https://app.example
Authorization: Bearer RPAOmgrWb5wD7DzloDjZ7Ain
]]></sourcecode>
<t>The server validates and translates the bearer token in its
implementation-specific way, and makes a determination whether to grant the
requested access.</t>
</section> <!-- client cert example -->
</section> <!-- TLS Client Certificate -->
<section title="IANA Considerations">
<t>TBD. Mechanism parameters "token_pop_endpoint" and "client_cert_endpoint" for auth-scheme "Bearer".</t>
</section> <!-- IANA -->
<section title="Security Considerations">
<t>When using the
<xref target="token_pop_mechanism">Proof-of-Possession mechanism</xref>, the
scope designer should carefully consider whether additional information should
go in the <em>proof-token</em> (which would therefore be signed) or can be
<tt>POST</tt> parameters (which would not be signed). The safe choice (which
therefore <bcp14>SHOULD</bcp14> be the default) is to include any additional
information in the <em>proof-token</em>.</t>
<t>Bearer tokens can be shared freely with other parties by an application.
Therefore, a bearer token obtained with the
<xref target="client_cert_mechanism">TLS Client Certificate mechanism</xref>
<bcp14>MUST NOT</bcp14> be construed to carry the same weight when authenticating
an HTTP request as if the client used the corresponding client certificate
for the request's connection. However, particularly for browser-based
applications where the application and the resource server(s) are not associated
with each other, the user typically doesn't audit the data being sent in HTTP
requests (even when a client certificate is used), so the portion of the
application running in the browser could be receiving data from anywhere else
and sending it over HTTP using the user's client certificate anyway.</t>
<t>Security considerations specific to challenge scopes are beyond the purview
of this memo.</t>
</section> <!-- Security Considerations -->
</middle>
<back>
<references>
<name>References</name>
<references title="Normative References">
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml" /> <!-- BCP14 -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.3986.xml" /> <!-- URI syntax -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.6749.xml" /> <!-- OAuth framework -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.6750.xml" /> <!-- Bearer tokens -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7235.xml" /> <!-- HTTP Auth -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7519.xml" /> <!-- JWT -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8174.xml" /> <!-- BCP14 -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8259.xml" /> <!-- JSON -->
</references>
<references title="Informative References">
<reference anchor="DID" target="https://www.w3.org/TR/did-core/">
<front>
<title>Decentralized Identifiers (DIDs) v1.0</title>
<author initials="D." surname="Reed"/>
<author initials="M." surname="Sporny"/>
<author initials="D." surname="Longley"/>
<author initials="C." surname="Allen"/>
<author initials="R." surname="Grant"/>
<author initials="M." surname="Sabadello"/>
<date month="April" year="2020"/>
</front>
</reference>
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7541.xml" /> <!-- HPACK -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7800.xml" /> <!-- POP Token -->
<xi:include href="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8446.xml" /> <!-- TLS -->
<reference anchor="OpenID.Core" target="https://openid.net/specs/openid-connect-core-1_0.html">
<front>
<title>OpenID Connect Core 1.0</title>
<author initials="N." surname="Sakimura"/>
<author initials="J." surname="Bradley"/>
<author initials="M." surname="Jones"/>
<author initials="B." surname="de Medeiros"/>
<author initials="C." surname="Mortimore"/>
<date month="November" year="2014"/>
</front>
</reference>
<reference anchor="VC" target="https://www.w3.org/TR/vc-data-model/">
<front>
<title>Verifiable Credentials Data Model 1.0</title>
<author initials="M." surname="Sporny" />
<author initials="D." surname="Longley" />
<author initials="D." surname="Chadwick" />
<author initials="G." surname="Noble" role="editor" />
<author initials="D." surname="Burnett" role="editor" />
<author initials="B." surname="Zundel" role="editor" />
<date month="November" year="2019" />
</front>
</reference>
<reference anchor="WebID" target="https://www.w3.org/2005/Incubator/webid/spec/identity/">
<front>
<title>WebID 1.0: Web Identity and Discovery</title>
<author initials="A." surname="Sambra" />
<author initials="H." surname="Story" />
<author initials="T." surname="Berners-Lee" />
<author initials="S." surname="Corlosquet" role="editor" />
<date month="March" year="2014" />
</front>
</reference>
<reference anchor="WebID-TLS" target="https://www.w3.org/2005/Incubator/webid/spec/tls/">
<front>
<title>WebID Authentication over TLS</title>
<author initials="T." surname="Inkster" />
<author initials="H." surname="Story" />
<author initials="B." surname="Harbulot" />
<author initials="S." surname="Corlosquet" role="editor" />
<author initials="A." surname="Sambra" role="editor" />
<date month="March" year="2014" />
</front>
</reference>
</references>
</references>
</back>
</rfc>