idnits 2.17.1 draft-ietf-oauth-dpop-05.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 == Using lowercase 'not' together with uppercase 'MUST', 'SHALL', 'SHOULD', or 'RECOMMENDED' is not an accepted usage according to RFC 2119. Please use uppercase 'NOT' together with RFC 2119 keywords (if that is what you mean). Found 'MUST not' in this paragraph: Note that the nonces provided by the two kinds of servers are different and MUST not be confused with one another. In particular, a nonce provided to the client by a particular server MUST only be used with that server and no other. Developers should also take care to not confuse this nonce with the OpenID Connect [OpenID.Core] ID Token nonce, should one also be present. -- The document date (19 February 2022) is 794 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 (-26) exists of draft-ietf-oauth-security-topics-19 -- Obsolete informational reference (is this intentional?): RFC 7230 (Obsoleted by RFC 9110, RFC 9112) -- Obsolete informational reference (is this intentional?): RFC 7235 (Obsoleted by RFC 9110) Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 3 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: 23 August 2022 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 19 February 2022 16 OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer 17 (DPoP) 18 draft-ietf-oauth-dpop-05 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 23 August 2022. 44 Copyright Notice 46 Copyright (c) 2022 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 Revised BSD License text as 55 described in Section 4.e of the Trust Legal Provisions and are 56 provided without warranty as described in the Revised BSD License. 58 Table of Contents 60 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 61 1.1. Conventions and Terminology . . . . . . . . . . . . . . . 4 62 2. Objectives . . . . . . . . . . . . . . . . . . . . . . . . . 4 63 3. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 64 4. DPoP Proof JWTs . . . . . . . . . . . . . . . . . . . . . . . 7 65 4.1. The DPoP HTTP Header . . . . . . . . . . . . . . . . . . 7 66 4.2. DPoP Proof JWT Syntax . . . . . . . . . . . . . . . . . . 8 67 4.3. Checking DPoP Proofs . . . . . . . . . . . . . . . . . . 10 68 5. DPoP Access Token Request . . . . . . . . . . . . . . . . . . 11 69 5.1. Authorization Server Metadata . . . . . . . . . . . . . . 13 70 5.2. Client Registration Metadata . . . . . . . . . . . . . . 14 71 6. Public Key Confirmation . . . . . . . . . . . . . . . . . . . 14 72 6.1. JWK Thumbprint Confirmation Method . . . . . . . . . . . 15 73 6.2. JWK Thumbprint Confirmation Method in Token 74 Introspection . . . . . . . . . . . . . . . . . . . . . . 15 75 7. Protected Resource Access . . . . . . . . . . . . . . . . . . 17 76 7.1. The DPoP Authentication Scheme . . . . . . . . . . . . . 17 77 7.2. Compatibility with the Bearer Authentication Scheme . . . 20 78 8. Authorization Server-Provided Nonce . . . . . . . . . . . . . 20 79 8.1. Providing a New Nonce Value . . . . . . . . . . . . . . . 22 80 9. Resource Server-Provided Nonce . . . . . . . . . . . . . . . 23 81 10. Authorization Code Binding to DPoP Key . . . . . . . . . . . 23 82 11. DPoP with Pushed Authorization Requests . . . . . . . . . . . 24 83 12. Security Considerations . . . . . . . . . . . . . . . . . . . 25 84 12.1. DPoP Proof Replay . . . . . . . . . . . . . . . . . . . 25 85 12.2. DPoP Proof Pre-Generation . . . . . . . . . . . . . . . 26 86 12.3. DPoP Nonce Downgrade . . . . . . . . . . . . . . . . . . 26 87 12.4. Untrusted Code in the Client Context . . . . . . . . . . 26 88 12.5. Signed JWT Swapping . . . . . . . . . . . . . . . . . . 27 89 12.6. Signature Algorithms . . . . . . . . . . . . . . . . . . 27 90 12.7. Message Integrity . . . . . . . . . . . . . . . . . . . 27 91 12.8. Access Token and Public Key Binding . . . . . . . . . . 28 92 12.9. Authorization Code and Public Key Binding . . . . . . . 29 93 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 94 13.1. OAuth Access Token Type Registration . . . . . . . . . . 29 95 13.2. OAuth Extensions Error Registration . . . . . . . . . . 30 96 13.3. OAuth Parameters Registration . . . . . . . . . . . . . 30 97 13.4. HTTP Authentication Scheme Registration . . . . . . . . 31 98 13.5. Media Type Registration . . . . . . . . . . . . . . . . 31 99 13.6. JWT Confirmation Methods Registration . . . . . . . . . 31 100 13.7. JSON Web Token Claims Registration . . . . . . . . . . . 31 101 13.8. HTTP Message Header Field Names Registration . . . . . . 32 102 13.9. OAuth Authorization Server Metadata Registration . . . . 33 103 13.10. OAuth Dynamic Client Registration Metadata . . . . . . . 33 104 14. Normative References . . . . . . . . . . . . . . . . . . . . 33 105 15. Informative References . . . . . . . . . . . . . . . . . . . 34 106 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 37 107 Appendix B. Document History . . . . . . . . . . . . . . . . . . 38 108 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 110 1. Introduction 112 DPoP (for Demonstrating Proof-of-Possession at the Application Layer) 113 is an application-level mechanism for sender-constraining OAuth 114 access and refresh tokens. It enables a client to prove the 115 possession of a public/private key pair by including a DPoP header in 116 an HTTP request. The value of the header is a JWT [RFC7519] that 117 enables the authorization server to bind issued tokens to the public 118 part of a client's key pair. Recipients of such tokens are then able 119 to verify the binding of the token to the key pair that the client 120 has demonstrated that it holds via the DPoP header, thereby providing 121 some assurance that the client presenting the token also possesses 122 the private key. In other words, the legitimate presenter of the 123 token is constrained to be the sender that holds and can prove 124 possession of the private part of the key pair. 126 The mechanism described herein can be used in cases where other 127 methods of sender-constraining tokens that utilize elements of the 128 underlying secure transport layer, such as [RFC8705] or 129 [I-D.ietf-oauth-token-binding], are not available or desirable. For 130 example, due to a sub-par user experience of TLS client 131 authentication in user agents and a lack of support for HTTP token 132 binding, neither mechanism can be used if an OAuth client is a Single 133 Page Application (SPA) running in a web browser. Native applications 134 installed and run on a user's device are another example well 135 positioned to benefit from DPoP-bound tokens to guard against misuse 136 of tokens by a compromised or malicious resource. Such applications 137 often have dedicated protected storage for cryptographic keys. 139 DPoP can be used to sender-constrain access tokens regardless of the 140 client authentication method employed, but DPoP itself is not used 141 for client authentication. DPoP can also be used to sender-constrain 142 refresh tokens issued to public clients (those without authentication 143 credentials associated with the client_id). 145 1.1. Conventions and Terminology 147 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 148 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 149 "OPTIONAL" in this document are to be interpreted as described in BCP 150 14 [RFC2119] [RFC8174] when, and only when, they appear in all 151 capitals, as shown here. 153 This specification uses the terms "access token", "refresh token", 154 "authorization server", "resource server", "authorization endpoint", 155 "authorization request", "authorization response", "token endpoint", 156 "grant type", "access token request", "access token response", and 157 "client" defined by The OAuth 2.0 Authorization Framework [RFC6749]. 159 2. Objectives 161 The primary aim of DPoP is to prevent unauthorized or illegitimate 162 parties from using leaked or stolen access tokens by binding a token 163 to a public key upon issuance and requiring that the client proves 164 possession of the corresponding private key when using the token. 165 This constrains the legitimate sender of the token to only the party 166 with access to the private key and gives the server receiving the 167 token added assurances that the sender is legitimately authorized to 168 use it. 170 Access tokens that are sender-constrained via DPoP thus stand in 171 contrast to the typical bearer token, which can be used by any party 172 in possession of such a token. Although protections generally exist 173 to prevent unintended disclosure of bearer tokens, unforeseen vectors 174 for leakage have occurred due to vulnerabilities and implementation 175 issues in other layers in the protocol or software stack (CRIME, 176 BREACH, Heartbleed, and the Cloudflare parser bug are some examples). 177 There have also been numerous published token theft attacks on OAuth 178 implementations themselves. DPoP provides a general defense in depth 179 against the impact of unanticipated token leakage. DPoP is not, 180 however, a substitute for a secure transport and MUST always be used 181 in conjunction with HTTPS. 183 The very nature of the typical OAuth protocol interaction 184 necessitates that the client discloses the access token to the 185 protected resources that it accesses. The attacker model in 186 [I-D.ietf-oauth-security-topics] describes cases where a protected 187 resource might be counterfeit, malicious or compromised and plays 188 received tokens against other protected resources to gain 189 unauthorized access. Properly audience restricting access tokens can 190 prevent such misuse, however, doing so in practice has proven to be 191 prohibitively cumbersome for many deployments (even despite 192 extensions such as [RFC8707]). Sender-constraining access tokens is 193 a more robust and straightforward mechanism to prevent such token 194 replay at a different endpoint and DPoP is an accessible application 195 layer means of doing so. 197 Due to the potential for cross-site scripting (XSS), browser-based 198 OAuth clients bring to bear added considerations with respect to 199 protecting tokens. The most straightforward XSS-based attack is for 200 an attacker to exfiltrate a token and use it themselves completely 201 independent of the legitimate client. A stolen access token is used 202 for protected resource access and a stolen refresh token for 203 obtaining new access tokens. If the private key is non-extractable 204 (as is possible with [W3C.WebCryptoAPI]), DPoP renders exfiltrated 205 tokens alone unusable. 207 XXS vulnerabilities also allow an attacker to execute code in the 208 context of the browser-based client application and maliciously use a 209 token indirectly through the client. That execution context has 210 access to utilize the signing key and thus can produce DPoP proofs to 211 use in conjunction with the token. At this application layer there 212 is most likely no feasible defense against this threat except 213 generally preventing XSS, therefore it is considered out of scope for 214 DPoP. 216 Malicious XSS code executed in the context of the browser-based 217 client application is also in a position to create DPoP proofs with 218 timestamp values in the future and exfiltrate them in conjunction 219 with a token. These stolen artifacts can later be used together 220 independent of the client application to access protected resources. 221 To prevent this, servers can optionally require clients to include a 222 server-chosen value into the proof that cannot be predicted by an 223 attacker (nonce). In the absence of the optional nonce, the impact 224 of pre-computed DPoP proofs is limited somewhat by the proof being 225 bound to an access token on protected resource access. Because a 226 proof covering an access token that does not yet exist cannot 227 feasibly be created, access tokens obtained with an exfiltrated 228 refresh token and pre-computed proofs will be unusable. 230 Additional security considerations are discussed in Section 12. 232 3. Concept 234 The main data structure introduced by this specification is a DPoP 235 proof JWT, described in detail below, which is sent as a header in an 236 HTTP request. A client uses a DPoP proof JWT to prove the possession 237 of a private key corresponding to a certain public key. 239 Roughly speaking, a DPoP proof is a signature over some data of the 240 HTTP request to which it is attached, a timestamp, a unique 241 identifier, an optional server-provided nonce, and a hash of the 242 associated access token when an access token is present within the 243 request. 245 +--------+ +---------------+ 246 | |--(A)-- Token Request ------------------->| | 247 | Client | (DPoP Proof) | Authorization | 248 | | | Server | 249 | |<-(B)-- DPoP-bound Access Token ----------| | 250 | | (token_type=DPoP) +---------------+ 251 | | 252 | | 253 | | +---------------+ 254 | |--(C)-- DPoP-bound Access Token --------->| | 255 | | (DPoP Proof) | Resource | 256 | | | Server | 257 | |<-(D)-- Protected Resource ---------------| | 258 | | +---------------+ 259 +--------+ 261 Figure 1: Basic DPoP Flow 263 The basic steps of an OAuth flow with DPoP (without the optional 264 nonce) are shown in Figure 1: 266 * (A) In the Token Request, the client sends an authorization grant 267 (e.g., an authorization code, refresh token, etc.) 268 to the authorization server in order to obtain an access token 269 (and potentially a refresh token). The client attaches a DPoP 270 proof to the request in an HTTP header. 272 * (B) The authorization server binds (sender-constrains) the access 273 token to the public key claimed by the client in the DPoP proof; 274 that is, the access token cannot be used without proving 275 possession of the respective private key. If a refresh token is 276 issued to a public client, it too is bound to the public key of 277 the DPoP proof. 279 * (C) To use the access token, the client has to prove possession of 280 the private key by, again, adding a header to the request that 281 carries a DPoP proof for that request. The resource server needs 282 to receive information about the public key to which the access 283 token is bound. This information may be encoded directly into the 284 access token (for JWT structured access tokens) or provided via 285 token introspection endpoint (not shown). The resource server 286 verifies that the public key to which the access token is bound 287 matches the public key of the DPoP proof. It also verifies that 288 the access token hash in the DPoP proof matches the access token 289 presented in the request. 291 * (D) The resource server refuses to serve the request if the 292 signature check fails or the data in the DPoP proof is wrong, 293 e.g., the request URI does not match the URI claim in the DPoP 294 proof JWT. The access token itself, of course, must also be valid 295 in all other respects. 297 The DPoP mechanism presented herein is not a client authentication 298 method. In fact, a primary use case of DPoP is for public clients 299 (e.g., single page applications and native applications) that do not 300 use client authentication. Nonetheless, DPoP is designed such that 301 it is compatible with private_key_jwt and all other client 302 authentication methods. 304 DPoP does not directly ensure message integrity but relies on the TLS 305 layer for that purpose. See Section 12 for details. 307 4. DPoP Proof JWTs 309 DPoP introduces the concept of a DPoP proof, which is a JWT created 310 by the client and sent with an HTTP request using the DPoP header 311 field. Each HTTP request requires a unique DPoP proof. 313 A valid DPoP proof demonstrates to the server that the client holds 314 the private key that was used to sign the DPoP proof JWT. This 315 enables authorization servers to bind issued tokens to the 316 corresponding public key (as described in Section 5) and for resource 317 servers to verify the key-binding of tokens that it receives (see 318 Section 7.1), which prevents said tokens from being used by any 319 entity that does not have access to the private key. 321 The DPoP proof demonstrates possession of a key and, by itself, is 322 not an authentication or access control mechanism. When presented in 323 conjunction with a key-bound access token as described in 324 Section 7.1, the DPoP proof provides additional assurance about the 325 legitimacy of the client to present the access token. However, a 326 valid DPoP proof JWT is not sufficient alone to make access control 327 decisions. 329 4.1. The DPoP HTTP Header 331 A DPoP proof is included in an HTTP request using the following 332 message header field. 334 DPoP A JWT that adheres to the structure and syntax of Section 4.2. 336 Figure 2 shows an example DPoP HTTP header field (line breaks and 337 extra whitespace for display purposes only). 339 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 340 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 341 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 342 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj 343 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia 344 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg 345 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg 347 Figure 2: Example DPoP header 349 Note that per [RFC7230] header field names are case-insensitive; so 350 DPoP, DPOP, dpop, etc., are all valid and equivalent header field 351 names. Case is significant in the header field value, however. 353 4.2. DPoP Proof JWT Syntax 355 A DPoP proof is a JWT ([RFC7519]) that is signed (using JWS, 356 [RFC7515]) with a private key chosen by the client (see below). The 357 header of a DPoP JWT contains at least the following parameters: 359 * typ: type header, value dpop+jwt (REQUIRED). 361 * alg: a digital signature algorithm identifier as per [RFC7518] 362 (REQUIRED). MUST NOT be none or an identifier for a symmetric 363 algorithm (MAC). 365 * jwk: representing the public key chosen by the client, in JWK 366 format, as defined in Section 4.1.3 of [RFC7515] (REQUIRED). MUST 367 NOT contain the private key. 369 The payload of a DPoP proof contains at least the following claims: 371 * jti: Unique identifier for the DPoP proof JWT (REQUIRED). The 372 value MUST be assigned such that there is a negligible probability 373 that the same value will be assigned to any other DPoP proof used 374 in the same context during the time window of validity. Such 375 uniqueness can be accomplished by encoding (base64url or any other 376 suitable encoding) at least 96 bits of pseudorandom data or by 377 using a version 4 UUID string according to [RFC4122]. The jti can 378 be used by the server for replay detection and prevention, see 379 Section 12.1. 381 * htm: The HTTP method for the request to which the JWT is attached, 382 as defined in [RFC7231] (REQUIRED). 384 * htu: The HTTP URI used for the request, without query and fragment 385 parts (REQUIRED). 387 * iat: Time at which the JWT was created (REQUIRED). 389 When the DPoP proof is used in conjunction with the presentation of 390 an access token, see Section 7, the DPoP proof MUST also contain the 391 following claim: 393 * ath: hash of the access token (REQUIRED). The value MUST be the 394 result of a base64url encoding (with no padding) the SHA-256 hash 395 of the ASCII encoding of the associated access token's value. 397 A DPoP proof MAY contain other headers or claims as defined by 398 extension, profile, or deployment specific requirements. 400 Figure 3 is a conceptual example showing the decoded content of the 401 DPoP proof in Figure 2. The JSON of the JOSE header and payload are 402 shown, but the signature part is omitted. As usual, line breaks and 403 extra whitespace are included for formatting and readability. 405 { 406 "typ":"dpop+jwt", 407 "alg":"ES256", 408 "jwk": { 409 "kty":"EC", 410 "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs", 411 "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA", 412 "crv":"P-256" 413 } 414 } 415 . 416 { 417 "jti":"-BwC3ESc6acc2lTc", 418 "htm":"POST", 419 "htu":"https://server.example.com/token", 420 "iat":1562262616 421 } 423 Figure 3: Example JWT content of a DPoP proof 425 Of the HTTP content in the request, only the HTTP method and URI are 426 included in the DPoP JWT, and therefore only these 2 headers of the 427 request are covered by the DPoP proof and its signature. The idea is 428 sign just enough of the HTTP data to provide reasonable proof-of- 429 possession with respect to the HTTP request. But that it be a 430 minimal subset of the HTTP data so as to avoid the substantial 431 difficulties inherent in attempting to normalize HTTP messages. 432 Nonetheless, DPoP proofs can be extended to contain other information 433 of the HTTP request (see also Section 12.7). 435 4.3. Checking DPoP Proofs 437 To check if a string that was received as part of an HTTP Request is 438 a valid DPoP proof, the receiving server MUST ensure that 440 1. that there is not more than one DPoP header in the request, 442 2. the string value of the header field is a well-formed JWT, 444 3. all required claims per Section 4.2 are contained in the JWT, 446 4. the typ field in the header has the value dpop+jwt, 448 5. the algorithm in the header of the JWT indicates an asymmetric 449 digital signature algorithm, is not none, is supported by the 450 application, and is deemed secure, 452 6. the JWT signature verifies with the public key contained in the 453 jwk header of the JWT, 455 7. the htm claim matches the HTTP method value of the HTTP request 456 in which the JWT was received, 458 8. the htu claim matches the HTTPS URI value for the HTTP request 459 in which the JWT was received, ignoring any query and fragment 460 parts, 462 9. if the server provided a nonce value to the client, the nonce 463 claim matches the server-provided nonce value, 465 10. the token was issued within an acceptable timeframe and, within 466 a reasonable consideration of accuracy and resource utilization, 467 a proof JWT with the same jti value has not previously been 468 received at the same resource during that time period (see 469 Section 12.1), 471 11. when presented to a protected resource in conjunction with an 472 access token, ensure that the value of the ath claim equals the 473 hash of that access token and confirm that the public key to 474 which the access token is bound matches the public key from the 475 DPoP proof. 477 Servers SHOULD employ Syntax-Based Normalization and Scheme-Based 478 Normalization in accordance with Section 6.2.2. and Section 6.2.3. of 479 [RFC3986] before comparing the htu claim. 481 5. DPoP Access Token Request 483 To request an access token that is bound to a public key using DPoP, 484 the client MUST provide a valid DPoP proof JWT in a DPoP header when 485 making an access token request to the authorization server's token 486 endpoint. This is applicable for all access token requests 487 regardless of grant type (including, for example, the common 488 authorization_code and refresh_token grant types but also extension 489 grants such as the JWT authorization grant [RFC7523]). The HTTPS 490 request shown in Figure 4 illustrates such an access token request 491 using an authorization code grant with a DPoP proof JWT in the DPoP 492 header (extra line breaks and whitespace for display purposes only). 494 POST /token HTTP/1.1 495 Host: server.example.com 496 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 497 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 498 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 499 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 500 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj 501 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia 502 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg 503 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg 505 grant_type=authorization_code 506 &code=SplxlOBeZQQYbYS6WxSbIA 507 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 508 &code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz- 510 Figure 4: Token Request for a DPoP sender-constrained token using an 511 authorization code 513 The DPoP HTTP header MUST contain a valid DPoP proof JWT. If the 514 DPoP proof is invalid, the authorization server issues an error 515 response per Section 5.2 of [RFC6749] with invalid_dpop_proof as the 516 value of the error parameter. 518 To sender-constrain the access token, after checking the validity of 519 the DPoP proof, the authorization server associates the issued access 520 token with the public key from the DPoP proof, which can be 521 accomplished as described in Section 6. A token_type of DPoP MUST be 522 included in the access token response to signal to the client that 523 the access token was bound to its DPoP key and can be used as 524 described in Section 7.1. The example response shown in Figure 5 525 illustrates such a response. 527 HTTP/1.1 200 OK 528 Content-Type: application/json 529 Cache-Control: no-store 531 { 532 "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU", 533 "token_type": "DPoP", 534 "expires_in": 2677, 535 "refresh_token": "Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g" 536 } 538 Figure 5: Access Token Response 540 The example response in Figure 5 includes a refresh token which the 541 client can use to obtain a new access token when the previous one 542 expires. Refreshing an access token is a token request using the 543 refresh_token grant type made to the authorization server's token 544 endpoint. As with all access token requests, the client makes it a 545 DPoP request by including a DPoP proof, as shown in the Figure 6 546 example (extra line breaks and whitespace for display purposes only). 548 POST /token HTTP/1.1 549 Host: server.example.com 550 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 551 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 552 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 553 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 554 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj 555 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia 556 WF0IjoxNTYyMjY1Mjk2fQ.pAqut2IRDm_De6PR93SYmGBPXpwrAk90e8cP2hjiaG5Qs 557 GSuKDYW7_X620BxqhvYC8ynrrvZLTk41mSRroapUA 559 grant_type=refresh_token 560 &refresh_token=Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g 562 Figure 6: Token Request for a DPoP-bound Token using a Refresh Token 564 When an authorization server supporting DPoP issues a refresh token 565 to a public client that presents a valid DPoP proof at the token 566 endpoint, the refresh token MUST be bound to the respective public 567 key. The binding MUST be validated when the refresh token is later 568 presented to get new access tokens. As a result, such a client MUST 569 present a DPoP proof for the same key that was used to obtain the 570 refresh token each time that refresh token is used to obtain a new 571 access token. The implementation details of the binding of the 572 refresh token are at the discretion of the authorization server. The 573 server both produces and validates the refresh tokens that it issues 574 so there is no interoperability consideration in the specific details 575 of the binding. 577 An authorization server MAY elect to issue access tokens which are 578 not DPoP bound, which is signaled to the client with a value of 579 Bearer in the token_type parameter of the access token response per 580 [RFC6750]. For a public client that is also issued a refresh token, 581 this has the effect of DPoP-binding the refresh token alone, which 582 can improve the security posture even when protected resources are 583 not updated to support DPoP. 585 If a client receives a different token_type value than DPoP in the 586 response, the access token protection provided by DPoP is not given. 587 The client MUST discard the response in this case if this protection 588 is deemed important for the security of the application and MAY 589 continue as in a regular OAuth interaction otherwise. 591 Refresh tokens issued to confidential clients (those having 592 established authentication credentials with the authorization server) 593 are not bound to the DPoP proof public key because they are already 594 sender-constrained with a different existing mechanism. The OAuth 595 2.0 Authorization Framework [RFC6749] already requires that an 596 authorization server bind refresh tokens to the client to which they 597 were issued and that confidential clients authenticate to the 598 authorization server when presenting a refresh token. As a result, 599 such refresh tokens are sender-constrained by way of the client ID 600 and the associated authentication requirement. This existing sender- 601 constraining mechanism is more flexible (e.g., it allows credential 602 rotation for the client without invalidating refresh tokens) than 603 binding directly to a particular public key. 605 5.1. Authorization Server Metadata 607 This document introduces the following authorization server metadata 608 [RFC8414] parameter to signal support for DPoP in general and the 609 specific JWS alg values the authorization server supports for DPoP 610 proof JWTs. 612 dpop_signing_alg_values_supported A JSON array containing a list of 613 the JWS alg values supported by the authorization server for DPoP 614 proof JWTs. 616 5.2. Client Registration Metadata 618 The Dynamic Client Registration Protocol [RFC7591] defines an API for 619 dynamically registering OAuth 2.0 client metadata with authorization 620 servers. The metadata defined by [RFC7591], and registered 621 extensions to it, also imply a general data model for clients that is 622 useful for authorization server implementations even when the Dynamic 623 Client Registration Protocol isn't in play. Such implementations 624 will typically have some sort of user interface available for 625 managing client configuration. 627 This document introduces the following client registration metadata 628 [RFC7591] parameter to indicate that the client always uses DPoP when 629 requesting tokens from the authorization server. 631 always_uses_dpop Boolean value specifying whether the client always 632 uses DPoP for token requests. If omitted, the default value is 633 false. 635 If true, the authorization server MUST reject token requests from 636 this client that do not contain the DPoP header. 638 6. Public Key Confirmation 640 Resource servers MUST be able to reliably identify whether an access 641 token is bound using DPoP and ascertain sufficient information about 642 the public key to which the token is bound in order to verify the 643 binding with respect to the presented DPoP proof (see Section 7.1). 644 Such a binding is accomplished by associating the public key with the 645 token in a way that can be accessed by the protected resource, such 646 as embedding the JWK hash in the issued access token directly, using 647 the syntax described in Section 6.1, or through token introspection 648 as described in Section 6.2. Other methods of associating a public 649 key with an access token are possible, per agreement by the 650 authorization server and the protected resource, but are beyond the 651 scope of this specification. 653 Resource servers supporting DPoP MUST ensure that the public key from 654 the DPoP proof matches the public key to which the access token is 655 bound. 657 6.1. JWK Thumbprint Confirmation Method 659 When access tokens are represented as JSON Web Tokens (JWT) 660 [RFC7519], the public key information SHOULD be represented using the 661 jkt confirmation method member defined herein. To convey the hash of 662 a public key in a JWT, this specification introduces the following 663 JWT Confirmation Method [RFC7800] member for use under the cnf claim. 665 jkt JWK SHA-256 Thumbprint Confirmation Method. The value of the 666 jkt member MUST be the base64url encoding (as defined in 667 [RFC7515]) of the JWK SHA-256 Thumbprint (according to [RFC7638]) 668 of the DPoP public key (in JWK format) to which the access token 669 is bound. 671 The following example JWT in Figure 7 with decoded JWT payload shown 672 in Figure 8 contains a cnf claim with the jkt JWK Thumbprint 673 confirmation method member. The jkt value in these examples is the 674 hash of the public key from the DPoP proofs in the examples in 675 Section 5. 677 eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1 678 wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE 679 1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll 680 5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO 681 YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA 683 Figure 7: JWT containing a JWK SHA-256 Thumbprint Confirmation 685 { 686 "sub":"someone@example.com", 687 "iss":"https://server.example.com", 688 "nbf":1562262611, 689 "exp":1562266216, 690 "cnf":{"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"} 691 } 693 Figure 8: JWT Claims Set with a JWK SHA-256 Thumbprint Confirmation 695 6.2. JWK Thumbprint Confirmation Method in Token Introspection 697 OAuth 2.0 Token Introspection [RFC7662] defines a method for a 698 protected resource to query an authorization server about the active 699 state of an access token as well as to determine metainformation 700 about the token. 702 For a DPoP-bound access token, the hash of the public key to which 703 the token is bound is conveyed to the protected resource as 704 metainformation in a token introspection response. The hash is 705 conveyed using the same cnf content with jkt member structure as the 706 JWK Thumbprint confirmation method, described in Section 6.1, as a 707 top-level member of the introspection response JSON. Note that the 708 resource server does not send a DPoP proof with the introspection 709 request and the authorization server does not validate an access 710 token's DPoP binding at the introspection endpoint. Rather the 711 resource server uses the data of the introspection response to 712 validate the access token binding itself locally. 714 If the token_type member is included in the introspection response, 715 it MUST contain the value DPoP. 717 The example introspection request in Figure 9 and corresponding 718 response in Figure 10 illustrate an introspection exchange for the 719 example DPoP-bound access token that was issued in Figure 5. 721 POST /as/introspect.oauth2 HTTP/1.1 722 Host: server.example.com 723 Content-Type: application/x-www-form-urlencoded 724 Authorization: Basic cnM6cnM6TWt1LTZnX2xDektJZHo0ZnNON2tZY3lhK1Rp 726 token=Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU 728 Figure 9: Example Introspection Request 730 HTTP/1.1 200 OK 731 Content-Type: application/json 732 Cache-Control: no-store 734 { 735 "active": true, 736 "sub": "someone@example.com", 737 "iss": "https://server.example.com", 738 "nbf": 1562262611, 739 "exp": 1562266216, 740 "cnf": {"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"} 741 } 743 Figure 10: Example Introspection Response for a DPoP-Bound Access 744 Token 746 7. Protected Resource Access 748 To make use of an access token that is bound to a public key using 749 DPoP, a client MUST prove possession of the corresponding private key 750 by providing a DPoP proof in the DPoP request header. As such, 751 protected resource requests with a DPoP-bound access token 752 necessarily must include both a DPoP proof as per Section 4 and the 753 access token as described in Section 7.1. The DPoP proof MUST 754 include the ath claim with a valid hash of the associated access 755 token. 757 7.1. The DPoP Authentication Scheme 759 A DPoP-bound access token is sent using the Authorization request 760 header field per Section 2 of [RFC7235] using an authentication 761 scheme of DPoP. The syntax of the Authorization header field for the 762 DPoP scheme uses the token68 syntax defined in Section 2.1 of 763 [RFC7235] (repeated below for ease of reference) for credentials. 764 The Augmented Backus-Naur Form (ABNF) notation [RFC5234] syntax for 765 DPoP authentication scheme credentials is as follows: 767 token68 = 1*( ALPHA / DIGIT / 768 "-" / "." / "_" / "~" / "+" / "/" ) *"=" 770 credentials = "DPoP" 1*SP token68 772 Figure 11: DPoP Authentication Scheme ABNF 774 For such an access token, a resource server MUST check that a DPoP 775 proof was also received in the DPoP header field of the HTTP request, 776 check the DPoP proof according to the rules in Section 4.3, and check 777 that the public key of the DPoP proof matches the public key to which 778 the access token is bound per Section 6. 780 The resource server MUST NOT grant access to the resource unless all 781 checks are successful. 783 Figure 12 shows an example request to a protected resource with a 784 DPoP-bound access token in the Authorization header and the DPoP 785 proof in the DPoP header. Following that is Figure 13, which shows 786 the decoded content of that DPoP proof. The JSON of the JOSE header 787 and payload are shown but the signature part is omitted. As usual, 788 line breaks and extra whitespace are included for formatting and 789 readability in both examples. 791 GET /protectedresource HTTP/1.1 792 Host: resource.example.org 793 Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU 794 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik 795 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR 796 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE 797 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj 798 oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z 799 WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF 800 c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E 801 OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA 803 Figure 12: DPoP Protected Resource Request 805 { 806 "typ":"dpop+jwt", 807 "alg":"ES256", 808 "jwk": { 809 "kty":"EC", 810 "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs", 811 "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA", 812 "crv":"P-256" 813 } 814 } 815 . 816 { 817 "jti":"e1j3V_bKic8-LAEB", 818 "htm":"GET", 819 "htu":"https://resource.example.org/protectedresource", 820 "iat":1562262618, 821 "ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo" 822 } 824 Figure 13: Decoded Content of the DPoP Proof JWT in Figure 12 826 Upon receipt of a request for a URI of a protected resource within 827 the protection space requiring DPoP authentication, if the request 828 does not include valid credentials or does not contain an access 829 token sufficient for access to the protected resource, the server can 830 reply with a challenge using the 401 (Unauthorized) status code 831 ([RFC7235], Section 3.1) and the WWW-Authenticate header field 832 ([RFC7235], Section 4.1). The server MAY include the WWW- 833 Authenticate header in response to other conditions as well. 835 In such challenges: 837 * The scheme name is DPoP. 839 * The authentication parameter realm MAY be included to indicate the 840 scope of protection in the manner described in [RFC7235], 841 Section 2.2. 843 * A scope authentication parameter MAY be included as defined in 844 [RFC6750], Section 3. 846 * An error parameter ([RFC6750], Section 3) SHOULD be included to 847 indicate the reason why the request was declined, if the request 848 included an access token but failed authentication. The error 849 parameter values described in Section 3.1 of [RFC6750] are 850 suitable as are any appropriate values defined by extension. The 851 value use_dpop_nonce can be used as described in Section 9 to 852 signal that a nonce is needed in the DPoP proof of subsequent 853 request(s). And invalid_dpop_proof is used to indicate that the 854 DPoP proof itself was deemed invalid based on the criteria of 855 Section 4.3. 857 * An error_description parameter ([RFC6750], Section 3) MAY be 858 included along with the error parameter to provide developers a 859 human-readable explanation that is not meant to be displayed to 860 end-users. 862 * An algs parameter SHOULD be included to signal to the client the 863 JWS algorithms that are acceptable for the DPoP proof JWT. The 864 value of the parameter is a space-delimited list of JWS alg 865 (Algorithm) header values ([RFC7515], Section 4.1.1). 867 * Additional authentication parameters MAY be used and unknown 868 parameters MUST be ignored by recipients. 870 For example, in response to a protected resource request without 871 authentication: 873 HTTP/1.1 401 Unauthorized 874 WWW-Authenticate: DPoP algs="ES256 PS256" 876 Figure 14: HTTP 401 Response to a Protected Resource Request without 877 Authentication 879 And in response to a protected resource request that was rejected 880 because the confirmation of the DPoP binding in the access token 881 failed: 883 HTTP/1.1 401 Unauthorized 884 WWW-Authenticate: DPoP error="invalid_token", 885 error_description="Invalid DPoP key binding", algs="ES256" 887 Figure 15: HTTP 401 Response to a Protected Resource Request with 888 an Invalid Token 890 7.2. Compatibility with the Bearer Authentication Scheme 892 Protected resources simultaneously supporting both the DPoP and 893 Bearer schemes need to update how evaluation of bearer tokens is 894 performed to prevent downgraded usage of a DPoP-bound access tokens. 895 Specifically, such a protected resource MUST reject an access token 896 received as a bearer token per [!@RFC6750], if that token is 897 determined to be DPoP-bound. 899 Section 4.1 of [RFC7235] allows a protected resource to indicate 900 support for multiple authentication schemes (i.e., Bearer and DPoP) 901 with the WWW-Authenticate header field of a 401 (Unauthorized) 902 response. 904 A protected resource that supports only [RFC6750] and is unaware of 905 DPoP would most presumably accept a DPoP-bound access token as a 906 bearer token (JWT [RFC7519] says to ignore unrecognized claims, 907 Introspection [RFC7662] says that other parameters might be present 908 while placing no functional requirements on their presence, and 909 [RFC6750] is effectively silent on the content of the access token as 910 it relates to validity). As such, a client MAY send a DPoP-bound 911 access token using the Bearer scheme upon receipt of a WWW- 912 Authenticate: Bearer challenge from a protected resource (or if it 913 has prior such knowledge about the capabilities of the protected 914 resource). The effect of this likely simplifies the logistics of 915 phased upgrades to protected resources in their support DPoP or even 916 prolonged deployments of protected resources with mixed token type 917 support. 919 8. Authorization Server-Provided Nonce 921 Including a nonce value contributed by the authorization server in 922 the DPoP proof MAY be used by authorization servers to limit the 923 lifetime of DPoP proofs. The server is in control of when to require 924 the use of a new nonce value in subsequent DPoP proofs. 926 Without employing such a mechanism, a malicious party controlling the 927 client (including potentially the end user) can create DPoP proofs 928 for use arbitrarily far in the future. This section specifies how 929 server-provided nonces are used with DPoP. 931 An authorization server MAY supply a nonce value to be included by 932 the client in DPoP proofs sent. In this case, the authorization 933 server responds to requests not including a nonce with an HTTP 400 934 (Bad Request) error response per Section 5.2 of [RFC6749] using 935 use_dpop_nonce as the error code value. The authorization server 936 includes a DPoP-Nonce HTTP header in the response supplying a nonce 937 value to be used when sending the subsequent request. This same 938 error code is used when supplying a new nonce value when there was a 939 nonce mismatch. The client will typically retry the request with the 940 new nonce value supplied upon receiving a use_dpop_nonce error with 941 an accompanying nonce value. 943 For example, in response to a token request without a nonce when the 944 authorization server requires one, the authorization server can 945 respond with a DPoP-Nonce value such as the following to provide a 946 nonce value to include in the DPoP proof: 948 HTTP/1.1 400 Bad Request 949 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v 951 { 952 "error": "use_dpop_nonce" 953 "error_description": 954 "Authorization server requires nonce in DPoP proof" 955 } 957 Figure 16: HTTP 400 Response to a Token Request without a Nonce 959 Other HTTP headers and JSON fields MAY also be included in the error 960 response, but there MUST NOT be more than one DPoP-Nonce header. 962 Upon receiving the nonce, the client is expected to retry its token 963 request using a DPoP proof including the supplied nonce value in the 964 nonce claim of the DPoP proof. An example unencoded JWT Payload of 965 such a DPoP proof including a nonce is: 967 { 968 "jti": "-BwC3ESc6acc2lTc", 969 "htm": "POST", 970 "htu": "https://server.example.com/token", 971 "iat": 1562262616, 972 "nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v" 973 } 975 Figure 17: DPoP Proof Payload Including a Nonce Value 977 The nonce syntax in ABNF as used by [RFC6749] (which is the same as 978 the scope-token syntax) is: 980 nonce = 1*NQCHAR 982 Figure 18: Nonce ABNF 984 The nonce is opaque to the client. 986 If the nonce claim in the DPoP proof of a token request does not 987 exactly match a nonce recently supplied by the authorization server 988 to the client, the authorization server MUST reject the request. The 989 rejection response MAY include a DPoP-Nonce HTTP header providing a 990 new nonce value to use for subsequent requests. 992 The intent is that both clients and servers need to keep only one 993 nonce value for one another. That said, transient circumstances may 994 arise in which the server's and client's stored nonce values differ. 995 However, this situation is self-correcting; with any rejection 996 message, the server can send the client the nonce value that the 997 server wants it to use and the client can store that nonce value and 998 retry the request with it. Even if the client and/or server discard 999 their stored nonce values, that situation is also self-correcting 1000 because new nonce values can be communicated when responding to or 1001 retrying failed requests. 1003 8.1. Providing a New Nonce Value 1005 It is up to the authorization server when to supply a new nonce value 1006 for the client to use. The client is expected to use the existing 1007 supplied nonce in DPoP proofs until the server supplies a new nonce 1008 value. 1010 The authorization server MAY supply the new nonce in the same way 1011 that the initial one was supplied: by using a DPoP-Nonce HTTP header 1012 in the response. Of course, each time this happens it requires an 1013 extra protocol round trip. 1015 A more efficient manner of supplying a new nonce value is also 1016 defined -- by including a DPoP-Nonce HTTP header in the HTTP 200 (OK) 1017 response from the previous request. The client MUST use the new 1018 nonce value supplied for the next token request, and for all 1019 subsequent token requests until the authorization server supplies a 1020 new nonce. 1022 Responses that include the DPoP-Nonce HTTP header should be 1023 uncacheable (e.g., using Cache-Control: no-store in response to a GET 1024 request) to prevent the response being used to serve a subsequent 1025 request and a stale nonce value being used as a result. 1027 An example 200 OK response providing a new nonce value is: 1029 HTTP/1.1 200 OK 1030 Cache-Control: no-store 1031 DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1 1032 Figure 19: HTTP 200 Response Providing the Next Nonce Value 1034 9. Resource Server-Provided Nonce 1036 Resource servers can also choose to provide a nonce value to be 1037 included in DPoP proofs sent to them. They provide the nonce using 1038 the DPoP-Nonce header in same way that authorization servers do. The 1039 error signaling is performed as described in Section 7.1. Resource 1040 servers use an HTTP 401 (Unauthorized) error code with an 1041 accompanying WWW-Authenticate: DPoP value and DPoP-Nonce value to 1042 accomplish this. 1044 For example, in response to a resource request without a nonce when 1045 the resource server requires one, the resource server can respond 1046 with a DPoP-Nonce value such as the following to provide a nonce 1047 value to include in the DPoP proof: 1049 HTTP/1.1 401 Unauthorized 1050 WWW-Authenticate: DPoP error="use_dpop_nonce", 1051 error_description="Resource server requires nonce in DPoP proof" 1052 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v 1054 Figure 20: HTTP 401 Response to a Resource Request without a Nonce 1056 Note that the nonces provided by the two kinds of servers are 1057 different and MUST not be confused with one another. In particular, 1058 a nonce provided to the client by a particular server MUST only be 1059 used with that server and no other. Developers should also take care 1060 to not confuse this nonce with the OpenID Connect [OpenID.Core] ID 1061 Token nonce, should one also be present. 1063 10. Authorization Code Binding to DPoP Key 1065 Binding the authorization code issued to the client's proof-of- 1066 possession key can enable end-to-end binding of the entire 1067 authorization flow. This specification defines the dpop_jkt 1068 authorization request parameter for this purpose. The value of the 1069 dpop_jkt authorization request parameter is the JSON Web Key (JWK) 1070 Thumbprint [RFC7638] of the proof-of-possession public key using the 1071 SHA-256 hash function - the same value as used for the jkt 1072 confirmation method defined in Section 6.1. 1074 When a token request is received, the authorization server computes 1075 the JWK thumbprint of the proof-of-possession public key in the DPoP 1076 proof and verifies that it matches the dpop_jkt parameter value in 1077 the authorization request. If they do not match, it MUST reject the 1078 request. 1080 An example authorization request using the dpop_jkt authorization 1081 request parameter is: 1083 GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz 1084 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 1085 &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 1086 &code_challenge_method=S256 1087 &dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1 1088 Host: server.example.com 1090 Figure 21: Authorization Request using the dpop_jkt Parameter 1092 Use of the dpop_jkt authorization request parameter is OPTIONAL. 1093 Note that the dpop_jkt authorization request parameter MAY also be 1094 used in combination with PKCE [RFC7636]. 1096 11. DPoP with Pushed Authorization Requests 1098 When Pushed Authorization Requests (PAR, [RFC9126]) are used in 1099 conjunction with DPoP, there are two ways in which the DPoP key can 1100 be communicated in the PAR request: 1102 * The dpop_jkt parameter can be used as described above to bind the 1103 issued authorization code to a specific key. In this case, 1104 dpop_jkt MUST be included alongside other authorization request 1105 parameters in the POST body of the PAR request. 1107 * Alternatively, the DPoP header can be added to the PAR request. 1108 In this case, the authorization server MUST check the provided 1109 DPoP proof JWT as defined in Section 4.3. It MUST further behave 1110 as if the contained public key's thumbprint was provided using 1111 dpop_jkt, i.e., reject the subsequent token request unless a DPoP 1112 proof for the same key is provided. This can help to simplify the 1113 implementation of the client, as it can "blindly" attach the DPoP 1114 header to all requests to the authorization server regardless of 1115 the type of request. Additionally, it provides a stronger 1116 binding, as the DPoP header contains a proof of possession of the 1117 private key. 1119 Both mechanisms MUST be supported by an authorization server that 1120 supports PAR and DPoP. If both mechanisms are used at the same time, 1121 the authorization server MUST reject the request if the JWK 1122 Thumbprint in dpop_jkt does not match the public key in the DPoP 1123 header. 1125 12. Security Considerations 1127 In DPoP, the prevention of token replay at a different endpoint (see 1128 Section 2) is achieved through the binding of the DPoP proof to a 1129 certain URI and HTTP method plus the optional server-provided nonce. 1130 DPoP, however, has a somewhat different nature of protection than 1131 TLS-based methods such as OAuth Mutual TLS [RFC8705] or OAuth Token 1132 Binding [I-D.ietf-oauth-token-binding] (see also Section 12.1 and 1133 Section 12.7). TLS-based mechanisms can leverage a tight integration 1134 between the TLS layer and the application layer to achieve a very 1135 high level of message integrity with respect to the transport layer 1136 to which the token is bound and replay protection in general. 1138 12.1. DPoP Proof Replay 1140 If an adversary is able to get hold of a DPoP proof JWT, the 1141 adversary could replay that token at the same endpoint (the HTTP 1142 endpoint and method are enforced via the respective claims in the 1143 JWTs). To prevent this, servers MUST only accept DPoP proofs for a 1144 limited time window after their iat time, preferably only for a 1145 relatively brief period. 1147 Servers SHOULD store, in the context of the request URI, the jti 1148 value of each DPoP proof for the time window in which the respective 1149 DPoP proof JWT would be accepted and decline HTTP requests to the 1150 same URI for which the jti value has been seen before. In order to 1151 guard against memory exhaustion attacks a server SHOULD reject DPoP 1152 proof JWTs with unnecessarily large jti values or store only a hash 1153 thereof. 1155 Note: To accommodate for clock offsets, the server MAY accept DPoP 1156 proofs that carry an iat time in the reasonably near future. Because 1157 clock skews between servers and clients may be large, servers may 1158 choose to limit DPoP proof lifetimes by using server-provided nonce 1159 values containing the time at the server rather than comparing the 1160 client-supplied iat time to the time at the server, yielding intended 1161 results even in the face of arbitrarily large clock skews. 1163 Server-provided nonces are an effective means of preventing DPoP 1164 proof replay. 1166 12.2. DPoP Proof Pre-Generation 1168 An attacker in control of the client can pre-generate DPoP proofs for 1169 use arbitrarily far into the future by choosing the iat value in the 1170 DPoP proof to be signed by the proof-of-possession key. Note that 1171 one such attacker is the person who is the legitimate user of the 1172 client. The user may pre-generate DPoP proofs to exfiltrate from the 1173 machine possessing the proof-of-possession key upon which they were 1174 generated and copy them to another machine that does not possess the 1175 key. For instance, a bank employee might pre-generate DPoP proofs on 1176 a bank computer and then copy them to another machine for use in the 1177 future, thereby bypassing bank audit controls. When DPoP proofs can 1178 be pre-generated and exfiltrated, all that is actually being proved 1179 in DPoP protocol interactions is possession of a DPoP proof -- not of 1180 the proof-of-possession key. 1182 Use of server-provided nonce values that are not predictable by 1183 attackers can prevent this attack. By providing new nonce values at 1184 times of its choosing, the server can limit the lifetime of DPoP 1185 proofs, preventing pre-generated DPoP proofs from being used. When 1186 server-provided nonces are used, possession of the proof-of- 1187 possession key is being demonstrated -- not just possession of a DPoP 1188 proof. 1190 The ath claim limits the use of pre-generated DPoP proofs to the 1191 lifetime of the access token. Deployments that do not utilize the 1192 nonce mechanism SHOULD NOT issue long-lived DPoP constrained access 1193 tokens, preferring instead to use short-lived access tokens and 1194 refresh tokens. Whilst an attacker could pre-generate DPoP proofs to 1195 use the refresh token to obtain a new access token, they would be 1196 unable to realistically pre-generate DPoP proofs to use a newly 1197 issued access token. 1199 12.3. DPoP Nonce Downgrade 1201 A server MUST NOT accept any DPoP proofs without the nonce claim when 1202 a DPoP nonce has been provided to the client. 1204 12.4. Untrusted Code in the Client Context 1206 If an adversary is able to run code in the client's execution 1207 context, the security of DPoP is no longer guaranteed. Common issues 1208 in web applications leading to the execution of untrusted code are 1209 cross-site scripting and remote code inclusion attacks. 1211 If the private key used for DPoP is stored in such a way that it 1212 cannot be exported, e.g., in a hardware or software security module, 1213 the adversary cannot exfiltrate the key and use it to create 1214 arbitrary DPoP proofs. The adversary can, however, create new DPoP 1215 proofs as long as the client is online, and use these proofs 1216 (together with the respective tokens) either on the victim's device 1217 or on a device under the attacker's control to send arbitrary 1218 requests that will be accepted by servers. 1220 To send requests even when the client is offline, an adversary can 1221 try to pre-compute DPoP proofs using timestamps in the future and 1222 exfiltrate these together with the access or refresh token. 1224 An adversary might further try to associate tokens issued from the 1225 token endpoint with a key pair under the adversary's control. One 1226 way to achieve this is to modify existing code, e.g., by replacing 1227 cryptographic APIs. Another way is to launch a new authorization 1228 grant between the client and the authorization server in an iframe. 1229 This grant needs to be "silent", i.e., not require interaction with 1230 the user. With code running in the client's origin, the adversary 1231 has access to the resulting authorization code and can use it to 1232 associate their own DPoP keys with the tokens returned from the token 1233 endpoint. The adversary is then able to use the resulting tokens on 1234 their own device even if the client is offline. 1236 Therefore, protecting clients against the execution of untrusted code 1237 is extremely important even if DPoP is used. Besides secure coding 1238 practices, Content Security Policy [W3C.CSP] can be used as a second 1239 layer of defense against cross-site scripting. 1241 12.5. Signed JWT Swapping 1243 Servers accepting signed DPoP proof JWTs MUST check the typ field in 1244 the headers of the JWTs to ensure that adversaries cannot use JWTs 1245 created for other purposes. 1247 12.6. Signature Algorithms 1249 Implementers MUST ensure that only asymmetric digital signature 1250 algorithms that are deemed secure can be used for signing DPoP 1251 proofs. In particular, the algorithm none MUST NOT be allowed. 1253 12.7. Message Integrity 1255 DPoP does not ensure the integrity of the payload or headers of 1256 requests. The DPoP proof only contains claims for the HTTP URI and 1257 method, but not, for example, the message body or general request 1258 headers. 1260 This is an intentional design decision intended to keep DPoP simple 1261 to use, but as described, makes DPoP potentially susceptible to 1262 replay attacks where an attacker is able to modify message contents 1263 and headers. In many setups, the message integrity and 1264 confidentiality provided by TLS is sufficient to provide a good level 1265 of protection. 1267 Implementers that have stronger requirements on the integrity of 1268 messages are encouraged to either use TLS-based mechanisms or signed 1269 requests. TLS-based mechanisms are in particular OAuth Mutual TLS 1270 [RFC8705] and OAuth Token Binding [I-D.ietf-oauth-token-binding]. 1272 Note: While signatures covering other parts of requests are out of 1273 the scope of this specification, additional information to be signed 1274 can be added into DPoP proofs. 1276 12.8. Access Token and Public Key Binding 1278 The binding of the access token to the DPoP public key, which is 1279 specified in Section 6, uses a cryptographic hash of the JWK 1280 representation of the public key. It relies on the hash function 1281 having sufficient second-preimage resistance so as to make it 1282 computationally infeasible to find or create another key that 1283 produces to the same hash output value. The SHA-256 hash function 1284 was used because it meets the aforementioned requirement while being 1285 widely available. If, in the future, JWK Thumbprints need to be 1286 computed using hash function(s) other than SHA-256, it is suggested 1287 that an additional related JWT confirmation method member be defined 1288 for that purpose, registered in the respective IANA registry, and 1289 used in place of the jkt confirmation method defined herein. 1291 Similarly, the binding of the DPoP proof to the access token uses a 1292 hash of that access token as the value of the ath claim in the DPoP 1293 proof (see Section 4.2). This relies on the value of the hash being 1294 sufficiently unique so as to reliably identify the access token. The 1295 collision resistance of SHA-256 meets that requirement. If, in the 1296 future, access token digests need be computed using hash function(s) 1297 other than SHA-256, it is suggested that an additional related JWT 1298 claim be defined for that purpose, registered in the respective IANA 1299 registry, and used in place of the ath claim defined herein. 1301 12.9. Authorization Code and Public Key Binding 1303 Cryptographic binding of the authorization code to the DPoP public 1304 key, is specified in Section 10. This binding prevents attacks in 1305 which the attacker captures the authorization code and creates a DPoP 1306 proof using a proof-of-possession key other than that held by the 1307 client and redeems the authorization code using that DPoP proof. By 1308 ensuring end-to-end that only the client's DPoP key can be used, this 1309 prevents captured authorization codes from being exfiltrated and used 1310 at locations other than the one to which the authorization code was 1311 issued. 1313 Authorization codes can, for instance, be harvested by attackers from 1314 places that the HTTP messages containing them are logged. Even when 1315 efforts are made to make authorization codes one-time-use, in 1316 practice, there is often a time window during which attackers can 1317 replay them. For instance, when authorization servers are 1318 implemented as scalable replicated services, some replicas may 1319 temporarily not yet have the information needed to prevent replay. 1320 DPoP binding of the authorization code solves these problems. 1322 If an authorization server does not (or cannot) strictly enforce the 1323 single-use limitation for authorization codes and an attacker can 1324 access the authorization code (and if PKCE is used, the 1325 code_verifier), the attacker can create a forged token request, 1326 binding the resulting token to an attacker-controlled key. For 1327 example, using cross-site scripting, attackers might obtain access to 1328 the authorization code and PKCE parameters. Use of the dpop_jkt 1329 parameter prevents this attack. 1331 The binding of the authorization code to the DPoP public key uses a 1332 JWK Thumbprint of the public key, just as the access token binding 1333 does. The same JWK Thumbprint considerations apply. 1335 13. IANA Considerations 1337 13.1. OAuth Access Token Type Registration 1339 This specification requests registration of the following access 1340 token type in the "OAuth Access Token Types" registry 1341 [IANA.OAuth.Params] established by [RFC6749]. 1343 * Type name: DPoP 1345 * Additional Token Endpoint Response Parameters: (none) 1347 * HTTP Authentication Scheme(s): DPoP 1348 * Change controller: IESG 1350 * Specification document(s): [[ this specification ]] 1352 13.2. OAuth Extensions Error Registration 1354 This specification requests registration of the following error 1355 values in the "OAuth Extensions Error" registry [IANA.OAuth.Params] 1356 established by [RFC6749]. 1358 Invalid DPoP proof: 1360 * Name: invalid_dpop_proof 1362 * Usage Location: token error response, resource error response 1364 * Protocol Extension: Demonstrating Proof of Possession (DPoP) 1366 * Change controller: IETF 1368 * Specification document(s): [[ this specification ]] 1370 Use DPoP nonce: 1372 * Name: use_dpop_nonce 1374 * Usage Location: token error response, resource error response 1376 * Protocol Extension: Demonstrating Proof of Possession (DPoP) 1378 * Change controller: IETF 1380 * Specification document(s): [[ this specification ]] 1382 13.3. OAuth Parameters Registration 1384 This specification requests registration of the following 1385 authorization request parameter in the "OAuth Parameters" registry 1386 [IANA.OAuth.Params] established by [RFC6749]. 1388 * Name: dpop_jkt 1390 * Parameter Usage Locaion: authorization request 1392 * Change Controller: IESG 1394 * Reference: [[ {#dpop_jkt} of this specification ]] 1396 13.4. HTTP Authentication Scheme Registration 1398 This specification requests registration of the following scheme in 1399 the "Hypertext Transfer Protocol (HTTP) Authentication Scheme 1400 Registry" [RFC7235][IANA.HTTP.AuthSchemes]: 1402 * Authentication Scheme Name: DPoP 1404 * Reference: [[ Section 7.1 of this specification ]] 1406 13.5. Media Type Registration 1408 [[ Is a media type registration at [IANA.MediaTypes] necessary for 1409 application/dpop+jwt? There is a +jwt structured syntax suffix 1410 registered already at [IANA.MediaType.StructuredSuffix] by 1411 Section 7.2 of [RFC8417], which is maybe sufficient? A full-blown 1412 registration of application/dpop+jwt seems like it'd be overkill. 1413 The dpop+jwt is used in the JWS/JWT typ header for explicit typing of 1414 the JWT per Section 3.11 of [RFC8725] but it is not used anywhere 1415 else (such as the Content-Type of HTTP messages). 1417 Note that there does seem to be some precedence for [IANA.MediaTypes] 1418 registration with application/at+jwt in [RFC9068], application/oauth- 1419 authz-req+jwt in [RFC9101], application/secevent+jwt in [RFC8417], 1420 and regular old application/jwt in [RFC7519]. But precedence isn't 1421 always right. ]] 1423 13.6. JWT Confirmation Methods Registration 1425 This specification requests registration of the following value in 1426 the IANA "JWT Confirmation Methods" registry [IANA.JWT] for JWT cnf 1427 member values established by [RFC7800]. 1429 * Confirmation Method Value: jkt 1431 * Confirmation Method Description: JWK SHA-256 Thumbprint 1433 * Change Controller: IESG 1435 * Specification Document(s): [[ Section 6 of this specification ]] 1437 13.7. JSON Web Token Claims Registration 1439 This specification requests registration of the following Claims in 1440 the IANA "JSON Web Token Claims" registry [IANA.JWT] established by 1441 [RFC7519]. 1443 HTTP method: 1445 * Claim Name: htm 1447 * Claim Description: The HTTP method of the request 1449 * Change Controller: IESG 1451 * Specification Document(s): [[ Section 4.2 of this specification ]] 1453 HTTP URI: 1455 * Claim Name: htu 1457 * Claim Description: The HTTP URI of the request (without query and 1458 fragment parts) 1460 * Change Controller: IESG 1462 * Specification Document(s): [[ Section 4.2 of this specification ]] 1464 Access token hash: 1466 * Claim Name: ath 1468 * Claim Description: The base64url encoded SHA-256 hash of the ASCII 1469 encoding of the associated access token's value 1471 * Change Controller: IESG 1473 * Specification Document(s): [[ Section 4.2 of this specification ]] 1475 13.8. HTTP Message Header Field Names Registration 1477 This document specifies the following HTTP header fields, 1478 registration of which is requested in the "Permanent Message Header 1479 Field Names" registry [IANA.Headers] defined in [RFC3864]. 1481 * Header Field Name: DPoP 1483 * Applicable protocol: HTTP 1485 * Status: standard 1487 * Author/change Controller: IETF 1489 * Specification Document(s): [[ this specification ]] 1491 13.9. OAuth Authorization Server Metadata Registration 1493 This specification requests registration of the following value in 1494 the IANA "OAuth Authorization Server Metadata" registry 1495 [IANA.OAuth.Parameters] established by [RFC8414]. 1497 * Metadata Name: dpop_signing_alg_values_supported 1499 * Metadata Description: JSON array containing a list of the JWS 1500 algorithms supported for DPoP proof JWTs 1502 * Change Controller: IESG 1504 * Specification Document(s): [[ Section 5.1 of this specification ]] 1506 13.10. OAuth Dynamic Client Registration Metadata 1508 This specification requests registration of the following value in 1509 the IANA "OAuth Dynamic Client Registration Metadata" registry 1510 [IANA.OAuth.Parameters] established by [RFC7591]. 1512 * Metadata Name: always_uses_dpop 1514 * Metadata Description: Boolean value specifying whether the client 1515 always uses DPoP for token requests 1517 * Change Controller: IESG 1519 * Specification Document(s): [[ Section 5.2 of this specification ]] 1521 14. Normative References 1523 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1524 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 1525 DOI 10.17487/RFC7231, June 2014, 1526 . 1528 [RFC7638] Jones, M. and N. Sakimura, "JSON Web Key (JWK) 1529 Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September 1530 2015, . 1532 [RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, 1533 DOI 10.17487/RFC7518, May 2015, 1534 . 1536 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 1537 Specifications: ABNF", STD 68, RFC 5234, 1538 DOI 10.17487/RFC5234, January 2008, 1539 . 1541 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 1542 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 1543 2015, . 1545 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 1546 RFC 6749, DOI 10.17487/RFC6749, October 2012, 1547 . 1549 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 1550 Resource Identifier (URI): Generic Syntax", STD 66, 1551 RFC 3986, DOI 10.17487/RFC3986, January 2005, 1552 . 1554 [RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- 1555 Possession Key Semantics for JSON Web Tokens (JWTs)", 1556 RFC 7800, DOI 10.17487/RFC7800, April 2016, 1557 . 1559 15. Informative References 1561 [I-D.ietf-oauth-security-topics] 1562 Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, 1563 "OAuth 2.0 Security Best Current Practice", Work in 1564 Progress, Internet-Draft, draft-ietf-oauth-security- 1565 topics-19, 16 December 2021, 1566 . 1569 [RFC8414] Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 1570 Authorization Server Metadata", RFC 8414, 1571 DOI 10.17487/RFC8414, June 2018, 1572 . 1574 [IANA.OAuth.Params] 1575 IANA, "OAuth Parameters", 1576 . 1578 [IANA.HTTP.AuthSchemes] 1579 IANA, "Hypertext Transfer Protocol (HTTP) Authentication 1580 Scheme Registry", 1581 . 1583 [IANA.Headers] 1584 IANA, "Message Headers", 1585 . 1587 [RFC7591] Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and 1588 P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", 1589 RFC 7591, DOI 10.17487/RFC7591, July 2015, 1590 . 1592 [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token 1593 (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, 1594 . 1596 [RFC7523] Jones, M., Campbell, B., and C. Mortimore, "JSON Web Token 1597 (JWT) Profile for OAuth 2.0 Client Authentication and 1598 Authorization Grants", RFC 7523, DOI 10.17487/RFC7523, May 1599 2015, . 1601 [IANA.MediaType.StructuredSuffix] 1602 IANA, "Structured Syntax Suffix Registry", 1603 . 1606 [RFC8725] Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best 1607 Current Practices", BCP 225, RFC 8725, 1608 DOI 10.17487/RFC8725, February 2020, 1609 . 1611 [OpenID.Core] 1612 Sakimura, N., Bradley, J., Jones, M.B., Medeiros, B.d., 1613 and C. Mortimore, "OpenID Connect Core 1.0", November 1614 2014, 1615 . 1617 [RFC9126] Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., 1618 and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", 1619 RFC 9126, DOI 10.17487/RFC9126, September 2021, 1620 . 1622 [RFC8417] Hunt, P., Ed., Jones, M., Denniss, W., and M. Ansari, 1623 "Security Event Token (SET)", RFC 8417, 1624 DOI 10.17487/RFC8417, July 2018, 1625 . 1627 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1628 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1629 May 2017, . 1631 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 1632 Unique IDentifier (UUID) URN Namespace", RFC 4122, 1633 DOI 10.17487/RFC4122, July 2005, 1634 . 1636 [RFC7662] Richer, J., Ed., "OAuth 2.0 Token Introspection", 1637 RFC 7662, DOI 10.17487/RFC7662, October 2015, 1638 . 1640 [RFC9101] Sakimura, N., Bradley, J., and M. Jones, "The OAuth 2.0 1641 Authorization Framework: JWT-Secured Authorization Request 1642 (JAR)", RFC 9101, DOI 10.17487/RFC9101, August 2021, 1643 . 1645 [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration 1646 Procedures for Message Header Fields", BCP 90, RFC 3864, 1647 DOI 10.17487/RFC3864, September 2004, 1648 . 1650 [IANA.MediaTypes] 1651 IANA, "Media Types", 1652 . 1654 [I-D.ietf-oauth-token-binding] 1655 Jones, M. B., Campbell, B., Bradley, J., and W. Denniss, 1656 "OAuth 2.0 Token Binding", Work in Progress, Internet- 1657 Draft, draft-ietf-oauth-token-binding-08, 19 October 2018, 1658 . 1661 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1662 Protocol (HTTP/1.1): Message Syntax and Routing", 1663 RFC 7230, DOI 10.17487/RFC7230, June 2014, 1664 . 1666 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 1667 Framework: Bearer Token Usage", RFC 6750, 1668 DOI 10.17487/RFC6750, October 2012, 1669 . 1671 [RFC7235] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1672 Protocol (HTTP/1.1): Authentication", RFC 7235, 1673 DOI 10.17487/RFC7235, June 2014, 1674 . 1676 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1677 Requirement Levels", BCP 14, RFC 2119, 1678 DOI 10.17487/RFC2119, March 1997, 1679 . 1681 [RFC8707] Campbell, B., Bradley, J., and H. Tschofenig, "Resource 1682 Indicators for OAuth 2.0", RFC 8707, DOI 10.17487/RFC8707, 1683 February 2020, . 1685 [W3C.WebCryptoAPI] 1686 Watson, M., "Web Cryptography API", 26 January 2017, 1687 . 1689 [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key 1690 for Code Exchange by OAuth Public Clients", RFC 7636, 1691 DOI 10.17487/RFC7636, September 2015, 1692 . 1694 [RFC9068] Bertocci, V., "JSON Web Token (JWT) Profile for OAuth 2.0 1695 Access Tokens", RFC 9068, DOI 10.17487/RFC9068, October 1696 2021, . 1698 [IANA.JWT] IANA, "JSON Web Token Claims", 1699 . 1701 [RFC8705] Campbell, B., Bradley, J., Sakimura, N., and T. 1702 Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication 1703 and Certificate-Bound Access Tokens", RFC 8705, 1704 DOI 10.17487/RFC8705, February 2020, 1705 . 1707 [W3C.CSP] West, M., "Content Security Policy Level 3", 15 October 1708 2018, . 1710 Appendix A. Acknowledgements 1712 We would like to thank Annabelle Backman, Dominick Baier, Andrii 1713 Deinega, William Denniss, Vladimir Dzhuvinov, Mike Engan, Nikos 1714 Fotiou, Mark Haine, Dick Hardt, Joseph Heenan, Bjorn Hjelm, Jared 1715 Jennings, Benjamin Kaduk, Pieter Kasselman, Steinar Noem, Neil 1716 Madden, Rob Otto, Aaron Parecki, Michael Peck, Paul Querna, Justin 1717 Richer, Filip Skokan, Dmitry Telegin, Dave Tonge, Jim Willeke, 1718 Philippe De Ryck, and others (please let us know, if you've been 1719 mistakenly omitted) for their valuable input, feedback and general 1720 support of this work. 1722 This document originated from discussions at the 4th OAuth Security 1723 Workshop in Stuttgart, Germany. We thank the organizers of this 1724 workshop (Ralf Kusters, Guido Schmitz). 1726 Appendix B. Document History 1728 [[ To be removed from the final specification ]] 1730 -05 1732 * Added Authorization Code binding via the dpop_jkt parameter. 1734 * Described the authorization code reuse attack and how dpop_jkt 1735 mitigates it. 1737 * Enhanced description of DPoP proof expiration checking. 1739 * Described nonce storage requirements and how nonce mismatches and 1740 missing nonces are self-correcting. 1742 * Specified the use of the use_dpop_nonce error for missing and 1743 mismatched nonce values. 1745 * Specified that authorization servers use 400 (Bad Request) errors 1746 to supply nonces and resource servers use 401 (Unauthorized) 1747 errors to do so. 1749 * Added a bit more about ath and pre-generated proofs to the 1750 security considerations. 1752 * Mentioned confirming the DPoP binding of the access token in the 1753 list in Section 4.3. 1755 * Added the always_uses_dpop client registration metadata parameter. 1757 * Updated references for drafts that are now RFCs. 1759 -04 1761 * Added the option for a server-provided nonce in the DPoP proof. 1763 * Registered the invalid_dpop_proof and use_dpop_nonce error codes. 1765 * Removed fictitious uses of realm from the examples, as they added 1766 no value. 1768 * State that if the introspection response has a token_type, it has 1769 to be DPoP. 1771 * Mention that RFC7235 allows multiple authentication schemes in 1772 WWW-Authenticate with a 401. 1774 * Editorial fixes. 1776 -03 1778 * Add an access token hash (ath) claim to the DPoP proof when used 1779 in conjunction with the presentation of an access token for 1780 protected resource access 1782 * add Untrusted Code in the Client Context section to security 1783 considerations 1785 * Editorial updates and fixes 1787 -02 1789 * Lots of editorial updates and additions including expanding on the 1790 objectives, better defining the key confirmation representations, 1791 example updates and additions, better describing mixed bearer/dpop 1792 token type deployments, clarify RT binding only being done for 1793 public clients and why, more clearly allow for a bound RT but with 1794 bearer AT, explain/justify the choice of SHA-256 for key binding, 1795 and more 1797 * Require that a protected resource supporting bearer and DPoP at 1798 the same time must reject an access token received as bearer, if 1799 that token is DPoP-bound 1801 * Remove the case-insensitive qualification on the htm claim check 1803 * Relax the jti tracking requirements a bit and qualify it by URI 1805 -01 1807 * Editorial updates 1809 * Attempt to more formally define the DPoP Authorization header 1810 scheme 1812 * Define the 401/WWW-Authenticate challenge 1814 * Added invalid_dpop_proof error code for DPoP errors in token 1815 request 1817 * Fixed up and added to the IANA section 1818 * Added dpop_signing_alg_values_supported authorization server 1819 metadata 1821 * Moved the Acknowledgements into an Appendix and added a bunch of 1822 names (best effort) 1824 -00 [[ Working Group Draft ]] 1826 * Working group draft 1828 -04 1830 * Update OAuth MTLS reference to RFC 8705 1832 * Use the newish RFC v3 XML and HTML format 1834 -03 1836 * rework the text around uniqueness requirements on the jti claim in 1837 the DPoP proof JWT 1839 * make tokens a bit smaller by using htm, htu, and jkt rather than 1840 http_method, http_uri, and jkt#S256 respectively 1842 * more explicit recommendation to use mTLS if that is available 1844 * added David Waite as co-author 1846 * editorial updates 1848 -02 1850 * added normalization rules for URIs 1852 * removed distinction between proof and binding 1854 * "jwk" header again used instead of "cnf" claim in DPoP proof 1856 * renamed "Bearer-DPoP" token type to "DPoP" 1858 * removed ability for key rotation 1860 * added security considerations on request integrity 1862 * explicit advice on extending DPoP proofs to sign other parts of 1863 the HTTP messages 1865 * only use the jkt#S256 in ATs 1866 * iat instead of exp in DPoP proof JWTs 1868 * updated guidance on token_type evaluation 1870 -01 1872 * fixed inconsistencies 1874 * moved binding and proof messages to headers instead of parameters 1876 * extracted and unified definition of DPoP JWTs 1878 * improved description 1880 -00 1882 * first draft 1884 Authors' Addresses 1886 Daniel Fett 1887 yes.com 1888 Email: mail@danielfett.de 1890 Brian Campbell 1891 Ping Identity 1892 Email: bcampbell@pingidentity.com 1894 John Bradley 1895 Yubico 1896 Email: ve7jtb@ve7jtb.com 1898 Torsten Lodderstedt 1899 yes.com 1900 Email: torsten@lodderstedt.net 1902 Michael Jones 1903 Microsoft 1904 Email: mbj@microsoft.com 1905 URI: https://self-issued.info/ 1907 David Waite 1908 Ping Identity 1909 Email: david@alkaline-solutions.com