idnits 2.17.1 draft-ietf-oauth-dpop-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (1 May 2020) is 1450 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) ** Obsolete normative reference: RFC 7231 (Obsoleted by RFC 9110) == Outdated reference: A later version (-13) exists of draft-ietf-oauth-access-token-jwt-07 == Outdated reference: A later version (-34) exists of draft-ietf-oauth-jwsreq-21 -- Obsolete informational reference (is this intentional?): RFC 7235 (Obsoleted by RFC 9110) == Outdated reference: A later version (-25) exists of draft-ietf-oauth-security-topics-15 Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Web Authorization Protocol D. Fett 3 Internet-Draft yes.com 4 Intended status: Standards Track B. Campbell 5 Expires: 2 November 2020 Ping Identity 6 J. Bradley 7 Yubico 8 T. Lodderstedt 9 yes.com 10 M. Jones 11 Microsoft 12 D. Waite 13 Ping Identity 14 1 May 2020 16 OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer 17 (DPoP) 18 draft-ietf-oauth-dpop-01 20 Abstract 22 This document describes a mechanism for sender-constraining OAuth 2.0 23 tokens via a proof-of-possession mechanism on the application level. 24 This mechanism allows for the detection of replay attacks with access 25 and refresh tokens. 27 Status of This Memo 29 This Internet-Draft is submitted in full conformance with the 30 provisions of BCP 78 and BCP 79. 32 Internet-Drafts are working documents of the Internet Engineering 33 Task Force (IETF). Note that other groups may also distribute 34 working documents as Internet-Drafts. The list of current Internet- 35 Drafts is at https://datatracker.ietf.org/drafts/current/. 37 Internet-Drafts are draft documents valid for a maximum of six months 38 and may be updated, replaced, or obsoleted by other documents at any 39 time. It is inappropriate to use Internet-Drafts as reference 40 material or to cite them other than as "work in progress." 42 This Internet-Draft will expire on 2 November 2020. 44 Copyright Notice 46 Copyright (c) 2020 IETF Trust and the persons identified as the 47 document authors. All rights reserved. 49 This document is subject to BCP 78 and the IETF Trust's Legal 50 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 51 license-info) in effect on the date of publication of this document. 52 Please review these documents carefully, as they describe your rights 53 and restrictions with respect to this document. Code Components 54 extracted from this document must include Simplified BSD License text 55 as described in Section 4.e of the Trust Legal Provisions and are 56 provided without warranty as described in the Simplified BSD License. 58 Table of Contents 60 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 61 1.1. Conventions and Terminology . . . . . . . . . . . . . . . 3 62 2. Main Objective . . . . . . . . . . . . . . . . . . . . . . . 4 63 3. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 64 4. DPoP Proof JWTs . . . . . . . . . . . . . . . . . . . . . . . 6 65 4.1. DPoP Proof JWT Syntax . . . . . . . . . . . . . . . . . . 6 66 4.2. Checking DPoP Proofs . . . . . . . . . . . . . . . . . . 7 67 5. Token Request (Binding Tokens to a Public Key) . . . . . . . 8 68 6. Resource Access (Proof of Possession for Access Tokens) . . . 9 69 7. Public Key Confirmation . . . . . . . . . . . . . . . . . . . 11 70 8. Authorization Server Metadata . . . . . . . . . . . . . . . . 12 71 9. Security Considerations . . . . . . . . . . . . . . . . . . . 12 72 9.1. DPoP Proof Replay . . . . . . . . . . . . . . . . . . . . 13 73 9.2. Signed JWT Swapping . . . . . . . . . . . . . . . . . . . 13 74 9.3. Signature Algorithms . . . . . . . . . . . . . . . . . . 13 75 9.4. Message Integrity . . . . . . . . . . . . . . . . . . . . 13 76 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 77 10.1. OAuth Access Token Type Registration . . . . . . . . . . 14 78 10.2. HTTP Authentication Scheme Registration . . . . . . . . 14 79 10.3. Media Type Registration . . . . . . . . . . . . . . . . 14 80 10.4. JWT Confirmation Methods Registration . . . . . . . . . 15 81 10.5. JSON Web Token Claims Registration . . . . . . . . . . . 15 82 10.6. HTTP Message Header Field Names Registration . . . . . . 15 83 10.7. Authorization Server Metadata Registration . . . . . . . 16 84 11. Normative References . . . . . . . . . . . . . . . . . . . . 16 85 12. Informative References . . . . . . . . . . . . . . . . . . . 17 86 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 19 87 Appendix B. Document History . . . . . . . . . . . . . . . . . . 19 88 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 21 90 1. Introduction 92 This document outlines a relatively simple application-level 93 mechanism for sender-constraining OAuth access and refresh tokens. 94 It enables a client to demonstrate proof-of-possession of a public/ 95 private key pair by including the "DPoP" header in an HTTP request. 96 Using that header, an authorization server is able to bind issued 97 tokens to the public part of the client's key pair. Recipients of 98 such tokens are then able to verify the binding of the token to the 99 key pair that the client has demonstrated that it holds via the 100 "DPoP" header, thereby providing some assurance that the client 101 presenting the token also possesses the private key. In other words, 102 the legitimate presenter of the token is constrained to be the sender 103 that holds and can prove possession of the private part of the key 104 pair. 106 The mechanism described herein can be used in cases where potentially 107 stronger methods of sender-constraining tokens that utilize elements 108 of the underlying secure transport layer, such as [RFC8705] or 109 [I-D.ietf-oauth-token-binding], are not available or desirable. For 110 example, due to a sub-par user experience of TLS client 111 authentication in user agents and a lack of support for HTTP token 112 binding, neither mechanism can be used if an OAuth client is a Single 113 Page Application (SPA) running in a web browser. 115 DPoP can be used with public clients to sender-constrain access 116 tokens and refresh tokens. With confidential clients, DPoP can be 117 used in conjunction with any client authentication method to sender- 118 constrain access tokens. 120 1.1. Conventions and Terminology 122 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 123 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 124 "OPTIONAL" in this document are to be interpreted as described in BCP 125 14 [RFC2119] [RFC8174] when, and only when, they appear in all 126 capitals, as shown here. 128 This specification uses the terms "access token", "refresh token", 129 "authorization server", "resource server", "authorization endpoint", 130 "authorization request", "authorization response", "token endpoint", 131 "grant type", "access token request", "access token response", and 132 "client" defined by The OAuth 2.0 Authorization Framework [RFC6749]. 134 2. Main Objective 136 Under the attacker model defined in [I-D.ietf-oauth-security-topics], 137 the mechanism defined by this specification aims to prevent token 138 replay at a different endpoint. 140 More precisely, if an adversary is able to get hold of an access 141 token or refresh token because it set up a counterfeit authorization 142 server or resource server, the adversary is not able to replay the 143 respective token at another authorization or resource server. 145 Secondary objectives are discussed in Section 9. 147 3. Concept 149 The main data structure introduced by this specification is a DPoP 150 proof JWT, described in detail below, sent as a header in an HTTP 151 request. A client uses a DPoP proof JWT to prove the possession of a 152 private key corresponding to a certain public key. Roughly speaking, 153 a DPoP proof is a signature over a timestamp and some data of the 154 HTTP request to which it is attached. 156 +--------+ +---------------+ 157 | |--(A)-- Token Request ------------------->| | 158 | Client | (DPoP Proof) | Authorization | 159 | | | Server | 160 | |<-(B)-- DPoP-bound Access Token ----------| | 161 | | (token_type=DPoP) +---------------+ 162 | | PoP Refresh Token for public clients 163 | | 164 | | +---------------+ 165 | |--(C)-- DPoP-bound Access Token --------->| | 166 | | (DPoP Proof) | Resource | 167 | | | Server | 168 | |<-(D)-- Protected Resource ---------------| | 169 | | +---------------+ 170 +--------+ 172 Figure 1: Basic DPoP Flow 174 The basic steps of an OAuth flow with DPoP are shown in Figure 1: 176 * (A) In the Token Request, the client sends an authorization code 177 to the authorization server in order to obtain an access token 178 (and potentially a refresh token). The client attaches a DPoP 179 proof to the request in an HTTP header. 181 * (B) The AS binds (sender-constrains) the access token to the 182 public key claimed by the client in the DPoP proof; that is, the 183 access token cannot be used without proving possession of the 184 respective private key. This is signaled to the client by using 185 the "token_type" value "DPoP". 187 * If a refresh token is issued to a public client, it is bound to 188 the public key of the DPoP proof in a similar way. Note that for 189 confidential clients, refresh tokens are required by [RFC6749] to 190 bound to the "client_id" and associated authentication 191 credentials, which is a sender-constraining mechanism that is more 192 flexible than binding to a particular public key. 194 * (C) If the client wants to use the access token, it has to prove 195 possession of the private key by, again, adding a header to the 196 request that carries the DPoP proof. The resource server needs to 197 receive information about the public key to which the access token 198 is bound. This information is either encoded directly into the 199 access token (for JWT structured access tokens), or provided at 200 the token introspection endpoint of the authorization server (not 201 shown). The resource server verifies that the public key to which 202 the access token is bound matches the public key of the DPoP 203 proof. 205 * (D) The resource server refuses to serve the request if the 206 signature check fails or the data in the DPoP proof is wrong, 207 e.g., the request URI does not match the URI claim in the DPoP 208 proof JWT. 210 * When a refresh token that is sender-constrained using DPoP is used 211 by the client, the client has to provide a DPoP proof just as in 212 the case of a resource access. The new access token will be bound 213 to the same public key. 215 The mechanism presented herein is not a client authentication method. 216 In fact, a primary use case of DPoP is for public clients (e.g., 217 single page applications) that do not use client authentication. 218 Nonetheless, DPoP is designed such that it is compatible with 219 "private_key_jwt" and all other client authentication methods. 221 DPoP does not directly ensure message integrity but relies on the TLS 222 layer for that purpose. See Section 9 for details. 224 4. DPoP Proof JWTs 226 DPoP introduces concept of a DPoP proof JWT, which is used for 227 binding public keys and proving knowledge about private keys. The 228 DPoP proof JWT is sent with an HTTP request using the "DPoP" header 229 field. 231 4.1. DPoP Proof JWT Syntax 233 A DPoP proof is a JWT ([RFC7519]) that is signed (using JWS, 234 [RFC7515]) using a private key chosen by the client (see below). The 235 header of a DPoP JWT contains at least the following parameters: 237 * "typ": type header, value "dpop+jwt" (REQUIRED). 239 * "alg": a digital signature algorithm identifier as per [RFC7518] 240 (REQUIRED). MUST NOT be "none" or an identifier for a symmetric 241 algorithm (MAC). 243 * "jwk": representing the public key chosen by the client, in JWK 244 format, as defined in [RFC7515] (REQUIRED) 246 The body of a DPoP proof contains at least the following claims: 248 * "jti": Unique identifier for the DPoP proof JWT (REQUIRED). The 249 value MUST be assigned such that there is a negligible probability 250 that the same value will be assigned to any other DPoP proof used 251 in the same context during the time window of validity. Such 252 uniqueness can be accomplished by encoding (base64url or any other 253 suitable encoding) at least 96 bits of pseudorandom data or by 254 using a version 4 UUID string according to [RFC4122]. The "jti" 255 SHOULD be used by the server for replay detection and prevention, 256 see Section 9.1. 258 * "htm": The HTTP method for the request to which the JWT is 259 attached, as defined in [RFC7231] (REQUIRED). 261 * "htu": The HTTP URI used for the request, without query and 262 fragment parts (REQUIRED). 264 * "iat": Time at which the JWT was created (REQUIRED). 266 Figure 2 shows the JSON header and payload of a DPoP proof JWT. 268 { 269 "typ":"dpop+jwt", 270 "alg":"ES256", 271 "jwk": { 272 "kty":"EC", 273 "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs", 274 "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA", 275 "crv":"P-256" 276 } 277 }.{ 278 "jti":"-BwC3ESc6acc2lTc", 279 "htm":"POST", 280 "htu":"https://server.example.com/token", 281 "iat":1562262616 282 } 284 Figure 2: Example JWT content for "DPoP" proof header 286 Note: To keep DPoP simple to implement, only the HTTP method and URI 287 are signed in DPoP proofs. The idea is sign just enough of the HTTP 288 data to provide reasonable proof-of-possession with respect to the 289 HTTP request. But that it be a minimal subset of the HTTP data so as 290 to avoid the substantial difficulties inherent in attempting to 291 normalize HTTP messages. Nonetheless, DPoP proofs can be extended to 292 contain other information of the HTTP request (see also Section 9.4). 294 4.2. Checking DPoP Proofs 296 To check if a string that was received as part of an HTTP Request is 297 a valid DPoP proof, the receiving server MUST ensure that 299 1. the string value is a well-formed JWT, 301 2. all required claims are contained in the JWT, 303 3. the "typ" field in the header has the value "dpop+jwt", 305 4. the algorithm in the header of the JWT indicates an asymmetric 306 digital signature algorithm, is not "none", is supported by the 307 application, and is deemed secure, 309 5. that the JWT is signed using the public key contained in the 310 "jwk" header of the JWT, 312 6. the "htm" claim matches the HTTP method value of the HTTP request 313 in which the JWT was received (case-insensitive), 315 7. the "htu" claims matches the HTTP URI value for the HTTP request 316 in which the JWT was received, ignoring any query and fragment 317 parts, 319 8. the token was issued within an acceptable timeframe (see 320 Section 9.1), and 322 9. that, within a reasonable consideration of accuracy and resource 323 utilization, a JWT with the same "jti" value has not been 324 received previously (see Section 9.1). 326 Servers SHOULD employ Syntax-Based Normalization and Scheme-Based 327 Normalization in accordance with Section 6.2.2. and Section 6.2.3. of 328 [RFC3986] before comparing the "htu" claim. 330 5. Token Request (Binding Tokens to a Public Key) 332 To bind a token to a public key in the token request, the client MUST 333 provide a valid DPoP proof JWT in a "DPoP" header. The HTTPS request 334 shown in Figure 3 illustrates the protocol for this (with extra line 335 breaks for display purposes only). 337 POST /token HTTP/1.1 338 Host: server.example.com 339 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 340 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 341 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 342 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 343 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj 344 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia 345 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg 346 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg 347 grant_type=authorization_code 348 &code=SplxlOBeZQQYbYS6WxSbIA 349 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 350 &code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz- 352 Figure 3: Token Request for a DPoP sender-constrained token 354 The "DPoP" HTTP header MUST contain a valid DPoP proof JWT. If the 355 DPoP proof is invalid, the authorization server issues an error 356 response per Section 5.2 of [RFC6749] with "invalid_dpop_proof" as 357 the value of the "error" parameter. 359 The authorization server, after checking the validity of the DPoP 360 proof, associates the access token issued at the token endpoint with 361 the public key. It then sets "token_type" to "DPoP" in the token 362 response, which signals to the client that the access token was bound 363 to its DPoP key and can used as described in Section 6. 365 If a refresh token is issued to a public client at the token endpoint 366 and a valid DPoP proof is presented, the refresh token MUST be bound 367 to the public key contained in the header of the DPoP proof JWT. 369 When a DPoP-bound refresh token is used at the token endpoint by a 370 public client, the AS MUST ensure that the DPoP proof contains the 371 same public key as the one the refresh token is bound to. The access 372 token issued MUST be bound to the public key contained in the DPoP 373 proof. 375 6. Resource Access (Proof of Possession for Access Tokens) 377 To make use of an access token that is bound to a public key using 378 DPoP, a client MUST prove the possession of the corresponding private 379 key by providing a DPoP proof in the "DPoP" request header. 381 A DPoP-bound access token is sent using the "Authorization" request 382 header field per Section 2 of [RFC7235] using an authentication 383 scheme of "DPoP". The syntax of the "Authorization" header field for 384 the "DPoP" scheme uses the "token68" syntax defined in Section 2.1 of 385 [RFC7235] (repeated below for ease of reference) for credentials. 386 The Augmented Backus-Naur Form (ABNF) notation [RFC5234] syntax for 387 DPoP Authorization scheme credentials is as follows: 389 token68 = 1*( ALPHA / DIGIT / 390 "-" / "." / "_" / "~" / "+" / "/" ) *"=" 392 credentials = "DPoP" 1*SP token68 394 Figure 4: DPoP Authorization Scheme ABNF 396 For such an access token, a resource server MUST check that a "DPoP" 397 header was received in the HTTP request, check the header's contents 398 according to the rules in Section 4.2, and check that the public key 399 of the DPoP proof matches the public key to which the access token is 400 bound per Section 7. 402 The resource server MUST NOT grant access to the resource unless all 403 checks are successful. 405 GET /protectedresource HTTP/1.1 406 Host: resource.example.org 407 Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWI 408 iOiJzb21lb25lQGV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbX 409 BsZS5jb20iLCJhdWQiOiJodHRwczovL3Jlc291cmNlLmV4YW1wbGUub3JnIiwibmJmI 410 joxNTYyMjYyNjExLCJleHAiOjE1NjIyNjYyMTYsImNuZiI6eyJqa3QiOiIwWmNPQ09S 411 Wk5ZeS1EV3BxcTMwalp5SkdIVE4wZDJIZ2xCVjN1aWd1QTRJIn19.vsFiVqHCyIkBYu 412 50c69bmPJsj8qYlsXfuC6nZcLl8YYRNOhqMuRXu6oSZHe2dGZY0ODNaGg1cg-kVigzY 413 hF1MQ 414 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 415 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 416 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 417 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj 418 oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z 419 WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.lNhmpAX1WwmpBvwhok4E74kWCiGB 420 NdavjLAeevGy32H3dbF0Jbri69Nm2ukkwb-uyUI4AUg1JSskfWIyo4UCbQ 422 Figure 5: Protected Resource Request with a DPoP sender- 423 constrained access token 425 Upon receipt of a request for a URI of a protected resource within 426 the protection space requiring DPoP authorization, if the request 427 does not include valid credentials or or does not contain an access 428 token sufficient for access to the protected resource, the server can 429 reply with a challenge using the 401 (Unauthorized) status code 430 ([RFC7235], Section 3.1) and the "WWW-Authenticate" header field 431 ([RFC7235], Section 4.1). The server MAY include the "WWW- 432 Authenticate" header in response to other conditions as well. 434 In such challenges: 436 * The scheme name is "DPoP". 438 * The authentication parameter "realm" MAY be included to indicate 439 the scope of protection in the manner described in [RFC7235], 440 Section 2.2. 442 * A "scope" authentication parameter MAY be included as defined in 443 [RFC6750], Section 3. 445 * An "error" parameter ([RFC6750], Section 3) SHOULD be included to 446 indicate the reason why the request was declined, if the request 447 included an access token but failed authorization. Parameter 448 values are described in Section 3.1 of [RFC6750]. 450 * An "error_description" parameter ([RFC6750], Section 3) MAY be 451 included along with the "error" parameter to provide developers a 452 human-readable explanation that is not meant to be displayed to 453 end-users. 455 * An "algs" parameter SHOULD be included to signal to the client the 456 JWS algorithms that are acceptable for the DPoP proof JWT. The 457 value of the parameter is a space-delimited list of JWS "alg" 458 (Algorithm) header values ([RFC7515], Section 4.1.1). 460 * Additional authentication parameters MAY be used and unknown 461 parameters MUST be ignored by recipients 463 For example, in response to a protected resource request without 464 authentication: 466 HTTP/1.1 401 Unauthorized 467 WWW-Authenticate: DPoP realm="WallyWorld", algs="ES256 PS256" 469 Figure 6 471 And in response to a protected resource request that was rejected 472 because the confirmation of the DPoP binding in the access token 473 failed: 475 HTTP/1.1 401 Unauthorized 476 WWW-Authenticate: DPoP realm="WallyWorld", error="invalid_token", 477 error_description="Invalid DPoP key binding", algs="ES256" 479 Figure 7 481 7. Public Key Confirmation 483 It MUST be ensured that resource servers can reliably identify 484 whether a token is bound using DPoP and learn the public key to which 485 the token is bound. 487 Access tokens that are represented as JSON Web Tokens (JWT) [RFC7519] 488 MUST contain information about the DPoP public key (in JWK format) in 489 the member "jkt" of the "cnf" claim, as shown in Figure 8. 491 The value in "jkt" MUST be the base64url encoding [RFC7515] of the 492 JWK SHA-256 Thumbprint (according to [RFC7638]) of the public key to 493 which the access token is bound. 495 { 496 "sub":"someone@example.com", 497 "iss":"https://server.example.com", 498 "aud":"https://resource.example.org", 499 "nbf":1562262611, 500 "exp":1562266216, 501 "cnf":{ 502 "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" 503 } 504 } 506 Figure 8: Example access token body with "cnf" claim 508 When access token introspection is used, the same "cnf" claim as 509 above MUST be contained in the introspection response. 511 Resource servers MUST ensure that the fingerprint of the public key 512 in the DPoP proof JWT equals the value in the "jkt" claim in the 513 access token or introspection response. 515 8. Authorization Server Metadata 517 This document introduces the following new authorization server 518 metadata [RFC8414] parameter to signal the JWS "alg" values the 519 authorization server supports for DPoP proof JWTs: 521 "dpop_signing_alg_values_supported" OPTIONAL. JSON array containing 522 a list of the JWS "alg" values supported by the authorization 523 server for DPoP proof JWTs 525 9. Security Considerations 527 In DPoP, the prevention of token replay at a different endpoint (see 528 Section 2) is achieved through the binding of the DPoP proof to a 529 certain URI and HTTP method. DPoP does not, however, achieve the 530 same level of protection as TLS-based methods such as OAuth Mutual 531 TLS [RFC8705] or OAuth Token Binding [I-D.ietf-oauth-token-binding] 532 (see also Section 9.1 and Section 9.4). TLS-based mechanisms can 533 leverage a tight integration between the TLS layer and the 534 application layer to achieve a very high level of message integrity 535 and replay protection. Therefore, it is RECOMMENDED to prefer TLS- 536 based methods over DPoP if such methods are suitable for the scenario 537 at hand. 539 9.1. DPoP Proof Replay 541 If an adversary is able to get hold of a DPoP proof JWT, the 542 adversary could replay that token at the same endpoint (the HTTP 543 endpoint and method are enforced via the respective claims in the 544 JWTs). To prevent this, servers MUST only accept DPoP proofs for a 545 limited time window after their "iat" time, preferably only for a 546 relatively brief period. Servers SHOULD store the "jti" value of 547 each DPoP proof for the time window in which the respective DPoP 548 proof JWT would be accepted and decline HTTP requests for which the 549 "jti" value has been seen before. In order to guard against memory 550 exhaustion attacks a server SHOULD reject DPoP proof JWTs with 551 unnecessarily large "jti" values or store only a hash thereof. 553 Note: To accommodate for clock offsets, the server MAY accept DPoP 554 proofs that carry an "iat" time in the near future (e.g., up to a few 555 seconds in the future). 557 9.2. Signed JWT Swapping 559 Servers accepting signed DPoP proof JWTs MUST check the "typ" field 560 in the headers of the JWTs to ensure that adversaries cannot use JWTs 561 created for other purposes. 563 9.3. Signature Algorithms 565 Implementers MUST ensure that only asymmetric digital signature 566 algorithms that are deemed secure can be used for signing DPoP 567 proofs. In particular, the algorithm "none" MUST NOT be allowed. 569 9.4. Message Integrity 571 DPoP does not ensure the integrity of the payload or headers of 572 requests. The signature of DPoP proofs only contains the HTTP URI 573 and method, but not, for example, the message body or other request 574 headers. 576 This is an intentional design decision to keep DPoP simple to use, 577 but as described, makes DPoP potentially susceptible to replay 578 attacks where an attacker is able to modify message contents and 579 headers. In many setups, the message integrity and confidentiality 580 provided by TLS is sufficient to provide a good level of protection. 582 Implementers that have stronger requirements on the integrity of 583 messages are encouraged to either use TLS-based mechanisms or signed 584 requests. TLS-based mechanisms are in particular OAuth Mutual TLS 585 [RFC8705] and OAuth Token Binding [I-D.ietf-oauth-token-binding]. 587 Note: While signatures on (parts of) requests are out of the scope of 588 this specification, signatures or information to be signed can be 589 added into DPoP proofs. 591 10. IANA Considerations 593 10.1. OAuth Access Token Type Registration 595 This specification requests registration of the following access 596 token type in the "OAuth Access Token Types" registry 597 [IANA.OAuth.Params] established by [RFC6749]. 599 * Type name: "DPoP" 601 * Additional Token Endpoint Response Parameters: (none) 603 * HTTP Authentication Scheme(s): "DPoP" 605 * Change controller: IESG 607 * Specification document(s): [[ this specification ]] 609 10.2. HTTP Authentication Scheme Registration 611 This specification requests registration of the following scheme in 612 the "Hypertext Transfer Protocol (HTTP) Authentication Scheme 613 Registry" [RFC7235][IANA.HTTP.AuthSchemes]: 615 * Authentication Scheme Name: "DPoP" 617 * Reference: [[ Section 6 of this specification ]] 619 10.3. Media Type Registration 621 [[ Is a media type registration at [IANA.MediaTypes] necessary for 622 "application/dpop+jwt"? There is a "+jwt" structured syntax suffix 623 registered already at [IANA.MediaType.StructuredSuffixs] by 624 Section 7.2 of [RFC8417], which is maybe sufficient? A fullblown 625 registration of "application/dpop+jwt" seems like it'd be overkill. 626 The "dpop+jwt" is used in the JWS/JWT "typ" header for explicit 627 typing of the JWT per Section 3.11 of [RFC8725] but it is not used 628 anywhere else (such as the "Content-Type" of HTTP messages). 630 Note that there does seem to be some precedence for [IANA.MediaTypes] 631 registration with [I-D.ietf-oauth-access-token-jwt], 632 [I-D.ietf-oauth-jwsreq], [RFC8417], and of course [RFC7519]. But 633 precedence isn't always right. ]] 635 10.4. JWT Confirmation Methods Registration 637 This specification requests registration of the following value in 638 the IANA "JWT Confirmation Methods" registry [IANA.JWT] for JWT "cnf" 639 member values established by [RFC7800]. 641 * Confirmation Method Value: "jkt" 643 * Confirmation Method Description: JWK SHA-256 Thumbprint 645 * Change Controller: IESG 647 * Specification Document(s): [[ Section 7 of this specification ]] 649 10.5. JSON Web Token Claims Registration 651 This specification requests registration of the following Claims in 652 the IANA "JSON Web Token Claims" registry [IANA.JWT] established by 653 [RFC7519]. 655 HTTP method: 657 * Claim Name: "htm" 659 * Claim Description: The HTTP method of the request 661 * Change Controller: IESG 663 * Specification Document(s): [[ Section 4.1 of this specification ]] 665 HTTP URI: 667 * Claim Name: "htu" 669 * Claim Description: The HTTP URI of the request (without query and 670 fragment parts) 672 * Change Controller: IESG 674 * Specification Document(s): [[ Section 4.1 of this specification ]] 676 10.6. HTTP Message Header Field Names Registration 678 This document specifies the following new HTTP header fields, 679 registration of which is requested in the "Permanent Message Header 680 Field Names" registry [IANA.Headers] defined in [RFC3864]. 682 * Header Field Name: "DPoP" 683 * Applicable protocol: HTTP 685 * Status: standard 687 * Author/change Controller: IETF 689 * Specification Document(s): [[ this specification ]] 691 10.7. Authorization Server Metadata Registration 693 This specification requests registration of the following values in 694 the IANA "OAuth Authorization Server Metadata" registry 695 [IANA.OAuth.Parameters] established by [RFC8414]. 697 * Metadata Name: "dpop_signing_alg_values_supported" 699 * Metadata Description: JSON array containing a list of the JWS 700 algorithms supported for DPoP proof JWTs 702 * Change Controller: IESG 704 * Specification Document(s): [[ Section 8 of this specification ]] 706 11. Normative References 708 [RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- 709 Possession Key Semantics for JSON Web Tokens (JWTs)", 710 RFC 7800, DOI 10.17487/RFC7800, April 2016, 711 . 713 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 714 RFC 6749, DOI 10.17487/RFC6749, October 2012, 715 . 717 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 718 Specifications: ABNF", STD 68, RFC 5234, 719 DOI 10.17487/RFC5234, January 2008, 720 . 722 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 723 Resource Identifier (URI): Generic Syntax", STD 66, 724 RFC 3986, DOI 10.17487/RFC3986, January 2005, 725 . 727 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 728 Framework: Bearer Token Usage", RFC 6750, 729 DOI 10.17487/RFC6750, October 2012, 730 . 732 [RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, 733 DOI 10.17487/RFC7518, May 2015, 734 . 736 [RFC7638] Jones, M. and N. Sakimura, "JSON Web Key (JWK) 737 Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September 738 2015, . 740 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 741 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 742 DOI 10.17487/RFC7231, June 2014, 743 . 745 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 746 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 747 2015, . 749 12. Informative References 751 [I-D.ietf-oauth-token-binding] 752 Jones, M., Campbell, B., Bradley, J., and W. Denniss, 753 "OAuth 2.0 Token Binding", Work in Progress, Internet- 754 Draft, draft-ietf-oauth-token-binding-08, 19 October 2018, 755 . 758 [I-D.ietf-oauth-access-token-jwt] 759 Bertocci, V., "JSON Web Token (JWT) Profile for OAuth 2.0 760 Access Tokens", Work in Progress, Internet-Draft, draft- 761 ietf-oauth-access-token-jwt-07, 27 April 2020, 762 . 765 [I-D.ietf-oauth-jwsreq] 766 Sakimura, N. and J. Bradley, "The OAuth 2.0 Authorization 767 Framework: JWT Secured Authorization Request (JAR)", Work 768 in Progress, Internet-Draft, draft-ietf-oauth-jwsreq-21, 769 19 April 2020, 770 . 772 [RFC8705] Campbell, B., Bradley, J., Sakimura, N., and T. 773 Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication 774 and Certificate-Bound Access Tokens", RFC 8705, 775 DOI 10.17487/RFC8705, February 2020, 776 . 778 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 779 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 780 May 2017, . 782 [IANA.MediaTypes] 783 IANA, "Media Types", 784 . 786 [RFC8414] Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 787 Authorization Server Metadata", RFC 8414, 788 DOI 10.17487/RFC8414, June 2018, 789 . 791 [RFC8417] Hunt, P., Ed., Jones, M., Denniss, W., and M. Ansari, 792 "Security Event Token (SET)", RFC 8417, 793 DOI 10.17487/RFC8417, July 2018, 794 . 796 [IANA.JWT] IANA, "JSON Web Token Claims", 797 . 799 [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration 800 Procedures for Message Header Fields", BCP 90, RFC 3864, 801 DOI 10.17487/RFC3864, September 2004, 802 . 804 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 805 Requirement Levels", BCP 14, RFC 2119, 806 DOI 10.17487/RFC2119, March 1997, 807 . 809 [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token 810 (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, 811 . 813 [IANA.OAuth.Params] 814 IANA, "OAuth Parameters", 815 . 817 [IANA.MediaType.StructuredSuffixs] 818 IANA, "Structured Syntax Suffix Registry", 819 . 822 [IANA.Headers] 823 IANA, "Message Headers", 824 . 826 [RFC7235] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 827 Protocol (HTTP/1.1): Authentication", RFC 7235, 828 DOI 10.17487/RFC7235, June 2014, 829 . 831 [IANA.HTTP.AuthSchemes] 832 IANA, "Hypertext Transfer Protocol (HTTP) Authentication 833 Scheme Registry", 834 . 836 [RFC8725] Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best 837 Current Practices", BCP 225, RFC 8725, 838 DOI 10.17487/RFC8725, February 2020, 839 . 841 [I-D.ietf-oauth-security-topics] 842 Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, 843 "OAuth 2.0 Security Best Current Practice", Work in 844 Progress, Internet-Draft, draft-ietf-oauth-security- 845 topics-15, 5 April 2020, . 848 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 849 Unique IDentifier (UUID) URN Namespace", RFC 4122, 850 DOI 10.17487/RFC4122, July 2005, 851 . 853 Appendix A. Acknowledgements 855 We would like to thank Filip Skokan, Mike Engan, Justin Richer, 856 Michael Peck, Vladimir Dzhuvinov, Rob Otto, Dominick Baier, Jim 857 Willeke, Annabelle Backman, Bjorn Hjelm, Steinar Noem, Aaron Parecki, 858 Neil Madden, Paul Querna, Dick Hardt, Dave Tonge, Jared Jennings, 859 Mark Haine and others (please let us know, if you've been mistakenly 860 omitted) for their valuable input, feedback and general support of 861 this work. 863 This document resulted from discussions at the 4th OAuth Security 864 Workshop in Stuttgart, Germany. We thank the organizers of this 865 workshop (Ralf Kusters, Guido Schmitz). 867 Appendix B. Document History 869 [[ To be removed from the final specification ]] 871 -01 873 * Editorial updates 874 * Attempt to more formally define the DPoP Authorization header 875 scheme 877 * Define the 401/WWW-Authenticate challenge 879 * Added "invalid_dpop_proof" error code for DPoP errors in token 880 request 882 * Fixed up and added to the IANA section 884 * Added "dpop_signing_alg_values_supported" authorization server 885 metadata 887 * Moved the Acknowledgements into an Appendix and added a bunch of 888 names (best effort) 890 -00 [[ Working Group Draft ]] 892 * Working group draft 894 -04 896 * Update OAuth MTLS reference to RFC 8705 898 * Use the newish RFC v3 XML and HTML format 900 -03 902 * rework the text around uniqueness requirements on the jti claim in 903 the DPoP proof JWT 905 * make tokens a bit smaller by using "htm", "htu", and "jkt" rather 906 than "http_method", "http_uri", and "jkt#S256" respectively 908 * more explicit recommendation to use mTLS if that is available 910 * added David Waite as co-author 912 * editorial updates 914 -02 916 * added normalization rules for URIs 918 * removed distinction between proof and binding 920 * "jwk" header again used instead of "cnf" claim in DPoP proof 921 * renamed "Bearer-DPoP" token type to "DPoP" 923 * removed ability for key rotation 925 * added security considerations on request integrity 927 * explicit advice on extending DPoP proofs to sign other parts of 928 the HTTP messages 930 * only use the jkt#S256 in ATs 932 * iat instead of exp in DPoP proof JWTs 934 * updated guidance on token_type evaluation 936 -01 938 * fixed inconsistencies 940 * moved binding and proof messages to headers instead of parameters 942 * extracted and unified definition of DPoP JWTs 944 * improved description 946 -00 948 * first draft 950 Authors' Addresses 952 Daniel Fett 953 yes.com 955 Email: mail@danielfett.de 957 Brian Campbell 958 Ping Identity 960 Email: bcampbell@pingidentity.com 962 John Bradley 963 Yubico 965 Email: ve7jtb@ve7jtb.com 966 Torsten Lodderstedt 967 yes.com 969 Email: torsten@lodderstedt.net 971 Michael Jones 972 Microsoft 974 Email: mbj@microsoft.com 975 URI: https://self-issued.info/ 977 David Waite 978 Ping Identity 980 Email: david@alkaline-solutions.com