idnits 2.17.1 draft-ietf-gnap-core-protocol-02.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 : ---------------------------------------------------------------------------- ** There are 81 instances of too long lines in the document, the longest one being 27 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (17 November 2020) is 1256 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Unused Reference: 'RFC8693' is defined on line 4207, but no explicit reference was found in the text -- Possible downref: Non-RFC (?) normative reference: ref. 'BCP195' == Outdated reference: A later version (-19) exists of draft-ietf-httpbis-message-signatures-00 == Outdated reference: A later version (-16) exists of draft-ietf-oauth-dpop-01 == Outdated reference: A later version (-18) exists of draft-ietf-secevent-subject-identifiers-06 -- Possible downref: Non-RFC (?) normative reference: ref. 'OIDC' -- Possible downref: Non-RFC (?) normative reference: ref. 'OIDC4IA' ** Obsolete normative reference: RFC 3230 (Obsoleted by RFC 9530) Summary: 2 errors (**), 0 flaws (~~), 5 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 GNAP J. Richer, Ed. 3 Internet-Draft Bespoke Engineering 4 Intended status: Standards Track A. Parecki 5 Expires: 21 May 2021 Okta 6 F. Imbault 7 acert.io 8 17 November 2020 10 Grant Negotiation and Authorization Protocol 11 draft-ietf-gnap-core-protocol-02 13 Abstract 15 This document defines a mechanism for delegating authorization to a 16 piece of software, and conveying that delegation to the software. 17 This delegation can include access to a set of APIs as well as 18 information passed directly to the software. 20 This document has been prepared by the GNAP working group design team 21 of Kathleen Moriarty, Fabien Imbault, Dick Hardt, Mike Jones, and 22 Justin Richer. This document is intended as a starting point for the 23 working group and includes decision points for discussion and 24 agreement. Many of the features in this proposed protocol can be 25 accomplished in a number of ways. Where possible, the editor has 26 included notes and discussion from the design team regarding the 27 options as understood. 29 Status of This Memo 31 This Internet-Draft is submitted in full conformance with the 32 provisions of BCP 78 and BCP 79. 34 Internet-Drafts are working documents of the Internet Engineering 35 Task Force (IETF). Note that other groups may also distribute 36 working documents as Internet-Drafts. The list of current Internet- 37 Drafts is at https://datatracker.ietf.org/drafts/current/. 39 Internet-Drafts are draft documents valid for a maximum of six months 40 and may be updated, replaced, or obsoleted by other documents at any 41 time. It is inappropriate to use Internet-Drafts as reference 42 material or to cite them other than as "work in progress." 44 This Internet-Draft will expire on 21 May 2021. 46 Copyright Notice 48 Copyright (c) 2020 IETF Trust and the persons identified as the 49 document authors. All rights reserved. 51 This document is subject to BCP 78 and the IETF Trust's Legal 52 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 53 license-info) in effect on the date of publication of this document. 54 Please review these documents carefully, as they describe your rights 55 and restrictions with respect to this document. Code Components 56 extracted from this document must include Simplified BSD License text 57 as described in Section 4.e of the Trust Legal Provisions and are 58 provided without warranty as described in the Simplified BSD License. 60 Table of Contents 62 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 63 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 64 1.2. Roles . . . . . . . . . . . . . . . . . . . . . . . . . . 5 65 1.3. Elements . . . . . . . . . . . . . . . . . . . . . . . . 6 66 1.4. Sequences . . . . . . . . . . . . . . . . . . . . . . . . 7 67 1.4.1. Redirect-based Interaction . . . . . . . . . . . . . 10 68 1.4.2. User-code Interaction . . . . . . . . . . . . . . . . 12 69 1.4.3. Asynchronous Authorization . . . . . . . . . . . . . 14 70 1.4.4. Software-only Authorization . . . . . . . . . . . . . 15 71 1.4.5. Refreshing an Expired Access Token . . . . . . . . . 16 72 2. Requesting Access . . . . . . . . . . . . . . . . . . . . . . 17 73 2.1. Requesting Resources . . . . . . . . . . . . . . . . . . 19 74 2.1.1. Requesting a Single Access Token . . . . . . . . . . 19 75 2.1.2. Requesting Resources By Reference . . . . . . . . . . 21 76 2.1.3. Requesting Multiple Access Tokens . . . . . . . . . . 23 77 2.1.4. Signaling Token Behavior . . . . . . . . . . . . . . 25 78 2.2. Requesting User Information . . . . . . . . . . . . . . . 26 79 2.3. Identifying the RC . . . . . . . . . . . . . . . . . . . 27 80 2.3.1. Identifying the RC Instance . . . . . . . . . . . . . 29 81 2.3.2. Identifying the RC Key . . . . . . . . . . . . . . . 30 82 2.3.3. Providing Displayable RC Information . . . . . . . . 31 83 2.3.4. Authenticating the RC . . . . . . . . . . . . . . . . 31 84 2.4. Identifying the User . . . . . . . . . . . . . . . . . . 32 85 2.4.1. Identifying the User by Reference . . . . . . . . . . 33 86 2.5. Interacting with the User . . . . . . . . . . . . . . . . 33 87 2.5.1. Redirect to an Arbitrary URL . . . . . . . . . . . . 35 88 2.5.2. Open an Application-specific URL . . . . . . . . . . 36 89 2.5.3. Receive a Callback After Interaction . . . . . . . . 36 90 2.5.4. Display a Short User Code . . . . . . . . . . . . . . 38 91 2.5.5. Indicate Desired Interaction Locales . . . . . . . . 38 92 2.5.6. Extending Interaction Modes . . . . . . . . . . . . . 39 93 2.6. Declaring RC Capabilities . . . . . . . . . . . . . . . . 39 94 2.7. Referencing an Existing Grant Request . . . . . . . . . . 39 95 2.8. Requesting OpenID Connect Claims . . . . . . . . . . . . 39 96 2.9. Extending The Grant Request . . . . . . . . . . . . . . . 40 97 3. Grant Response . . . . . . . . . . . . . . . . . . . . . . . 40 98 3.1. Request Continuation . . . . . . . . . . . . . . . . . . 42 99 3.2. Access Tokens . . . . . . . . . . . . . . . . . . . . . . 43 100 3.2.1. Single Access Token . . . . . . . . . . . . . . . . . 43 101 3.2.2. Multiple Access Tokens . . . . . . . . . . . . . . . 46 102 3.3. Interaction Modes . . . . . . . . . . . . . . . . . . . . 47 103 3.3.1. Redirection to an arbitrary URL . . . . . . . . . . . 47 104 3.3.2. Launch of an application URL . . . . . . . . . . . . 48 105 3.3.3. Post-interaction Callback to an RC URL . . . . . . . 48 106 3.3.4. Display of a Short User Code . . . . . . . . . . . . 49 107 3.3.5. Extending Interaction Mode Responses . . . . . . . . 50 108 3.4. Returning User Information . . . . . . . . . . . . . . . 50 109 3.5. Returning Dynamically-bound Reference Handles . . . . . . 51 110 3.6. Error Response . . . . . . . . . . . . . . . . . . . . . 53 111 3.7. Extending the Response . . . . . . . . . . . . . . . . . 53 112 4. Interaction at the AS . . . . . . . . . . . . . . . . . . . . 53 113 4.1. Interaction at a Redirected URI . . . . . . . . . . . . . 54 114 4.2. Interaction at the User Code URI . . . . . . . . . . . . 54 115 4.3. Interaction through an Application URI . . . . . . . . . 55 116 4.4. Post-Interaction Completion . . . . . . . . . . . . . . . 55 117 4.4.1. Completing Interaction with a Browser Redirect to the 118 Callback URI . . . . . . . . . . . . . . . . . . . . 56 119 4.4.2. Completing Interaction with a Direct HTTP Request 120 Callback . . . . . . . . . . . . . . . . . . . . . . 56 121 4.4.3. Calculating the interaction hash . . . . . . . . . . 57 122 5. Continuing a Grant Request . . . . . . . . . . . . . . . . . 58 123 5.1. Continuing After a Completed Interaction . . . . . . . . 60 124 5.2. Continuing During Pending Interaction . . . . . . . . . . 61 125 5.3. Modifying an Existing Request . . . . . . . . . . . . . . 62 126 5.4. Getting the Current State of a Grant Request . . . . . . 67 127 5.5. Canceling a Grant Request . . . . . . . . . . . . . . . . 68 128 6. Token Management . . . . . . . . . . . . . . . . . . . . . . 68 129 6.1. Rotating the Access Token . . . . . . . . . . . . . . . . 69 130 6.2. Revoking the Access Token . . . . . . . . . . . . . . . . 70 131 7. Using Access Tokens . . . . . . . . . . . . . . . . . . . . . 71 132 8. Binding Keys . . . . . . . . . . . . . . . . . . . . . . . . 72 133 8.1. Detached JWS . . . . . . . . . . . . . . . . . . . . . . 73 134 8.2. Attached JWS . . . . . . . . . . . . . . . . . . . . . . 75 135 8.3. Mutual TLS . . . . . . . . . . . . . . . . . . . . . . . 79 136 8.4. Demonstration of Proof-of-Possession (DPoP) . . . . . . . 81 137 8.5. HTTP Signing . . . . . . . . . . . . . . . . . . . . . . 82 138 8.6. OAuth Proof of Possession (PoP) . . . . . . . . . . . . . 83 139 9. Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . 85 140 10. Resource Servers . . . . . . . . . . . . . . . . . . . . . . 86 141 10.1. Introspecting a Token . . . . . . . . . . . . . . . . . 86 142 10.2. Deriving a downstream token . . . . . . . . . . . . . . 88 143 10.3. Registering a Resource Handle . . . . . . . . . . . . . 89 144 10.4. Requesting Resources With Insufficient Access . . . . . 91 145 11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 91 146 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 91 147 13. Security Considerations . . . . . . . . . . . . . . . . . . . 92 148 14. Privacy Considerations . . . . . . . . . . . . . . . . . . . 92 149 15. Normative References . . . . . . . . . . . . . . . . . . . . 92 150 Appendix A. Document History . . . . . . . . . . . . . . . . . . 94 151 Appendix B. Component Data Models . . . . . . . . . . . . . . . 94 152 Appendix C. Example Protocol Flows . . . . . . . . . . . . . . . 95 153 C.1. Redirect-Based User Interaction . . . . . . . . . . . . . 95 154 C.2. Secondary Device Interaction . . . . . . . . . . . . . . 99 155 Appendix D. No User Involvement . . . . . . . . . . . . . . . . 102 156 D.1. Asynchronous Authorization . . . . . . . . . . . . . . . 103 157 D.2. Applying OAuth 2 Scopes and Client IDs . . . . . . . . . 106 158 Appendix E. JSON Structures and Polymorphism . . . . . . . . . . 107 159 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 108 161 1. Introduction 163 This protocol allows a piece of software, the resource client, to 164 request delegated authorization to resource servers and to request 165 direct information. This delegation is facilitated by an 166 authorization server usually on behalf of a resource owner. The 167 requesting party operating the software may interact with the 168 authorization server to authenticate, provide consent, and authorize 169 the request. 171 The process by which the delegation happens is known as a grant, and 172 GNAP allows for the negotiation of the grant process over time by 173 multiple parties acting in distinct roles. 175 This protocol solves many of the same use cases as OAuth 2.0 176 [RFC6749], OpenID Connect [OIDC], and the family of protocols that 177 have grown up around that ecosystem. However, GNAP is not an 178 extension of OAuth 2.0 and is not intended to be directly compatible 179 with OAuth 2.0. GNAP seeks to provide functionality and solve use 180 cases that OAuth 2.0 cannot easily or cleanly address. Even so, GNAP 181 and OAuth 2.0 will exist in parallel for many deployments, and 182 considerations have been taken to facilitate the mapping and 183 transition from legacy systems to GNAP. Some examples of these can 184 be found in Appendix D.2. 186 1.1. Terminology 188 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 189 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 190 "OPTIONAL" in this document are to be interpreted as described in 191 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 192 capitals, as shown here. 194 1.2. Roles 196 The parties in GNAP perform actions under different roles. Roles are 197 defined by the actions taken and the expectations leveraged on the 198 role by the overall protocol. 200 Authorization Server (AS) Manages the requested delegations for the 201 RO. The AS issues tokens and directly delegated information to 202 the RC. The AS is defined by its grant endpoint, a single URL 203 that accepts a POST request with a JSON payload. The AS could 204 also have other endpoints, including interaction endpoints and 205 user code endpoints, and these are introduced to the RC as needed 206 during the delegation process. 208 Resource Client (RC, aka "client") Requests tokens from the AS and 209 uses tokens at the RS. An instance of the RC software is 210 identified by its key, which can be known to the AS prior to the 211 first request. The AS determines which policies apply to a given 212 RC, including what it can request and on whose behalf. 214 Resource Server (RS, aka "API") Accepts tokens from the RC issued by 215 the AS and serves delegated resources on behalf of the RO. There 216 could be multiple RSs protected by the AS that the RC will call. 218 Resource Owner (RO) Authorizes the request from the RC to the RS, 219 often interactively at the AS. 221 Requesting Party (RQ, aka "user") Operates and interacts with the 222 RC. 224 The design of GNAP does not assume any one deployment architecture, 225 but instead attempts to define roles that can be fulfilled in a 226 number of different ways for different use cases. As long as a given 227 role fulfills all of its obligations and behaviors as defined by the 228 protocol, GNAP does not make additional requirements on its structure 229 or setup. 231 Multiple roles can be fulfilled by the same party, and a given party 232 can switch roles in different instances of the protocol. For 233 example, the RO and RQ in many instances are the same person, where a 234 user is authorizing the RC to act on their own behalf at the RS. In 235 this case, one party fulfills both of the RO and RQ roles, but the 236 roles themselves are still defined separately from each other to 237 allow for other use cases where they are fulfilled by different 238 parties. 240 For another example, in some complex scenarios, an RS receiving 241 requests from one RC can act as an RC for a downstream secondary RS 242 in order to fulfill the original request. In this case, one piece of 243 software is both an RS and an RC from different perspectives, and it 244 fulfills these roles separately as far as the overall protocol is 245 concerned. 247 A single role need not be deployed as a monolithic service. For 248 example, An RC could have components that are installed on the RQ's 249 device as well as a back-end system that it communicates with. If 250 both of these components participate in the delegation protocol, they 251 are both considered part of the RC. 253 For another example, an AS could likewise be built out of many 254 constituent components in a distributed architecture. The component 255 that the RC calls directly could be different from the component that 256 the the RO interacts with to drive consent, since API calls and user 257 interaction have different security considerations in many 258 environments. Furthermore, the AS could need to collect identity 259 claims about the RO from one system that deals with user attributes 260 while generating access tokens at another system that deals with 261 security rights. From the perspective of GNAP, all of these are 262 pieces of the AS and together fulfill the role of the AS as defined 263 by the protocol. 265 [[ See issue #29 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 266 issues/29) ]] 268 [[ See issue #32 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 269 issues/32) ]] 271 1.3. Elements 273 In addition to the roles above, the protocol also involves several 274 elements that are acted upon by the roles throughout the process. 276 Access Token A credential representing a set of access rights 277 delegated to the RC. The access token is created by the AS, 278 consumed and verified by the RS, and issued to and carried by the 279 RC. The contents and format of the access token are opaque to the 280 RC. 282 Grant The process by which the RC requests and is given delegated 283 access to the RS by the AS through the authority of the RO. 285 Cryptographic Key A cryptographic element binding a request to a 286 holder of the key. Access tokens and RC instances can be 287 associated with specific keys. 289 Resource A protected API served by the RS and accessed by the RC. 290 Access to this resource is delegated by the RO as part of the 291 grant process. 293 Subject Information Information about the RO that is returned 294 directly to the RC from the AS without the RC making a separate 295 call to an RS. Access to this information is delegated by the RO 296 as part of the grant process. 298 [[ See issue #33 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 299 issues/33) ]] 301 1.4. Sequences 303 GNAP can be used in a variety of ways to allow the core delegation 304 process to take place. Many portions of this process are 305 conditionally present depending on the context of the deployments, 306 and not every step in this overview will happen in all circumstances. 308 Note that a connection between roles in this process does not 309 necessarily indicate that a specific protocol message is sent across 310 the wire between the components fulfilling the roles in question, or 311 that a particular step is required every time. For example, for an 312 RC interested in only getting subject information directly, and not 313 calling an RS, all steps involving the RS below do not apply. 315 In some circumstances, the information needed at a given stage is 316 communicated out of band or is preconfigured between the components 317 or entities performing the roles. For example, one entity can fulfil 318 multiple roles, and so explicit communication between the roles is 319 not necessary within the protocol flow. 321 +------------+ +------------+ 322 | Requesting | ~ ~ ~ ~ ~ ~ | Resource | 323 | Party (RQ) | | Owner (RO) | 324 +------------+ +------------+ 325 + + 326 + + 327 (A) (B) 328 + + 329 + + 330 +--------+ + +------------+ 331 |Resource|--------------(1)------+------>| Resource | 332 | Client | + | Server | 333 | (RC) | +---------------+ | (RS) | 334 | |--(2)->| Authorization | | | 335 | |<-(3)--| Server | | | 336 | | | (AS) | | | 337 | |--(4)->| | | | 338 | |<-(5)--| | | | 339 | |--------------(6)------------->| | 340 | | | |<~(7)~~| | 341 | |<-------------(8)------------->| | 342 | |--(9)->| | | | 343 | |<-(10)-| | | | 344 | |--------------(11)------------>| | 345 | | | |<~(12)~| | 346 | |-(13)->| | | | 347 | | | | | | 348 +--------+ +---------------+ +------------+ 350 Legend 351 + + + indicates a possible interaction with a human 352 ----- indicates an interaction between protocol roles 353 ~ ~ ~ indicates a potential equivalence or out-of-band communication between roles 355 * (A) The RQ interacts with the RC to indicate a need for resources 356 on behalf of the RO. This could identify the RS the RC needs to 357 call, the resources needed, or the RO that is needed to approve 358 the request. Note that the RO and RQ are often the same entity in 359 practice. 361 * (1) The RC attempts to call the RS (Section 10.4) to determine 362 what access is needed. The RS informs the RC that access can be 363 granted through the AS. Note that for most situations, the RC 364 already knows which AS to talk to and which kinds of access it 365 needs. 367 * (2) The RC requests access at the AS (Section 2). 369 * (3) The AS processes the request and determines what is needed to 370 fulfill the request. The AS sends its response to the RC 371 (Section 3). 373 * (B) If interaction is required, the AS interacts with the RO 374 (Section 4) to gather authorization. The interactive component of 375 the AS can function using a variety of possible mechanisms 376 including web page redirects, applications, challenge/response 377 protocols, or other methods. The RO approves the request for the 378 RC being operated by the RQ. Note that the RO and RQ are often 379 the same entity in practice. 381 * (4) The RC continues the grant at the AS (Section 5). 383 * (5) If the AS determines that access can be granted, it returns a 384 response to the RC (Section 3) including an access token 385 (Section 3.2) for calling the RS and any directly returned 386 information (Section 3.4) about the RO. 388 * (6) The RC uses the access token (Section 7) to call the RS. 390 * (7) The RS determines if the token is sufficient for the request 391 by examining the token, potentially calling the AS (Section 10.1). 392 Note that the RS could also examine the token directly, call an 393 internal data store, execute a policy engine request, or any 394 number of alternative methods for validating the token and its 395 fitness for the request. 397 * (8) The RC to call the RS (Section 7) using the access token until 398 the RS or RC determine that the token is no longer valid. 400 * (9) When the token no longer works, the RC fetches an updated 401 access token (Section 6.1) based on the rights granted in (5). 403 * (10) The AS issues a new access token (Section 3.2) to the RC. 405 * (11) The RC uses the new access token (Section 7) to call the RS. 407 * (12) The RS determines if the new token is sufficient for the 408 request by examining the token, potentially calling the AS 409 (Section 10.1). 411 * (13) The RC disposes of the token (Section 6.2) once the RC has 412 completed its access of the RS and no longer needs the token. 414 The following sections and Appendix C contain specific guidance on 415 how to use GNAP in different situations and deployments. 417 1.4.1. Redirect-based Interaction 419 In this example flow, the RC is a web application that wants access 420 to resources on behalf of the current user, who acts as both the 421 requesting party (RQ) and the resource owner (RO). Since the RC is 422 capable of directing the user to an arbitrary URL and receiving 423 responses from the user's browser, interaction here is handled 424 through front-channel redirects using the user's browser. The RC 425 uses a persistent session with the user to ensure the same user that 426 is starting the interaction is the user that returns from the 427 interaction. 429 +--------+ +--------+ +------+ 430 | RC | | AS | | RO | 431 | | | | | + | 432 | |< (1) + Start Session + + + + + + + + + + + + + + + +| RQ | 433 | | | | |(User)| 434 | |--(2)--- Request Access --------->| | | | 435 | | | | | | 436 | |<-(3)-- Interaction Needed -------| | | | 437 | | | | | | 438 | |+ (4) + Redirect for Interaction + + + + + + + + + > | | 439 | | | | | | 440 | | | |<+ (5) +>| | 441 | | | | AuthN | | 442 | | | | | | 443 | | | |<+ (6) +>| | 444 | | | | AuthZ | | 445 | | | | | | 446 | |< (7) + Redirect for Continuation + + + + + + + + + +| | 447 | | | | +------+ 448 | |--(8)--- Continue Request ------->| | 449 | | | | 450 | |<-(9)----- Grant Access ----------| | 451 | | | | 452 +--------+ +--------+ 454 1. The RC establishes a verifiable session to the user, in the role 455 of the RQ. 457 2. The RC requests access to the resource (Section 2). The RC 458 indicates that it can redirect to an arbitrary URL 459 (Section 2.5.1) and receive a callback from the browser 460 (Section 2.5.3). The RC stores verification information for its 461 callback in the session created in (1). 463 3. The AS determines that interaction is needed and responds 464 (Section 3) with a URL to send the user to (Section 3.3.1) and 465 information needed to verify the callback (Section 3.3.3) in (7). 466 The AS also includes information the RC will need to continue the 467 request (Section 3.1) in (8). The AS associates this 468 continuation information with an ongoing request that will be 469 referenced in (4), (6), and (8). 471 4. The RC stores the verification and continuation information from 472 (3) in the session from (1). The RC then redirects the user to 473 the URL (Section 4.1) given by the AS in (3). The user's browser 474 loads the interaction redirect URL. The AS loads the pending 475 request based on the incoming URL generated in (3). 477 5. The user authenticates at the AS, taking on the role of the RO. 479 6. As the RO, the user authorizes the pending request from the RC. 481 7. When the AS is done interacting with the user, the AS redirects 482 the user back (Section 4.4.1) to the RC using the callback URL 483 provided in (2). The callback URL is augmented with an 484 interaction reference that the AS associates with the ongoing 485 request created in (2) and referenced in (4). The callback URL 486 is also augmented with a hash of the security information 487 provided in (2) and (3). The RC loads the verification 488 information from (2) and (3) from the session created in (1). 489 The RC calculates a hash (Section 4.4.3) based on this 490 information and continues only if the hash validates. Note that 491 the RC needs to ensure that the parameters for the incoming 492 request match those that it is expecting from the session created 493 in (1). The RC also needs to be prepared for the RQ never being 494 returned to the RC and handle time outs appropriately. 496 8. The RC loads the continuation information from (3) and sends the 497 interaction reference from (7) in a request to continue the 498 request (Section 5.1). The AS validates the interaction 499 reference ensuring that the reference is associated with the 500 request being continued. 502 9. If the request has been authorized, the AS grants access to the 503 information in the form of access tokens (Section 3.2) and direct 504 subject information (Section 3.4) to the RC. 506 An example set of protocol messages for this method can be found in 507 Appendix C.1. 509 1.4.2. User-code Interaction 511 In this example flow, the RC is a device that is capable of 512 presenting a short, human-readable code to the user and directing the 513 user to enter that code at a known URL. The RC is not capable of 514 presenting an arbitrary URL to the user, nor is it capable of 515 accepting incoming HTTP requests from the user's browser. The RC 516 polls the AS while it is waiting for the RO to authorize the request. 517 The user's interaction is assumed to occur on a secondary device. In 518 this example it is assumed that the user is both the RQ and RO, 519 though the user is not assumed to be interacting with the RC through 520 the same web browser used for interaction at the AS. 522 +--------+ +--------+ +------+ 523 | RC | | AS | | RO | 524 | |--(1)--- Request Access --------->| | | + | 525 | | | | | RQ | 526 | |<-(2)-- Interaction Needed -------| | |(User)| 527 | | | | | | 528 | |+ (3) + + Display User Code + + + + + + + + + + + + >| | 529 | | | | | | 530 | | | |<+ (4) + | | 531 | | | |Open URI | | 532 | | | | | | 533 | | | |<+ (5) +>| | 534 | | | | AuthN | | 535 | |--(9)--- Continue Request (A) --->| | | | 536 | | | |<+ (6) +>| | 537 | |<-(10)- Not Yet Granted (Wait) ---| | Code | | 538 | | | | | | 539 | | | |<+ (7) +>| | 540 | | | | AuthZ | | 541 | | | | | | 542 | | | |<+ (8) +>| | 543 | | | |Completed| | 544 | | | | | | 545 | |--(11)-- Continue Request (B) --->| | +------+ 546 | | | | 547 | |<-(12)----- Grant Access ---------| | 548 | | | | 549 +--------+ +--------+ 551 1. The RC requests access to the resource (Section 2). The RC 552 indicates that it can display a user code (Section 2.5.4). 554 2. The AS determines that interaction is needed and responds 555 (Section 3) with a user code to communicate to the user 556 (Section 3.3.4). This could optionally include a URL to direct 557 the user to, but this URL should be static and so could be 558 configured in the RC's documentation. The AS also includes 559 information the RC will need to continue the request 560 (Section 3.1) in (8) and (10). The AS associates this 561 continuation information with an ongoing request that will be 562 referenced in (4), (6), (8), and (10). 564 3. The RC stores the continuation information from (2) for use in 565 (8) and (10). The RC then communicates the code to the user 566 (Section 4.1) given by the AS in (2). 568 4. The user's directs their browser to the user code URL. This URL 569 is stable and can be communicated via the RC's documentation, 570 the AS documentation, or the RC software itself. Since it is 571 assumed that the RO will interact with the AS through a 572 secondary device, the RC does not provide a mechanism to launch 573 the RO's browser at this URL. 575 5. The RQ authenticates at the AS, taking on the role of the RO. 577 6. The RO enters the code communicated in (3) to the AS. The AS 578 validates this code against a current request in process. 580 7. As the RO, the user authorizes the pending request from the RC. 582 8. When the AS is done interacting with the user, the AS indicates 583 to the RO that the request has been completed. 585 9. Meanwhile, the RC loads the continuation information stored at 586 (3) and continues the request (Section 5). The AS determines 587 which ongoing access request is referenced here and checks its 588 state. 590 10. If the access request has not yet been authorized by the RO in 591 (6), the AS responds to the RC to continue the request 592 (Section 3.1) at a future time through additional polled 593 continuation requests. This response can include updated 594 continuation information as well as information regarding how 595 long the RC should wait before calling again. The RC replaces 596 its stored continuation information from the previous response 597 (2). Note that the AS may need to determine that the RO has not 598 approved the request in a sufficient amount of time and return 599 an appropriate error to the RC. 601 11. The RC continues to poll the AS (Section 5.2) with the new 602 continuation information in (9). 604 12. If the request has been authorized, the AS grants access to the 605 information in the form of access tokens (Section 3.2) and 606 direct subject information (Section 3.4) to the RC. 608 An example set of protocol messages for this method can be found in 609 Appendix C.2. 611 1.4.3. Asynchronous Authorization 613 In this example flow, the RQ and RO roles are fulfilled by different 614 parties, and the RO does not interact with the RC. The AS reaches 615 out asynchronously to the RO during the request process to gather the 616 RO's authorization for the RC's request. The RC polls the AS while 617 it is waiting for the RO to authorize the request. 619 +--------+ +--------+ +------+ 620 | RC | | AS | | RO | 621 | |--(1)--- Request Access --------->| | | | 622 | | | | | | 623 | |<-(2)-- Not Yet Granted (Wait) ---| | | | 624 | | | |<+ (3) +>| | 625 | | | | AuthN | | 626 | |--(6)--- Continue Request (A) --->| | | | 627 | | | |<+ (4) +>| | 628 | |<-(7)-- Not Yet Granted (Wait) ---| | AuthZ | | 629 | | | | | | 630 | | | |<+ (5) +>| | 631 | | | |Completed| | 632 | | | | | | 633 | |--(8)--- Continue Request (B) --->| | +------+ 634 | | | | 635 | |<-(9)------ Grant Access ---------| | 636 | | | | 637 +--------+ +--------+ 639 1. The RC requests access to the resource (Section 2). The RC does 640 not send any interactions modes to the server, indicating that it 641 does not expect to interact with the RO. The RC can also signal 642 which RO it requires authorization from, if known, by using the 643 user request section (Section 2.4). 645 2. The AS determines that interaction is needed, but the RC cannot 646 interact with the RO. The AS responds (Section 3) with the 647 information the RC will need to continue the request 648 (Section 3.1) in (6) and (8), including a signal that the RC 649 should wait before checking the status of the request again. The 650 AS associates this continuation information with an ongoing 651 request that will be referenced in (3), (4), (5), (6), and (8). 653 3. The AS determines which RO to contact based on the request in 654 (1), through a combination of the user request (Section 2.4), the 655 resources request (Section 2.1), and other policy information. 656 The AS contacts the RO and authenticates them. 658 4. The RO authorizes the pending request from the RC. 660 5. When the AS is done interacting with the RO, the AS indicates to 661 the RO that the request has been completed. 663 6. Meanwhile, the RC loads the continuation information stored at 664 (3) and continues the request (Section 5). The AS determines 665 which ongoing access request is referenced here and checks its 666 state. 668 7. If the access request has not yet been authorized by the RO in 669 (6), the AS responds to the RC to continue the request 670 (Section 3.1) at a future time through additional polling. This 671 response can include refreshed credentials as well as information 672 regarding how long the RC should wait before calling again. The 673 RC replaces its stored continuation information from the previous 674 response (2). Note that the AS may need to determine that the RO 675 has not approved the request in a sufficient amount of time and 676 return an appropriate error to the RC. 678 8. The RC continues to poll the AS (Section 5.2) with the new 679 continuation information from (7). 681 9. If the request has been authorized, the AS grants access to the 682 information in the form of access tokens (Section 3.2) and direct 683 subject information (Section 3.4) to the RC. 685 An example set of protocol messages for this method can be found in 686 Appendix D.1. 688 1.4.4. Software-only Authorization 690 In this example flow, the AS policy allows the RC to make a call on 691 its own behalf, without the need for a RO to be involved at runtime 692 to approve the decision. Since there is no explicit RO, the RC does 693 not interact with an RO. 695 +--------+ +--------+ 696 | RC | | AS | 697 | |--(1)--- Request Access --------->| | 698 | | | | 699 | |<-(2)---- Grant Access -----------| | 700 | | | | 701 +--------+ +--------+ 703 1. The RC requests access to the resource (Section 2). The RC does 704 not send any interactions modes to the server. 706 2. The AS determines that the request is been authorized, the AS 707 grants access to the information in the form of access tokens 708 (Section 3.2) and direct subject information (Section 3.4) to the 709 RC. 711 An example set of protocol messages for this method can be found in 712 Appendix D. 714 1.4.5. Refreshing an Expired Access Token 716 In this example flow, the RC receives an access token to access a 717 resource server through some valid GNAP process. The RC uses that 718 token at the RS for some time, but eventually the access token 719 expires. The RC then gets a new access token by rotating the expired 720 access token at the AS using the token's management URL. 722 +--------+ +--------+ 723 | RC | | AS | 724 | |--(1)--- Request Access ----------------->| | 725 | | | | 726 | |<-(2)--- Grant Access --------------------| | 727 | | | | 728 | | +--------+ | | 729 | |--(3)--- Access Resource --->| RS | | | 730 | | | | | | 731 | |<-(4)--- Error Response -----| | | | 732 | | +--------+ | | 733 | | | | 734 | |--(5)--- Rotate Token ------------------->| | 735 | | | | 736 | |<-(6)--- Rotated Token -------------------| | 737 | | | | 738 +--------+ +--------+ 740 1. The RC requests access to the resource (Section 2). 742 2. The AS grants access to the resource (Section 3) with an access 743 token (Section 3.2) usable at the RS. The access token response 744 includes a token management URI. 746 3. The RC presents the token (Section 7) to the RS. The RS 747 validates the token and returns an appropriate response for the 748 API. 750 4. When the access token is expired, the RS responds to the RC with 751 an error. 753 5. The RC calls the token management URI returned in (2) to rotate 754 the access token (Section 6.1). The RC presents the access token 755 as well as the appropriate key. 757 6. The AS validates the rotation request including the signature and 758 keys presented in (5) and returns a new access token 759 (Section 3.2.1). The response includes a new access token and 760 can also include updated token management information, which the 761 RC will store in place of the values returned in (2). 763 2. Requesting Access 765 To start a request, the RC sends JSON [RFC8259] document with an 766 object as its root. Each member of the request object represents a 767 different aspect of the RC's request. Each field is described in 768 detail in a section below. 770 resources (object / array of objects/strings) Describes the rights 771 that the RC is requesting for one or more access tokens to be used 772 at RS's. Section 2.1 774 subject (object) Describes the information about the RO that the RC 775 is requesting to be returned directly in the response from the AS. 776 Section 2.2 778 client (object / string) Describes the RC that is making this 779 request, including the key that the RC will use to protect this 780 request and any continuation requests at the AS and any user- 781 facing information about the RC used in interactions at the AS. 782 Section 2.3 784 user (object / string) Identifies the RQ to the AS in a manner that 785 the AS can verify, either directly or by interacting with the RQ 786 to determine their status as the RO. Section 2.4 788 interact (object) Describes the modes that the RC has for allowing 789 the RO to interact with the AS and modes for the RC to receive 790 updates when interaction is complete. Section 2.5 792 capabilities (array of strings) Identifies named extension 793 capabilities that the RC can use, signaling to the AS which 794 extensions it can use. Section 2.6 796 existing_grant (string) Identifies a previously-existing grant that 797 the RC is extending with this request. Section 2.7 799 claims (object) Identifies the identity claims to be returned as 800 part of an OpenID Connect claims request. Section 2.8 802 Additional members of this request object can be defined by 803 extensions to this protocol as described in Section 2.9 805 A non-normative example of a grant request is below: 807 { 808 "resources": [ 809 { 810 "type": "photo-api", 811 "actions": [ 812 "read", 813 "write", 814 "dolphin" 815 ], 816 "locations": [ 817 "https://server.example.net/", 818 "https://resource.local/other" 819 ], 820 "datatypes": [ 821 "metadata", 822 "images" 823 ] 824 }, 825 "dolphin-metadata" 826 ], 827 "client": { 828 "display": { 829 "name": "My Client Display Name", 830 "uri": "https://example.net/client" 831 }, 832 "key": { 833 "proof": "jwsd", 834 "jwk": { 835 "kty": "RSA", 836 "e": "AQAB", 837 "kid": "xyz-1", 838 "alg": "RS256", 839 "n": "kOB5rR4Jv0GMeL...." 840 } 841 } 842 }, 843 "interact": { 844 "redirect": true, 845 "callback": { 846 "method": "redirect", 847 "uri": "https://client.example.net/return/123455", 848 "nonce": "LKLTI25DK82FX4T4QFZC" 849 } 850 }, 851 "capabilities": ["ext1", "ext2"], 852 "subject": { 853 "sub_ids": ["iss_sub", "email"], 854 "assertions": ["id_token"] 855 } 856 } 858 The request MUST be sent as a JSON object in the body of the HTTP 859 POST request with Content-Type "application/json", unless otherwise 860 specified by the signature mechanism. 862 2.1. Requesting Resources 864 If the RC is requesting one or more access tokens for the purpose of 865 accessing an API, the RC MUST include a "resources" field. This 866 field MUST be an array (for a single access token (Section 2.1.1)) or 867 an object (for multiple access tokens (Section 2.1.3)), as described 868 in the following sections. 870 2.1.1. Requesting a Single Access Token 872 When requesting an access token, the RC MUST send a "resources" field 873 containing a JSON array. The elements of the JSON array represent 874 rights of access that the RC is requesting in the access token. The 875 requested access is the sum of all elements within the array. 877 The RC declares what access it wants to associated with the resulting 878 access token using objects that describe multiple dimensions of 879 access. Each object contains a "type" property that determines the 880 type of API that the RC is calling. 882 type (string) The type of resource request as a string. This field 883 MAY define which other fields are allowed in the request object. 884 This field is REQUIRED. 886 The value of this field is under the control of the AS. This field 887 MUST be compared using an exact byte match of the string value 888 against known types by the AS. The AS MUST ensure that there is no 889 collision between different authorization data types that it 890 supports. The AS MUST NOT do any collation or normalization of data 891 types during comparison. It is RECOMMENDED that designers of 892 general-purpose APIs use a URI for this field to avoid collisions 893 between multiple API types protected by a single AS. 895 While it is expected that many APIs will have its own properties, a 896 set of common properties are defined here. Specific API 897 implementations SHOULD NOT re-use these fields with different 898 semantics or syntax. The available values for these properties are 899 determined by the API being protected at the RS. 901 [[ See issue #34 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 902 issues/34) ]] 904 actions (array of strings) The types of actions the RC will take at 905 the RS as an array of strings. For example, an RC asking for a 906 combination of "read" and "write" access. 908 locations (array of strings) The location of the RS as an array of 909 strings. These strings are typically URIs identifying the 910 location of the RS. 912 datatypes (array of strings) The kinds of data available to the RC 913 at the RS's API as an array of strings. For example, an RC asking 914 for access to raw "image" data and "metadata" at a photograph API. 916 identifier (string) A string identifier indicating a specific 917 resource at the RS. For example, a patient identifier for a 918 medical API or a bank account number for a financial API. 920 The following non-normative example shows the use of both common and 921 API-specific fields as part of two different access "type" values. 923 "resources": [ 924 { 925 "type": "photo-api", 926 "actions": [ 927 "read", 928 "write", 929 "dolphin" 930 ], 931 "locations": [ 932 "https://server.example.net/", 933 "https://resource.local/other" 934 ], 935 "datatypes": [ 936 "metadata", 937 "images" 938 ] 939 }, 940 { 941 "type": "financial-transaction", 942 "actions": [ 943 "withdraw" 944 ], 945 "identifier": "account-14-32-32-3", 946 "currency": "USD" 947 } 948 ] 950 If this request is approved, the resulting access token 951 (Section 3.2.1) will include the sum of both of the requested types 952 of access. 954 2.1.2. Requesting Resources By Reference 956 Instead of sending an object describing the requested resource 957 (Section 2.1.1), a RC MAY send a string known to the AS or RS 958 representing the access being requested. Each string SHOULD 959 correspond to a specific expanded object representation at the AS. 961 [[ See issue #35 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 962 issues/35) ]] 964 "resources": [ 965 "read", "dolphin-metadata", "some other thing" 966 ] 968 This value is opaque to the RC and MAY be any valid JSON string, and 969 therefore could include spaces, unicode characters, and properly 970 escaped string sequences. However, in some situations the value is 971 intended to be seen and understood be the RC developer. In such 972 cases, the API designer choosing any such human-readable strings 973 SHOULD take steps to ensure the string values are not easily confused 974 by a developer 976 This functionality is similar in practice to OAuth 2's "scope" 977 parameter [RFC6749], where a single string represents the set of 978 access rights requested by the RC. As such, the reference string 979 could contain any valid OAuth 2 scope value as in Appendix D.2. Note 980 that the reference string here is not bound to the same character 981 restrictions as in OAuth 2's "scope" definition. 983 A single "resources" array MAY include both object-type and string- 984 type resource items. 986 "resources": [ 987 { 988 "type": "photo-api", 989 "actions": [ 990 "read", 991 "write", 992 "dolphin" 993 ], 994 "locations": [ 995 "https://server.example.net/", 996 "https://resource.local/other" 997 ], 998 "datatypes": [ 999 "metadata", 1000 "images" 1001 ] 1002 }, 1003 "read", 1004 "dolphin-metadata", 1005 { 1006 "type": "financial-transaction", 1007 "actions": [ 1008 "withdraw" 1009 ], 1010 "identifier": "account-14-32-32-3", 1011 "currency": "USD" 1012 }, 1013 "some other thing" 1014 ] 1016 [[ See issue #36 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1017 issues/36) ]] 1019 2.1.3. Requesting Multiple Access Tokens 1021 When requesting multiple access tokens, the resources field is a JSON 1022 object. The names of the JSON object fields are token identifiers 1023 chosen by the RC, and MAY be any valid string. The values of the 1024 JSON object fields are JSON arrays representing a single access token 1025 request, as specified in requesting a single access token 1026 (Section 2.1.1). 1028 The following non-normative example shows a request for two separate 1029 access tokens, "token1" and "token2". 1031 "resources": { 1032 "token1": [ 1033 { 1034 "type": "photo-api", 1035 "actions": [ 1036 "read", 1037 "write", 1038 "dolphin" 1039 ], 1040 "locations": [ 1041 "https://server.example.net/", 1042 "https://resource.local/other" 1043 ], 1044 "datatypes": [ 1045 "metadata", 1046 "images" 1047 ] 1048 }, 1049 "dolphin-metadata" 1050 ], 1051 "token2": [ 1052 { 1053 "type": "walrus-access", 1054 "actions": [ 1055 "foo", 1056 "bar" 1057 ], 1058 "locations": [ 1059 "https://resource.other/" 1060 ], 1061 "datatypes": [ 1062 "data", 1063 "pictures", 1064 "walrus whiskers" 1065 ] 1066 } 1067 ] 1068 } 1070 Any approved access requests are returned in the multiple access 1071 token response (Section 3.2.2) structure using the token identifiers 1072 in the request. 1074 2.1.4. Signaling Token Behavior 1076 While the AS is ultimately in control of how tokens are returned and 1077 bound to the RC, sometimes the RC has context about what it can 1078 support that can affect the AS's response. This specification 1079 defines several flags that are passed as resource reference strings 1080 (Section 2.1.2). 1082 Each flag applies only to the single resource request in which it 1083 appears. 1085 Support of all flags is optional, such as any other resource 1086 reference value. 1088 multi_token The RC wishes to support multiple simultaneous access 1089 tokens through the token rotation process. When the RC rotates an 1090 access token (Section 6.1), the AS does not invalidate the 1091 previous access token. The old access token continues to remain 1092 valid until such time as it expires or is revoked through other 1093 means. 1095 split_token The RC is capable of receiving multiple access tokens 1096 (Section 3.2.2) in response to any single token request 1097 (Section 2.1.1), or receiving a different number of tokens than 1098 specified in the multiple token request (Section 2.1.3). The 1099 labels of the returned additional tokens are chosen by the AS. 1100 The RC MUST be able to tell from the token response where and how 1101 it can use each of the access tokens. [[ See issue #37 1102 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/37) ]] 1104 bind_token The RC wants the issued access token to be bound to the 1105 key the RC used (Section 2.3.2) to make the request. The 1106 resulting access token MUST be bound using the same "proof" 1107 mechanism used by the client with a "key" value of "true", 1108 indicating the client's presented key is to be used for binding. 1109 [[ See issue #38 (https://github.com/ietf-wg-gnap/gnap-core- 1110 protocol/issues/38) ]] 1112 The AS MUST respond with any applied flags in the token response 1113 (Section 3.2) "resources" section. 1115 In this non-normative example, the requested access token is to be 1116 bound to the client's key and should be kept during rotation. 1118 "resources": [ 1119 { 1120 "type": "photo-api", 1121 "actions": [ 1122 "read", 1123 "write", 1124 "dolphin" 1125 ], 1126 "locations": [ 1127 "https://server.example.net/", 1128 "https://resource.local/other" 1129 ], 1130 "datatypes": [ 1131 "metadata", 1132 "images" 1133 ] 1134 }, 1135 "read", 1136 "bind_token", 1137 "multi_token" 1138 ] 1140 Additional flags can be registered in a registry TBD (Section 12). 1142 [[ See issue #39 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1143 issues/39) ]] 1145 2.2. Requesting User Information 1147 If the RC is requesting information about the RO from the AS, it 1148 sends a "subject" field as a JSON object. This object MAY contain 1149 the following fields (or additional fields defined in a registry TBD 1150 (Section 12)). 1152 sub_ids (array of strings) An array of subject identifier subject 1153 types requested for the RO, as defined by 1154 [I-D.ietf-secevent-subject-identifiers]. 1156 assertions (array of strings) An array of requested assertion 1157 formats. Possible values include "id_token" for an [OIDC] ID 1158 Token and "saml2" for a SAML 2 assertion. Additional assertion 1159 values are defined by a registry TBD (Section 12). [[ See issue 1160 #41 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/41) 1161 ]] 1163 "subject": { 1164 "sub_ids": [ "iss_sub", "email" ], 1165 "assertions": [ "id_token", "saml2" ] 1166 } 1168 The AS can determine the RO's identity and permission for releasing 1169 this information through interaction with the RO (Section 4), AS 1170 policies, or assertions presented by the RC (Section 2.4). If this 1171 is determined positively, the AS MAY return the RO's information in 1172 its response (Section 3.4) as requested. 1174 Subject identifiers requested by the RC serve only to identify the RO 1175 in the context of the AS and can't be used as communication channels 1176 by the RC, as discussed in Section 3.4. One method of requesting 1177 communication channels and other identity claims are discussed in 1178 Section 2.8. 1180 The AS SHOULD NOT re-use subject identifiers for multiple different 1181 ROs. 1183 [[ See issue #42 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1184 issues/42) ]] 1186 Note: the "sub_ids" and "assertions" request fields are independent 1187 of each other, and a returned assertion MAY omit a requested subject 1188 identifier. 1190 [[ See issue #43 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1191 issues/43) ]] 1193 2.3. Identifying the RC 1195 When sending a non-continuation request to the AS, the RC MUST 1196 identify itself by including the "client" field of the request and by 1197 signing the request as described in Section 8. Note that for a 1198 continuation request (Section 5), the RC instance is identified by 1199 its association with the request being continued and so this field is 1200 not sent under those circumstances. 1202 When RC information is sent by value, the "client" field of the 1203 request consists of a JSON object with the following fields. 1205 key (object / string) The public key of the RC to be used in this 1206 request as described in Section 2.3.2. This field is REQUIRED. 1208 class_id (string) An identifier string that the AS can use to 1209 identify the software comprising this instance of the RC. The 1210 contents and format of this field are up to the AS. This field is 1211 OPTIONAL. 1213 display (object) An object containing additional information that 1214 the AS MAY display to the RO during interaction, authorization, 1215 and management. This field is OPTIONAL. 1217 "client": { 1218 "key": { 1219 "proof": "httpsig", 1220 "jwk": { 1221 "kty": "RSA", 1222 "e": "AQAB", 1223 "kid": "xyz-1", 1224 "alg": "RS256", 1225 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xY..." 1226 }, 1227 "cert": "MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFA..." 1228 }, 1229 "class_id": "web-server-1234", 1230 "display": { 1231 "name": "My Client Display Name", 1232 "uri": "https://example.net/client" 1233 } 1234 } 1236 Additional fields are defined in a registry TBD (Section 12). 1238 The RC MUST prove possession of any presented key by the "proof" 1239 mechanism associated with the key in the request. Proof types are 1240 defined in a registry TBD (Section 12) and an initial set of methods 1241 is described in Section 8. 1243 Note that the AS MAY know the RC's public key ahead of time, and the 1244 AS MAY apply different policies to the request depending on what has 1245 been registered against that key. If the same public key is sent by 1246 value on subsequent access requests, the AS SHOULD treat these 1247 requests as coming from the same RC software instance for purposes of 1248 identification, authentication, and policy application. If the AS 1249 does not know the RC's public key ahead of time, the AS MAY accept or 1250 reject the request based on AS policy, attestations within the client 1251 request, and other mechanisms. 1253 [[ See issue #44 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1254 issues/44) ]] 1256 2.3.1. Identifying the RC Instance 1258 If the RC has an instance identifier that the AS can use to determine 1259 appropriate key information, the RC can send this value in the 1260 "instance_id" field. The instance identifier MAY be assigned to an 1261 RC instance at runtime through the Section 3.5 or MAY be obtained in 1262 another fashion, such as a static registration process at the AS. 1264 instance_id (string) An identifier string that the AS can use to 1265 identify the particular instance of this RC. The content and 1266 structure of this identifier is opaque to the RC. 1268 "client": { 1269 "instance_id": "client-541-ab" 1270 } 1272 If there are no additional fields to send, the RC MAY send the 1273 instance identifier as a direct reference value in lieu of the 1274 object. 1276 "client": "client-541-ab" 1278 When the AS receives a request with an instance identifier, the AS 1279 MUST ensure that the key used to sign the request (Section 8) is 1280 associated with the instance identifier. 1282 If the "instance_id" field is sent, it MUST NOT be accompanied by 1283 other fields unless such fields are explicitly marked safe for 1284 inclusion alongside the instance identifier. 1286 [[ See issue #45 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1287 issues/45) ]] 1289 If the AS does not recognize the instance identifier, the request 1290 MUST be rejected with an error. 1292 If the RC instance is identified in this manner, the registered key 1293 for the RC MAY be a symmetric key known to the AS. The RC MUST NOT 1294 send a symmetric key by value in the request, as doing so would 1295 expose the key directly instead of proving possession of it. 1297 [[ See issue #46 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1298 issues/46) ]] 1300 2.3.2. Identifying the RC Key 1302 The RC key MUST be a public key in at least one supported format and 1303 MUST be applicable to the proofing mechanism used in the request. If 1304 the key is sent in multiple formats, all the keys MUST be the same. 1305 The key presented in this field MUST be the key used to sign the 1306 request. 1308 proof (string) The form of proof that the RC will use when 1309 presenting the key to the AS. The valid values of this field and 1310 the processing requirements for each are detailed in Section 8. 1311 This field is REQUIRED. 1313 jwk (object) Value of the public key as a JSON Web Key. MUST contain 1314 an "alg" field which is used to validate the signature. MUST 1315 contain the "kid" field to identify the key in the signed object. 1317 cert (string) PEM serialized value of the certificate used to sign 1318 the request, with optional internal whitespace. 1320 cert#S256 (string) The certificate thumbprint calculated as per 1321 OAuth-MTLS [RFC8705] in base64 URL encoding. 1323 Additional key types are defined in a registry TBD (Section 12). 1325 [[ See issue #47 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1326 issues/47) ]] 1328 This non-normative example shows a single key presented in multiple 1329 formats using a single proofing mechanism. 1331 "key": { 1332 "proof": "jwsd", 1333 "jwk": { 1334 "kty": "RSA", 1335 "e": "AQAB", 1336 "kid": "xyz-1", 1337 "alg": "RS256", 1338 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xY..." 1339 }, 1340 "cert": "MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFA..." 1341 } 1343 Continuation requests (Section 5) MUST use the same key (or its most 1344 recent rotation) and proof method as the initial request. 1346 2.3.3. Providing Displayable RC Information 1348 If the RC has additional information to display to the RO during any 1349 interactions at the AS, it MAY send that information in the "display" 1350 field. This field is a JSON object that declares information to 1351 present to the RO during any interactive sequences. 1353 name (string) Display name of the RC software 1355 uri (string) User-facing web page of the RC software 1357 logo_uri (string) Display image to represent the RC software 1359 "display": { 1360 "name": "My Client Display Name", 1361 "uri": "https://example.net/client" 1362 } 1364 [[ See issue #48 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1365 issues/48) ]] 1367 Additional display fields are defined by a registry TBD (Section 12). 1369 The AS SHOULD use these values during interaction with the RO. The 1370 values are for informational purposes only and MUST NOT be taken as 1371 authentic proof of the RC's identity or source. The AS MAY restrict 1372 display values to specific RC instances, as identified by their keys 1373 in Section 2.3. 1375 2.3.4. Authenticating the RC 1377 If the presented key is known to the AS and is associated with a 1378 single instance of the RC software, the process of presenting a key 1379 and proving possession of that key is sufficient to authenticate the 1380 RC to the AS. The AS MAY associate policies with the RC software 1381 identified by this key, such as limiting which resources can be 1382 requested and which interaction methods can be used. For example, 1383 only specific RCs with certain known keys might be trusted with 1384 access tokens without the AS interacting directly with the RO as in 1385 Appendix D. 1387 The presentation of a key allows the AS to strongly associate 1388 multiple successive requests from the same RC with each other. This 1389 is true when the AS knows the key ahead of time and can use the key 1390 to authenticate the RC software, but also if the key is ephemeral and 1391 created just for this series of requests. As such the AS MAY allow 1392 for RCs to make requests with unknown keys. This pattern allows for 1393 ephemeral RCs, such as single-page applications, and RCs with many 1394 individual instances, such as mobile applications, to generate their 1395 own key pairs and use them within the protocol without having to go 1396 through a separate registration step. The AS MAY limit which 1397 capabilities are made available to RCs with unknown keys. For 1398 example, the AS could have a policy saying that only previously- 1399 registered RCs can request particular resources, or that all RCs with 1400 unknown keys have to be interactively approved by an RO. 1402 2.4. Identifying the User 1404 If the RC knows the identity of the RQ through one or more 1405 identifiers or assertions, the RC MAY send that information to the AS 1406 in the "user" field. The RC MAY pass this information by value or by 1407 reference. 1409 sub_ids (array of strings) An array of subject identifiers for the 1410 RQ, as defined by [I-D.ietf-secevent-subject-identifiers]. 1412 assertions (object) An object containing assertions as values keyed 1413 on the assertion type defined by a registry TBD (Section 12). 1414 Possible keys include "id_token" for an [OIDC] ID Token and 1415 "saml2" for a SAML 2 assertion. Additional assertion values are 1416 defined by a registry TBD (Section 12). [[ See issue #41 1417 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/41) ]] 1419 "user": { 1420 "sub_ids": [ { 1421 "subject_type": "email", 1422 "email": "user@example.com" 1423 } ], 1424 "assertions": { 1425 "id_token": "eyj..." 1426 } 1427 } 1429 Subject identifiers are hints to the AS in determining the RO and 1430 MUST NOT be taken as declarative statements that a particular RO is 1431 present at the RC and acting as the RQ. Assertions SHOULD be 1432 validated by the AS. [[ See issue #49 (https://github.com/ietf-wg- 1433 gnap/gnap-core-protocol/issues/49) ]] 1435 If the identified RQ does not match the RO present at the AS during 1436 an interaction step, the AS SHOULD reject the request with an error. 1438 [[ See issue #50 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1439 issues/50) ]] 1440 If the AS trusts the RC to present verifiable assertions, the AS MAY 1441 decide, based on its policy, to skip interaction with the RO, even if 1442 the RC provides one or more interaction modes in its request. 1444 2.4.1. Identifying the User by Reference 1446 User reference identifiers can be dynamically issued by the AS 1447 (Section 3.5) to allow the RC to represent the same RQ to the AS over 1448 subsequent requests. 1450 If the RC has a reference for the RQ at this AS, the RC MAY pass that 1451 reference as a string. The format of this string is opaque to the 1452 RC. 1454 "user": "XUT2MFM1XBIKJKSDU8QM" 1456 User reference identifiers are not intended to be human-readable user 1457 identifiers or structured assertions. For the RC to send either of 1458 these, use the full user request object (Section 2.4) instead. 1460 [[ See issue #51 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1461 issues/51) ]] 1463 If the AS does not recognize the user reference, it MUST return an 1464 error. 1466 2.5. Interacting with the User 1468 Many times, the AS will require interaction with the RO in order to 1469 approve a requested delegation to the RC for both resources and 1470 direct claim information. Many times the RQ using the RC is the same 1471 person as the RO, and the RC can directly drive interaction with the 1472 AS by redirecting the RQ on the same device, or by launching an 1473 application. Other times, the RC can provide information to start 1474 the RO's interaction on a secondary device, or the RC will wait for 1475 the RO to approve the request asynchronously. The RC could also be 1476 signaled that interaction has completed by the AS making callbacks. 1477 To facilitate all of these modes, the RC declares the means that it 1478 can interact using the "interact" field. 1480 The "interact" field is a JSON object with keys that declare 1481 different interaction modes. A RC MUST NOT declare an interaction 1482 mode it does not support. The RC MAY send multiple modes in the same 1483 request. There is no preference order specified in this request. An 1484 AS MAY respond to any, all, or none of the presented interaction 1485 modes (Section 3.3) in a request, depending on its capabilities and 1486 what is allowed to fulfill the request. This specification defines 1487 the following interaction modes: 1489 redirect (boolean) Indicates that the RC can direct the RQ to an 1490 arbitrary URL at the AS for interaction. Section 2.5.1 1492 app (boolean) Indicates that the RC can launch an application on the 1493 RQ's device for interaction. Section 2.5.2 1495 callback (object) Indicates that the RC can receive a callback from 1496 the AS after interaction with the RO has concluded. Section 2.5.3 1498 user_code (boolean) Indicates that the RC can communicate a human- 1499 readable short code to the RQ for use with a stable URL at the AS. 1500 Section 2.5.4 1502 ui_locales (array of strings) Indicates the RQ's preferred locales 1503 that the AS can use during interaction, particularly before the RO 1504 has authenticated. Section 2.5.5 1506 The following sections detail requests for interaction modes. 1507 Additional interaction modes are defined in a registry TBD 1508 (Section 12). 1510 [[ See issue #52 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1511 issues/52) ]] 1513 In this non-normative example, the RC is indicating that it can 1514 redirect (Section 2.5.1) the RQ to an arbitrary URL and can receive a 1515 callback (Section 2.5.3) through a browser request. 1517 "interact": { 1518 "redirect": true, 1519 "callback": { 1520 "method": "redirect", 1521 "uri": "https://client.example.net/return/123455", 1522 "nonce": "LKLTI25DK82FX4T4QFZC" 1523 } 1524 } 1526 In this non-normative example, the RC is indicating that it can 1527 display a user code (Section 2.5.4) and direct the RQ to an arbitrary 1528 URL of maximum length (Section 2.5.1.1) 255 characters, but it cannot 1529 accept a callback. 1531 "interact": { 1532 "redirect": 255, 1533 "user_code": true 1534 } 1536 If the RC does not provide a suitable interaction mechanism, the AS 1537 cannot contact the RO asynchronously, and the AS determines that 1538 interaction is required, then the AS SHOULD return an error since the 1539 RC will be unable to complete the request without authorization. 1541 The AS SHOULD apply suitable timeouts to any interaction mechanisms 1542 provided, including user codes and redirection URLs. The RC SHOULD 1543 apply suitable timeouts to any callback URLs. 1545 2.5.1. Redirect to an Arbitrary URL 1547 If the RC is capable of directing the RQ to a URL defined by the AS 1548 at runtime, the RC indicates this by sending the "redirect" field 1549 with the boolean value "true". The means by which the RC will 1550 activate this URL is out of scope of this specification, but common 1551 methods include an HTTP redirect, launching a browser on the RQ's 1552 device, providing a scannable image encoding, and printing out a URL 1553 to an interactive console. 1555 "interact": { 1556 "redirect": true 1557 } 1559 If this interaction mode is supported for this RC and request, the AS 1560 returns a redirect interaction response Section 3.3.1. 1562 2.5.1.1. Redirect to an Arbitrary Shortened URL 1564 If the RC would prefer to redirect to a shortened URL defined by the 1565 AS at runtime, the RC indicates this by sending the "redirect" field 1566 with an integer indicating the maximum character length of the 1567 returned URL. The AS MAY use this value to decide whether to return 1568 a shortened form of the response URL. If the AS cannot shorten its 1569 response URL enough to fit in the requested size, the AS SHOULD 1570 return an error. [[ See issue #53 (https://github.com/ietf-wg-gnap/ 1571 gnap-core-protocol/issues/53) ]] 1573 "interact": { 1574 "redirect": 255 1575 } 1577 If this interaction mode is supported for this RC and request, the AS 1578 returns a redirect interaction response with short URL Section 3.3.1. 1580 2.5.2. Open an Application-specific URL 1582 If the RC can open a URL associated with an application on the RQ's 1583 device, the RC indicates this by sending the "app" field with boolean 1584 value "true". The means by which the RC determines the application 1585 to open with this URL are out of scope of this specification. 1587 "interact": { 1588 "app": true 1589 } 1591 If this interaction mode is supported for this RC and request, the AS 1592 returns an app interaction response with an app URL payload 1593 Section 3.3.2. 1595 [[ See issue #54 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1596 issues/54) ]] 1598 2.5.3. Receive a Callback After Interaction 1600 If the RC is capable of receiving a message from the AS indicating 1601 that the RO has completed their interaction, the RC indicates this by 1602 sending the "callback" field. The value of this field is an object 1603 containing the following members. 1605 uri (string) REQUIRED. Indicates the URI to send the RO to after 1606 interaction. This URI MAY be unique per request and MUST be 1607 hosted by or accessible by the RC. This URI MUST NOT contain any 1608 fragment component. This URI MUST be protected by HTTPS, be 1609 hosted on a server local to the RO's browser ("localhost"), or use 1610 an application-specific URI scheme. If the RC needs any state 1611 information to tie to the front channel interaction response, it 1612 MUST use a unique callback URI to link to that ongoing state. The 1613 allowable URIs and URI patterns MAY be restricted by the AS based 1614 on the RC's presented key information. The callback URI SHOULD be 1615 presented to the RO during the interaction phase before redirect. 1616 [[ See issue #55 (https://github.com/ietf-wg-gnap/gnap-core- 1617 protocol/issues/55) ]] 1619 nonce (string) REQUIRED. Unique value to be used in the calculation 1620 of the "hash" query parameter sent to the callback URL, must be 1621 sufficiently random to be unguessable by an attacker. MUST be 1622 generated by the RC as a unique value for this request. 1624 method (string) REQUIRED. The callback method that the AS will use 1625 to contact the RC. Valid values include "redirect" 1626 Section 2.5.3.1 and "push" Section 2.5.3.2, with other values 1627 defined by a registry TBD (Section 12). 1629 hash_method (string) OPTIONAL. The hash calculation mechanism to be 1630 used for the callback hash in Section 4.4.3. Can be one of "sha3" 1631 or "sha2". If absent, the default value is "sha3". [[ See issue 1632 #56 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/56) 1633 ]] 1635 "interact": { 1636 "callback": { 1637 "method": "redirect", 1638 "uri": "https://client.example.net/return/123455", 1639 "nonce": "LKLTI25DK82FX4T4QFZC" 1640 } 1641 } 1643 If this interaction mode is supported for this RC and request, the AS 1644 returns a nonce for use in validating the callback response 1645 (Section 3.3.3). Requests to the callback URI MUST be processed as 1646 described in Section 4.4, and the AS MUST require presentation of an 1647 interaction callback reference as described in Section 5.1. 1649 [[ See issue #58 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1650 issues/58) ]] 1652 [[ See issue #59 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1653 issues/59) ]] 1655 2.5.3.1. Receive an HTTP Callback Through the Browser 1657 A callback "method" value of "redirect" indicates that the RC will 1658 expect a call from the RO's browser using the HTTP method GET as 1659 described in Section 4.4.1. 1661 "interact": { 1662 "callback": { 1663 "method": "redirect", 1664 "uri": "https://client.example.net/return/123455", 1665 "nonce": "LKLTI25DK82FX4T4QFZC" 1666 } 1667 } 1669 Requests to the callback URI MUST be processed by the RC as described 1670 in Section 4.4.1. 1672 Since the incoming request to the callback URL is from the RO's 1673 browser, this method is usually used when the RO and RQ are the same 1674 entity. As such, the RC MUST ensure the RQ is present on the request 1675 to prevent substitution attacks. 1677 2.5.3.2. Receive an HTTP Direct Callback 1679 A callback "method" value of "push" indicates that the RC will expect 1680 a call from the AS directly using the HTTP method POST as described 1681 in Section 4.4.2. 1683 "interact": { 1684 "callback": { 1685 "method": "push", 1686 "uri": "https://client.example.net/return/123455", 1687 "nonce": "LKLTI25DK82FX4T4QFZC" 1688 } 1689 } 1691 Requests to the callback URI MUST be processed by the RC as described 1692 in Section 4.4.2. 1694 Since the incoming request to the callback URL is from the AS and not 1695 from the RO's browser, the RC MUST NOT require the RQ to be present 1696 on the incoming HTTP request. 1698 [[ See issue #60 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1699 issues/60) ]] 1701 2.5.4. Display a Short User Code 1703 If the RC is capable of displaying or otherwise communicating a 1704 short, human-entered code to the RO, the RC indicates this by sending 1705 the "user_code" field with the boolean value "true". This code is to 1706 be entered at a static URL that does not change at runtime, as 1707 described in Section 3.3.4. 1709 "interact": { 1710 "user_code": true 1711 } 1713 If this interaction mode is supported for this RC and request, the AS 1714 returns a user code and interaction URL as specified in Section 4.2. 1716 2.5.5. Indicate Desired Interaction Locales 1718 If the RC knows the RQ's locale and language preferences, the RC can 1719 send this information to the AS using the "ui_locales" field with an 1720 array of locale strings as defined by [RFC5646]. 1722 "interact": { 1723 "ui_locales": ["en-US", "fr-CA"] 1724 } 1725 If possible, the AS SHOULD use one of the locales in the array, with 1726 preference to the first item in the array supported by the AS. If 1727 none of the given locales are supported, the AS MAY use a default 1728 locale. 1730 2.5.6. Extending Interaction Modes 1732 Additional interaction modes are defined in a registry TBD 1733 (Section 12). 1735 [[ See issue #61 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1736 issues/61) ]] 1738 2.6. Declaring RC Capabilities 1740 If the RC supports extension capabilities, it MAY present them to the 1741 AS in the "capabilities" field. This field is an array of strings 1742 representing specific extensions and capabilities, as defined by a 1743 registry TBD (Section 12). 1745 "capabilities": ["ext1", "ext2"] 1747 2.7. Referencing an Existing Grant Request 1749 If the RC has a reference handle from a previously granted request, 1750 it MAY send that reference in the "existing_grant" field. This field 1751 is a single string consisting of the "value" of the "access_token" 1752 returned in a previous request's continuation response (Section 3.1). 1754 "existing_grant": "80UPRY5NM33OMUKMKSKU" 1756 The AS MUST dereference the grant associated with the reference and 1757 process this request in the context of the referenced one. The AS 1758 MUST NOT alter the existing grant associated with the reference. 1760 [[ See issue #62 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1761 issues/62) ]] 1763 2.8. Requesting OpenID Connect Claims 1765 If the RC and AS both support OpenID Connect's claims query language 1766 as defined in [OIDC] Section 5.5, the RC sends the value of the 1767 OpenID Connect "claims" authorization request parameter as a JSON 1768 object under the name "claims" in the root of the request. 1770 "claims": { 1771 "id_token" : { 1772 "email" : { "essential" : true }, 1773 "email_verified" : { "essential" : true } 1774 }, 1775 "userinfo" : { 1776 "name" : { "essential" : true }, 1777 "picture" : null 1778 } 1779 } 1781 The contents of the "claims" parameter have the same semantics as 1782 they do in OpenID Connect's "claims" authorization request parameter, 1783 including all extensions such as [OIDC4IA]. The AS MUST process the 1784 claims object in the same way that it would with an OAuth 2 based 1785 authorization request. 1787 Note that because this is an independent query object, the "claims" 1788 value can augment or alter other portions of the request, namely the 1789 "resources" and "subject" fields. This query language uses the 1790 fields in the top level of the object to indicate the target for any 1791 requested claims. For instance, the "userinfo" target indicates that 1792 a returned access token would grant access to the given claims at the 1793 UserInfo Endpoint, while the "id_token" target indicates that the 1794 claims would be returned in an ID Token as described in Section 3.4. 1796 [[ See issue #63 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1797 issues/63) ]] 1799 [[ See issue #64 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1800 issues/64) ]] 1802 2.9. Extending The Grant Request 1804 The request object MAY be extended by registering new items in a 1805 registry TBD (Section 12). Extensions SHOULD be orthogonal to other 1806 parameters. Extensions MUST document any aspects where the extension 1807 item affects or influences the values or behavior of other request 1808 and response objects. 1810 [[ See issue #65 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1811 issues/65) ]] 1813 3. Grant Response 1815 In response to a RC's request, the AS responds with a JSON object as 1816 the HTTP entity body. Each possible field is detailed in the 1817 sections below 1818 continue (object) Indicates that the RC can continue the request by 1819 making an additional request using these parameters. Section 3.1 1821 access_token (object) A single access token that the RC can use to 1822 call the RS on behalf of the RO. Section 3.2.1 1824 multiple_access_token (object) Multiple named access tokens that the 1825 RC can use to call the RS on behalf of the RO. Section 3.2.2 1827 interact (object) Indicates that interaction through some set of 1828 defined mechanisms needs to take place. Section 3.3 1830 subject (object) Claims about the RO as known and declared by the 1831 AS. Section 3.4 1833 instance_id (string) An identifier this RC instance can use to 1834 identify itself when making future requests. Section 3.5 1836 user_handle (string) An identifier this RC instance can use to 1837 identify its current RQ when making future requests. Section 3.5 1839 error (object) An error code indicating that something has gone 1840 wrong. Section 3.6 1842 In this example, the AS is returning an interaction URL 1843 (Section 3.3.1), a callback nonce (Section 3.3.3), and a continuation 1844 handle (Section 3.1). 1846 { 1847 "interact": { 1848 "redirect": "https://server.example.com/interact/4CF492MLVMSW9MKMXKHQ", 1849 "callback": "MBDOFXG4Y5CVJCX821LH" 1850 }, 1851 "continue": { 1852 "access_token": { 1853 "value": "80UPRY5NM33OMUKMKSKU", 1854 "key": true 1855 }, 1856 "uri": "https://server.example.com/tx" 1857 } 1858 } 1860 In this example, the AS is returning a bearer access token 1861 (Section 3.2.1) with a management URL and a subject identifier 1862 (Section 3.4) in the form of an email address. 1864 { 1865 "access_token": { 1866 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 1867 "key": false, 1868 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L" 1869 }, 1870 "subject": { 1871 "sub_ids": [ { 1872 "subject_type": "email", 1873 "email": "user@example.com", 1874 } ] 1875 } 1876 } 1878 3.1. Request Continuation 1880 If the AS determines that the request can be continued with 1881 additional requests, it responds with the "continue" field. This 1882 field contains a JSON object with the following properties. 1884 uri (string) REQUIRED. The URI at which the RC can make 1885 continuation requests. This URI MAY vary per request, or MAY be 1886 stable at the AS if the AS includes an access token. The RC MUST 1887 use this value exactly as given when making a continuation request 1888 (Section 5). 1890 wait (integer) RECOMMENDED. The amount of time in integer seconds 1891 the RC SHOULD wait after receiving this continuation handle and 1892 calling the URI. 1894 access_token (object) RECOMMENDED. A unique access token for 1895 continuing the request, in the format specified in Section 3.2.1. 1896 This access token MUST be bound to the RC's key used in the 1897 request and MUST NOT be a "bearer" token. This access token MUST 1898 NOT be usable at resources outside of the AS. If the AS includes 1899 an access token, the RC MUST present the access token in all 1900 requests to the continuation URI as described in Section 7. [[ 1901 See issue #66 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1902 issues/66) ]] 1904 { 1905 "continue": { 1906 "access_token": { 1907 "value": "80UPRY5NM33OMUKMKSKU", 1908 "key": true 1909 }, 1910 "uri": "https://server.example.com/continue", 1911 "wait": 60 1912 } 1913 } 1915 The RC can use the values of this field to continue the request as 1916 described in Section 5. Note that the RC MUST sign all continuation 1917 requests with its key as described in Section 8. If the AS includes 1918 an "access_token", the RC MUST present the access token in its 1919 continuation request. 1921 This field SHOULD be returned when interaction is expected, to allow 1922 the RC to follow up after interaction has been concluded. 1924 [[ See issue #67 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1925 issues/67) ]] 1927 3.2. Access Tokens 1929 If the AS has successfully granted one or more access tokens to the 1930 RC, the AS responds with either the "access_token" or the 1931 "multiple_access_token" field. The AS MUST NOT respond with both the 1932 "access_token" and "multiple_access_token" fields. 1934 [[ See issue #68 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 1935 issues/68) ]] 1937 3.2.1. Single Access Token 1939 If the RC has requested a single access token and the AS has granted 1940 that access token, the AS responds with the "access_token" field. 1941 The value of this field is an object with the following properties. 1943 value (string) REQUIRED. The value of the access token as a string. 1944 The value is opaque to the RC. The value SHOULD be limited to 1945 ASCII characters to facilitate transmission over HTTP headers 1946 within other protocols without requiring additional encoding. 1948 manage (string) OPTIONAL. The management URI for this access token. 1950 If provided, the RC MAY manage its access token as described in 1951 Section 6. This management URI is a function of the AS and is 1952 separate from the RS the RC is requesting access to. This URI 1953 MUST NOT include the access token value and SHOULD be different 1954 for each access token issued in a request. 1956 resources (array of objects/strings) RECOMMENDED. A description of 1957 the rights associated with this access token, as defined in 1958 Section 2.1.1. If included, this MUST reflect the rights 1959 associated with the issued access token. These rights MAY vary 1960 from what was requested by the RC. 1962 expires_in (integer) OPTIONAL. The number of seconds in which the 1963 access will expire. The RC MUST NOT use the access token past 1964 this time. An RS MUST NOT accept an access token past this time. 1965 Note that the access token MAY be revoked by the AS or RS at any 1966 point prior to its expiration. 1968 key (object / string / boolean) REQUIRED. The key that the token is 1969 bound to. If the boolean value "true" is used, the token is bound 1970 to the key used by the RC (Section 2.3.2) in its request for 1971 access. If the boolean value "false" is used, the token is a 1972 bearer token with no key bound to it. Otherwise, the key MUST be 1973 an object or string in a format described in Section 2.3.2, 1974 describing a public key to which the RC can use the associated 1975 private key. The RC MUST be able to dereference or process the 1976 key information in order to be able to sign the request. 1978 The following non-normative example shows a single bearer token with 1979 a management URL that has access to three described resources. 1981 "access_token": { 1982 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 1983 "key": false, 1984 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L", 1985 "resources": [ 1986 { 1987 "type": "photo-api", 1988 "actions": [ 1989 "read", 1990 "write", 1991 "dolphin" 1992 ], 1993 "locations": [ 1994 "https://server.example.net/", 1995 "https://resource.local/other" 1996 ], 1997 "datatypes": [ 1998 "metadata", 1999 "images" 2000 ] 2001 }, 2002 "read", "dolphin-metadata" 2003 ] 2004 } 2006 The following non-normative example shows a single access token bound 2007 to the RC's key, which was presented using the detached JWS 2008 (Section 8.1) binding method. 2010 "access_token": { 2011 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 2012 "key": true, 2013 "resources": [ 2014 "finance", "medical" 2015 ] 2016 } 2018 If the RC requested multiple access tokens (Section 2.1.3), the AS 2019 MUST NOT respond with a single access token structure unless the RC 2020 sends the "split_token" flag as described in Section 2.1.4. 2022 [[ See issue #69 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2023 issues/69) ]] 2025 3.2.2. Multiple Access Tokens 2027 If the RC has requested multiple access tokens and the AS has granted 2028 at least one of them, the AS responds with the 2029 "multiple_access_tokens" field. The value of this field is a JSON 2030 object, and the property names correspond to the token identifiers 2031 chosen by the RC in the multiple access token request 2032 (Section 2.1.3). The values of the properties of this object are 2033 access tokens as described in Section 3.2.1. 2035 In this non-normative example, two bearer tokens are issued under the 2036 names "token1" and "token2", and only the first token has a 2037 management URL associated with it. 2039 "multiple_access_tokens": { 2040 "token1": { 2041 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 2042 "key": false, 2043 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L" 2044 }, 2045 "token2": { 2046 "value": "UFGLO2FDAFG7VGZZPJ3IZEMN21EVU71FHCARP4J1", 2047 "key": false 2048 } 2049 } 2051 Each access token corresponds to the named resources arrays in the 2052 RC's request (Section 2.1.3). 2054 The multiple access token response MUST be used when multiple access 2055 tokens are requested, even if only one access token is issued as a 2056 result of the request. The AS MAY refuse to issue one or more of the 2057 requested access tokens, for any reason. In such cases the refused 2058 token is omitted from the response and all of the other issued access 2059 tokens are included in the response the requested names appropriate 2060 names. 2062 If the RC requested a single access token (Section 2.1.1), the AS 2063 MUST NOT respond with the multiple access token structure unless the 2064 RC sends the "split_token" flag as described in Section 2.1.4. 2066 Each access token MAY have different proofing mechanisms. If 2067 management is allowed, each access token SHOULD have different 2068 management URIs. 2070 [[ See issue #70 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2071 issues/70) ]] 2073 3.3. Interaction Modes 2075 If the RC has indicated a capability to interact with the RO in its 2076 request (Section 2.5), and the AS has determined that interaction is 2077 both supported and necessary, the AS responds to the RC with any of 2078 the following values in the "interact" field of the response. There 2079 is no preference order for interaction modes in the response, and it 2080 is up to the RC to determine which ones to use. All supported 2081 interaction methods are included in the same "interact" object. 2083 redirect (string) Redirect to an arbitrary URL. Section 3.3.1 2085 app (string) Launch of an application URL. Section 3.3.2 2087 callback (string) Callback to an RC URL after interaction is 2088 completed. Section 3.3.3 2090 user_code (object) Display a short user code. Section 3.3.4 2092 Additional interaction mode responses can be defined in a registry 2093 TBD (Section 12). 2095 The AS MUST NOT respond with any interaction mode that the RC did not 2096 indicate in its request. The AS MUST NOT respond with any 2097 interaction mode that the AS does not support. Since interaction 2098 responses include secret or unique information, the AS SHOULD respond 2099 to each interaction mode only once in an ongoing request, 2100 particularly if the RC modifies its request (Section 5.3). 2102 3.3.1. Redirection to an arbitrary URL 2104 If the RC indicates that it can redirect to an arbitrary URL 2105 (Section 2.5.1) and the AS supports this mode for the RC's request, 2106 the AS responds with the "redirect" field, which is a string 2107 containing the URL to direct the RQ to. This URL MUST be unique for 2108 the request and MUST NOT contain any security-sensitive information. 2110 "interact": { 2111 "redirect": "https://interact.example.com/4CF492MLVMSW9MKMXKHQ" 2112 } 2114 The interaction URL returned represents a function of the AS but MAY 2115 be completely distinct from the URL the RC uses to request access 2116 (Section 2), allowing an AS to separate its user-interactive 2117 functionality from its back-end security functionality. 2119 [[ See issue #72 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2120 issues/72) ]] 2121 The RC sends the RQ to the URL to interact with the AS. The RC MUST 2122 NOT alter the URL in any way. The means for the RC to send the RQ to 2123 this URL is out of scope of this specification, but common methods 2124 include an HTTP redirect, launching the system browser, displaying a 2125 scannable code, or printing out the URL in an interactive console. 2127 3.3.2. Launch of an application URL 2129 If the RC indicates that it can launch an application URL 2130 (Section 2.5.2) and the AS supports this mode for the RC's request, 2131 the AS responds with the "app" field, which is a string containing 2132 the URL to direct the RQ to. This URL MUST be unique for the request 2133 and MUST NOT contain any security-sensitive information. 2135 "interact": { 2136 "app": "https://app.example.com/launch?tx=4CF492MLV" 2137 } 2139 The RC launches the URL as appropriate on its platform, and the means 2140 for the RC to launch this URL is out of scope of this specification. 2141 The RC MUST NOT alter the URL in any way. The RC MAY attempt to 2142 detect if an installed application will service the URL being sent 2143 before attempting to launch the application URL. 2145 [[ See issue #71 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2146 issues/71) ]] 2148 3.3.3. Post-interaction Callback to an RC URL 2150 If the RC indicates that it can receive a post-interaction callback 2151 on a URL (Section 2.5.3) and the AS supports this mode for the RC's 2152 request, the AS responds with a "callback" field containing a nonce 2153 that the RC will use in validating the callback as defined in 2154 Section 4.4.1. 2156 "interact": { 2157 "callback": "MBDOFXG4Y5CVJCX821LH" 2158 } 2160 [[ See issue #73 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2161 issues/73) ]] 2163 When the RO completes interaction at the AS, the AS MUST call the 2164 RC's callback URL using the method indicated in the callback request 2165 (Section 2.5.3) as described in Section 4.4.1. 2167 If the AS returns a "callback" nonce, the RC MUST NOT continue a 2168 grant request before it receives the associated interaction reference 2169 on the callback URI. 2171 3.3.4. Display of a Short User Code 2173 If the RC indicates that it can display a short user-typeable code 2174 (Section 2.5.4) and the AS supports this mode for the RC's request, 2175 the AS responds with a "user_code" field. This field is an object 2176 that contains the following members. 2178 code (string) REQUIRED. A unique short code that the user can type 2179 into an authorization server. This string MUST be case- 2180 insensitive, MUST consist of only easily typeable characters (such 2181 as letters or numbers). The time in which this code will be 2182 accepted SHOULD be short lived, such as several minutes. It is 2183 RECOMMENDED that this code be no more than eight characters in 2184 length. 2186 url (string) RECOMMENDED. The interaction URL that the RC will 2187 direct the RO to. This URL MUST be stable at the AS such that RCs 2188 can be statically configured with it. 2190 "interact": { 2191 "user_code": { 2192 "code": "A1BC-3DFF", 2193 "url": "https://srv.ex/device" 2194 } 2195 } 2197 The RC MUST communicate the "code" to the RQ in some fashion, such as 2198 displaying it on a screen or reading it out audibly. The "code" is a 2199 one-time-use credential that the AS uses to identify the pending 2200 request from the RC. When the RO enters this code (Section 4.2) into 2201 the AS, the AS MUST determine the pending request that it was 2202 associated with. If the AS does not recognize the entered code, the 2203 AS MUST display an error to the user. If the AS detects too many 2204 unrecognized codes entered, it SHOULD display an error to the user. 2206 The RC SHOULD also communicate the URL if possible to facilitate user 2207 interaction, but since the URL should be stable, the RC should be 2208 able to safely decide to not display this value. As this interaction 2209 mode is designed to facilitate interaction via a secondary device, it 2210 is not expected that the RC redirect the RQ to the URL given here at 2211 runtime. Consequently, the URL needs to be stable enough that a RC 2212 could be statically configured with it, perhaps referring the RQ to 2213 the URL via documentation instead of through an interactive means. 2214 If the RC is capable of communicating an arbitrary URL to the RQ, 2215 such as through a scannable code, the RC can use the "redirect" 2216 (Section 2.5.1) mode for this purpose instead of or in addition to 2217 the user code mode. 2219 The interaction URL returned represents a function of the AS but MAY 2220 be completely distinct from the URL the RC uses to request access 2221 (Section 2), allowing an AS to separate its user-interactive 2222 functionality from its back-end security functionality. 2224 [[ See issue #72 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2225 issues/72) ]] 2227 3.3.5. Extending Interaction Mode Responses 2229 Extensions to this specification can define new interaction mode 2230 responses in a registry TBD (Section 12). Extensions MUST document 2231 the corresponding interaction request. 2233 3.4. Returning User Information 2235 If information about the RO is requested and the AS grants the RC 2236 access to that data, the AS returns the approved information in the 2237 "subject" response field. This field is an object with the following 2238 OPTIONAL properties. 2240 sub_ids (array of strings) An array of subject identifiers for the 2241 RO, as defined by [I-D.ietf-secevent-subject-identifiers]. [[ See 2242 issue #74 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2243 issues/74) ]] 2245 assertions (object) An object containing assertions as values keyed 2246 on the assertion type defined by a registry TBD (Section 12). [[ 2247 See issue #41 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2248 issues/41) ]] 2250 updated_at (string) Timestamp as an ISO8610 date string, indicating 2251 when the identified account was last updated. The RC MAY use this 2252 value to determine if it needs to request updated profile 2253 information through an identity API. The definition of such an 2254 identity API is out of scope for this specification. 2256 "subject": { 2257 "sub_ids": [ { 2258 "subject_type": "email", 2259 "email": "user@example.com", 2260 } ], 2261 "assertions": { 2262 "id_token": "eyj..." 2263 } 2264 } 2266 The AS MUST return the "subject" field only in cases where the AS is 2267 sure that the RO and the RQ are the same party. This can be 2268 accomplished through some forms of interaction with the RO 2269 (Section 4). 2271 Subject identifiers returned by the AS SHOULD uniquely identify the 2272 RO at the AS. Some forms of subject identifier are opaque to the RC 2273 (such as the subject of an issuer and subject pair), while others 2274 forms (such as email address and phone number) are intended to allow 2275 the RC to correlate the identifier with other account information at 2276 the RC. The RC MUST NOT request or use any returned subject 2277 identifiers for communication purposes (see Section 2.2). That is, a 2278 subject identifier returned in the format of an email address or a 2279 phone number only identifies the RO to the AS and does not indicate 2280 that the AS has validated that the represented email address or phone 2281 number in the identifier is suitable for communication with the 2282 current user. To get such information, the RC MUST use an identity 2283 protocol to request and receive additional identity claims. While 2284 Section 2.8 specifies one such method, other identity protocols could 2285 also be used on top of GNAP to convey this information and the 2286 details of an identity protocol and associated schema are outside the 2287 scope of this specification. 2289 [[ See issue #75 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2290 issues/75) ]] 2292 [[ See issue #74 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2293 issues/74) ]] 2295 Extensions to this specification MAY define additional response 2296 properties in a registry TBD (Section 12). 2298 3.5. Returning Dynamically-bound Reference Handles 2300 Many parts of the RC's request can be passed as either a value or a 2301 reference. The use of a reference in place of a value allows for a 2302 client to optimize requests to the AS. 2304 Some references, such as for the RC instance's identity 2305 (Section 2.3.1) or the requested resources (Section 2.1.2), can be 2306 managed statically through an admin console or developer portal 2307 provided by the AS or RS. The developer of the RC can include these 2308 values in their code for a more efficient and compact request. 2310 If desired, the AS MAY also generate and return some of these 2311 references dynamically to the RC in its response to facilitate 2312 multiple interactions with the same software. The RC SHOULD use 2313 these references in future requests in lieu of sending the associated 2314 data value. These handles are intended to be used on future 2315 requests. 2317 Dynamically generated handles are string values that MUST be 2318 protected by the RC as secrets. Handle values MUST be unguessable 2319 and MUST NOT contain any sensitive information. Handle values are 2320 opaque to the RC. 2322 [[ See issue #76 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2323 issues/76) ]] 2325 All dynamically generated handles are returned as fields in the root 2326 JSON object of the response. This specification defines the 2327 following dynamic handle returns, additional handles can be defined 2328 in a registry TBD (Section 12). 2330 instance_id (string) A string value used to represent the 2331 information in the "client" object that the RC can use in a future 2332 request, as described in Section 2.3.1. 2334 user_handle (string) A string value used to represent the current 2335 user. The RC can use in a future request, as described in 2336 Section 2.4.1. 2338 This non-normative example shows two handles along side an issued 2339 access token. 2341 { 2342 "user_handle": "XUT2MFM1XBIKJKSDU8QM", 2343 "instance_id": "7C7C4AZ9KHRS6X63AJAO", 2344 "access_token": { 2345 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 2346 "key": false 2347 } 2348 } 2350 [[ See issue #77 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2351 issues/77) ]] 2353 [[ See issue #78 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2354 issues/78) ]] 2356 3.6. Error Response 2358 If the AS determines that the request cannot be issued for any 2359 reason, it responds to the RC with an error message. 2361 error (string) The error code. 2363 { 2365 "error": "user_denied" 2367 } 2369 The error code is one of the following, with additional values 2370 available in a registry TBD (Section 12): 2372 user_denied The RO denied the request. 2374 too_fast The RC did not respect the timeout in the wait response. 2376 unknown_request The request referenced an unknown ongoing access 2377 request. 2379 [[ See issue #79 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2380 issues/79) ]] 2382 3.7. Extending the Response 2384 Extensions to this specification MAY define additional fields for the 2385 grant response in a registry TBD (Section 12). 2387 [[ See issue #80 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2388 issues/80) ]] 2390 4. Interaction at the AS 2392 If the RC indicates that it is capable of driving interaction with 2393 the RO in its request (Section 2.5), and the AS determines that 2394 interaction is required and responds to one or more of the RC's 2395 interaction modes, the RC SHOULD initiate one of the returned 2396 interaction modes in the response (Section 3.3). 2398 When the RO is interacting with the AS, the AS MAY perform whatever 2399 actions it sees fit, including but not limited to: 2401 * authenticate the current user (who may be the RQ) as the RO 2403 * gather consent and authorization from the RO for access to 2404 requested resources and direct information 2406 * allow the RO to modify the parameters of the request (such as 2407 disallowing some requested resources or specifying an account or 2408 record) 2410 * provide warnings to the RO about potential attacks or negative 2411 effects of the requested information 2413 [[ See issue #81 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2414 issues/81) ]] 2416 4.1. Interaction at a Redirected URI 2418 When the RO is directed to the AS through the "redirect" 2419 (Section 3.3.1) mode, the AS can interact with the RO through their 2420 web browser to authenticate the user as an RO and gather their 2421 consent. Note that since the RC does not add any parameters to the 2422 URL, the AS MUST determine the grant request being referenced from 2423 the URL value itself. If the URL cannot be associated with a 2424 currently active request, the AS MUST display an error to the RO and 2425 MUST NOT attempt to redirect the RO back to any RC even if a callback 2426 is supplied (Section 2.5.3). 2428 The interaction URL MUST be reachable from the RO's browser, though 2429 note that the RO MAY open the URL on a separate device from the RC 2430 itself. The interaction URL MUST be accessible from an HTTP GET 2431 request, and MUST be protected by HTTPS or equivalent means. 2433 With this method, it is common for the RO to be the same party as the 2434 RQ, since the RC has to communicate the redirection URI to the RQ. 2436 4.2. Interaction at the User Code URI 2438 When the RO is directed to the AS through the "user_code" 2439 (Section 3.3.4) mode, the AS can interact with the RO through their 2440 web browser to collect the user code, authenticate the user as an RO, 2441 and gather their consent. Note that since the URL itself is static, 2442 the AS MUST determine the grant request being referenced from the 2443 user code value itself. If the user code cannot be associated with a 2444 currently active request, the AS MUST display an error to the RO and 2445 MUST NOT attempt to redirect the RO back to any RC even if a callback 2446 is supplied (Section 2.5.3). 2448 The user code URL MUST be reachable from the RO's browser, though 2449 note that the RO MAY open the URL on a separate device from the RC 2450 itself. The user code URL MUST be accessible from an HTTP GET 2451 request, and MUST be protected by HTTPS or equivalent means. 2453 While it is common for the RO to be the same party as the RQ, since 2454 the RC has to communicate the user code to someone, there are cases 2455 where the RQ and RO are separate parties and the authorization 2456 happens asynchronously. 2458 4.3. Interaction through an Application URI 2460 When the RC successfully launches an application through the "app" 2461 mode (Section 3.3.2), the AS interacts with the RO through that 2462 application to authenticate the user as the RO and gather their 2463 consent. The details of this interaction are out of scope for this 2464 specification. 2466 [[ See issue #82 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2467 issues/82) ]] 2469 4.4. Post-Interaction Completion 2471 Upon completing an interaction with the RO, if a "callback" 2472 (Section 3.3.3) mode is available with the current request, the AS 2473 MUST follow the appropriate method at the end of interaction to allow 2474 the RC to continue. If this mode is not available, the AS SHOULD 2475 instruct the RO to return to their RC software upon completion. Note 2476 that these steps still take place in most error cases, such as when 2477 the RO has denied access. This pattern allows the RC to potentially 2478 recover from the error state without restarting the request from 2479 scratch by modifying its request or providing additional information 2480 directly to the AS. 2482 [[ See issue #83 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2483 issues/83) ]] 2485 The AS MUST create an interaction reference and associate that 2486 reference with the current interaction and the underlying pending 2487 request. This value MUST be sufficiently random so as not to be 2488 guessable by an attacker. The interaction reference MUST be one- 2489 time-use. 2491 The AS MUST calculate a hash value based on the RC and AS nonces and 2492 the interaction reference, as described in Section 4.4.3. The RC 2493 will use this value to validate the return call from the AS. 2495 The AS then MUST send the hash and interaction reference based on the 2496 interaction finalization mode as described in the following sections. 2498 4.4.1. Completing Interaction with a Browser Redirect to the Callback 2499 URI 2501 When using the "callback" interaction mode (Section 3.3.3) with the 2502 "redirect" method, the AS signals to the RC that interaction is 2503 complete and the request can be continued by directing the RO (in 2504 their browser) back to the RC's callback URL sent in the callback 2505 request (Section 2.5.3.1). 2507 The AS secures this callback by adding the hash and interaction 2508 reference as query parameters to the RC's callback URL. 2510 hash REQUIRED. The interaction hash value as described in 2511 Section 4.4.3. 2513 interact_ref REQUIRED. The interaction reference generated for this 2514 interaction. 2516 The means of directing the RO to this URL are outside the scope of 2517 this specification, but common options include redirecting the RO 2518 from a web page and launching the system browser with the target URL. 2520 https://client.example.net/return/123455 2521 ?hash=p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R2HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A 2522 &interact_ref=4IFWWIKYBC2PQ6U56NL1 2524 When receiving the request, the RC MUST parse the query parameters to 2525 calculate and validate the hash value as described in Section 4.4.3. 2526 If the hash validates, the RC sends a continuation request to the AS 2527 as described in Section 5.1 using the interaction reference value 2528 received here. 2530 4.4.2. Completing Interaction with a Direct HTTP Request Callback 2532 When using the "callback" interaction mode (Section 3.3.3) with the 2533 "push" method, the AS signals to the RC that interaction is complete 2534 and the request can be continued by sending an HTTP POST request to 2535 the RC's callback URL sent in the callback request (Section 2.5.3.2). 2537 The entity message body is a JSON object consisting of the following 2538 two fields: 2540 hash (string) REQUIRED. The interaction hash value as described in 2541 Section 4.4.3. 2543 interact_ref (string) REQUIRED. The interaction reference generated 2544 for this interaction. 2546 POST /push/554321 HTTP/1.1 2547 Host: client.example.net 2548 Content-Type: application/json 2550 { 2551 "hash": "p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R2HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A", 2552 "interact_ref": "4IFWWIKYBC2PQ6U56NL1" 2553 } 2555 When receiving the request, the RC MUST parse the JSON object and 2556 validate the hash value as described in Section 4.4.3. If the hash 2557 validates, the RC sends a continuation request to the AS as described 2558 in Section 5.1 using the interaction reference value received here. 2560 4.4.3. Calculating the interaction hash 2562 The "hash" parameter in the request to the RC's callback URL ties the 2563 front channel response to an ongoing request by using values known 2564 only to the parties involved. This security mechanism allows the RC 2565 to protect itself against several kinds of session fixation and 2566 injection attacks. The AS MUST always provide this hash, and the RC 2567 MUST validate the hash when received. 2569 [[ See issue #84 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2570 issues/84) ]] 2572 To calculate the "hash" value, the party doing the calculation first 2573 takes the "nonce" value sent by the RC in the interaction section of 2574 the initial request (Section 2.5.3), the AS's nonce value from the 2575 callback response (Section 3.3.3), and the "interact_ref" sent to the 2576 RC's callback URL. These three values are concatenated to each other 2577 in this order using a single newline character as a separator between 2578 the fields. There is no padding or whitespace before or after any of 2579 the lines, and no trailing newline character. 2581 VJLO6A4CAYLBXHTR0KRO 2582 MBDOFXG4Y5CVJCX821LH 2583 4IFWWIKYBC2PQ6U56NL1 2585 The party then hashes this string with the appropriate algorithm 2586 based on the "hash_method" parameter of the "callback". If the 2587 "hash_method" value is not present in the RC's request, the algorithm 2588 defaults to "sha3". 2590 [[ See issue #56 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2591 issues/56) ]] 2593 4.4.3.1. SHA3-512 2595 The "sha3" hash method consists of hashing the input string with the 2596 512-bit SHA3 algorithm. The byte array is then encoded using URL 2597 Safe Base64 with no padding. The resulting string is the hash value. 2599 p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R2HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A 2601 4.4.3.2. SHA2-512 2603 The "sha2" hash method consists of hashing the input string with the 2604 512-bit SHA2 algorithm. The byte array is then encoded using URL 2605 Safe Base64 with no padding. The resulting string is the hash value. 2607 62SbcD3Xs7L40rjgALA-ymQujoh2LB2hPJyX9vlcr1H6ecChZ8BNKkG_HrOKP_Bpj84rh4mC9aE9x7HPBFcIHw 2609 5. Continuing a Grant Request 2611 While it is possible for the AS to return a Section 3 with all the 2612 RC's requested information (including access tokens (Section 3.2) and 2613 direct user information (Section 3.4)), it's more common that the AS 2614 and the RC will need to communicate several times over the lifetime 2615 of an access grant. This is often part of facilitating interaction 2616 (Section 4), but it could also be used to allow the AS and RC to 2617 continue negotiating the parameters of the original grant request 2618 (Section 2). 2620 To enable this ongoing negotiation, the AS returns a "continue" field 2621 in the response (Section 3.1) that contains information the RC needs 2622 to continue this process with another request, including a URI to 2623 access as well as an optional access token to use during the 2624 continued requests. 2626 When the RC makes any calls to the continuation URL, the RC MUST 2627 present proof of the most recent key associated with this ongoing 2628 request by signing the request as described in Section 8. The key in 2629 use will be either the key from the initial request (Section 2.3.2) 2630 or its most recent rotation. [[ See issue #85 (https://github.com/ 2631 ietf-wg-gnap/gnap-core-protocol/issues/85) ]] 2633 For example, here the RC makes a POST request and signs with detached 2634 JWS: 2636 POST /continue/80UPRY5NM33OMUKMKSKU HTTP/1.1 2637 Host: server.example.com 2638 Detached-JWS: ejy0... 2640 If the AS includes an "access_token" in the "continue" response in 2641 Section 3.1, the RC MUST include the access token the request as 2642 described in Section 7. Note that the access token is always bound 2643 to the RC's presented key (or its most recent rotation). 2645 For example, here the RC makes a POST request with the interaction 2646 reference, includes the access token, and signs with detached JWS: 2648 POST /continue HTTP/1.1 2649 Host: server.example.com 2650 Content-type: application/json 2651 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 2652 Detached-JWS: ejy0... 2654 { 2655 "interact_ref": "4IFWWIKYBC2PQ6U56NL1" 2656 } 2658 The AS MUST be able to tell from the RC's request which specific 2659 ongoing request is being accessed. Common methods for doing so 2660 include using a unique, unguessable URL for each continuation 2661 response, associating the request with the provided access token, or 2662 allowing only a single ongoing grant request for a given RC instance 2663 at a time. If the AS cannot determine a single active grant request 2664 to map the continuation request to, the AS MUST return an error. 2666 The ability to continue an already-started request allows the RC to 2667 perform several important functions, including presenting additional 2668 information from interaction, modifying the initial request, and 2669 getting the current state of the request. 2671 If a "wait" parameter was included in the continuation response 2672 (Section 3.1), the RC MUST NOT call the continuation URI prior to 2673 waiting the number of seconds indicated. If no "wait" period is 2674 indicated, the RC SHOULD wait at least 5 seconds If the RC does not 2675 respect the given wait period, the AS MUST return an error. [[ See 2676 issue #86 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2677 issues/86) ]] 2679 The response from the AS is a JSON object and MAY contain any of the 2680 fields described in Section 3, as described in more detail in the 2681 sections below. 2683 If the AS determines that the RC can make a further continuation 2684 request, the AS MUST include a new "continue" response (Section 3.1). 2685 If the continuation was previously bound to an access token, the new 2686 "continue" response MUST include a bound access token as well, and 2687 this token SHOULD be a new access token. If the AS does not return a 2688 new "continue" response, the RC MUST NOT make an additional 2689 continuation request. If a RC does so, the AS MUST return an error. 2690 [[ See issue #87 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2691 issues/87) ]] 2693 For continuation functions that require the RC to send a message 2694 body, the body MUST be a JSON object. 2696 5.1. Continuing After a Completed Interaction 2698 When the AS responds to the RC's "callback" parameter as in 2699 Section 4.4.1, this response includes an interaction reference. The 2700 RC MUST include that value as the field "interact_ref" in a POST 2701 request to the continuation URI. 2703 POST /continue/80UPRY5NM33OMUKMKSKU HTTP/1.1 2704 Host: server.example.com 2705 Content-type: application/json 2706 Detached-JWS: ejy0... 2708 { 2709 "interact_ref": "4IFWWIKYBC2PQ6U56NL1" 2710 } 2712 Since the interaction reference is a one-time-use value as described 2713 in Section 4.4.1, if the RC needs to make additional continuation 2714 calls after this request, the RC MUST NOT include the interaction 2715 reference. If the AS detects an RC submitting the same interaction 2716 reference multiple times, the AS MUST return an error and SHOULD 2717 invalidate the ongoing request. 2719 The Section 3 MAY contain any newly-created access tokens 2720 (Section 3.2) or newly-released subject claims (Section 3.4). The 2721 response MAY contain a new "continue" response (Section 3.1) as 2722 described above. The response SHOULD NOT contain any interaction 2723 responses (Section 3.3). [[ See issue #89 (https://github.com/ietf- 2724 wg-gnap/gnap-core-protocol/issues/89) ]] 2726 For example, if the request is successful in causing the AS to issue 2727 access tokens and release subject claims, the response could look 2728 like this: 2730 { 2731 "access_token": { 2732 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 2733 "key": false, 2734 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L" 2735 }, 2736 "subject": { 2737 "sub_ids": [ { 2738 "subject_type": "email", 2739 "email": "user@example.com", 2740 } ] 2741 } 2742 } 2744 With this example, the RC can not make an additional continuation 2745 request because a "continue" field is not included. 2747 [[ See issue #88 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2748 issues/88) ]] 2750 5.2. Continuing During Pending Interaction 2752 When the RC does not include a "callback" parameter, the RC will 2753 often need to poll the AS until the RO has authorized the request. 2754 To do so, the RC makes a POST request to the continuation URI as in 2755 Section 5.1, but does not include a message body. 2757 POST /continue HTTP/1.1 2758 Host: server.example.com 2759 Content-type: application/json 2760 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 2761 Detached-JWS: ejy0... 2763 The Section 3 MAY contain any newly-created access tokens 2764 (Section 3.2) or newly-released subject claims (Section 3.4). The 2765 response MAY contain a new "continue" response (Section 3.1) as 2766 described above. If a "continue" field is included, it SHOULD 2767 include a "wait" field to facilitate a reasonable polling rate by the 2768 RC. The response SHOULD NOT contain interaction responses 2769 (Section 3.3). 2771 For example, if the request has not yet been authorized by the RO, 2772 the AS could respond by telling the RC to make another continuation 2773 request in the future. In this example, a new, unique access token 2774 has been issued for the call, which the RC will use in its next 2775 continuation request. 2777 { 2778 "continue": { 2779 "access_token": { 2780 "value": "33OMUKMKSKU80UPRY5NM", 2781 "key": true 2782 }, 2783 "uri": "https://server.example.com/continue", 2784 "wait": 30 2785 } 2786 } 2788 [[ See issue #90 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2789 issues/90) ]] 2791 [[ See issue #91 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2792 issues/91) ]] 2794 If the request is successful in causing the AS to issue access tokens 2795 and release subject claims, the response could look like this 2796 example: 2798 { 2799 "access_token": { 2800 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 2801 "key": false, 2802 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L" 2803 }, 2804 "subject": { 2805 "sub_ids": [ { 2806 "subject_type": "email", 2807 "email": "user@example.com", 2808 } ] 2809 } 2810 } 2812 5.3. Modifying an Existing Request 2814 The RC might need to modify an ongoing request, whether or not tokens 2815 have already been issued or claims have already been released. In 2816 such cases, the RC makes an HTTP PATCH request to the continuation 2817 URI and includes any fields it needs to modify. Fields that aren't 2818 included in the request are considered unchanged from the original 2819 request. 2821 The RC MAY include the "resources" and "subject" fields as described 2822 in Section 2.1 and Section 2.2. Inclusion of these fields override 2823 any values in the initial request, which MAY trigger additional 2824 requirements and policies by the AS. For example, if the RC is 2825 asking for more access, the AS could require additional interaction 2826 with the RO to gather additional consent. If the RC is asking for 2827 more limited access, the AS could determine that sufficient 2828 authorization has been granted to the RC and return the more limited 2829 access rights immediately. [[ See issue #92 (https://github.com/ 2830 ietf-wg-gnap/gnap-core-protocol/issues/92) ]] 2832 The RC MAY include the "interact" field as described in Section 2.5. 2833 Inclusion of this field indicates that the RC is capable of driving 2834 interaction with the RO, and this field replaces any values from a 2835 previous request. The AS MAY respond to any of the interaction 2836 responses as described in Section 3.3, just like it would to a new 2837 request. 2839 The RC MAY include the "user" field as described in Section 2.4 to 2840 present new assertions or information about the RQ. [[ See issue #93 2841 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/93) ]] 2843 The RC MUST NOT include the "client" section of the request. [[ See 2844 issue #94 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2845 issues/94) ]] 2847 The RC MAY include post-interaction responses such as described in 2848 Section 5.1. [[ See issue #95 (https://github.com/ietf-wg-gnap/gnap- 2849 core-protocol/issues/95) ]] 2851 Modification requests MUST NOT alter previously-issued access tokens. 2852 Instead, any access tokens issued from a continuation are considered 2853 new, separate access tokens. The AS MAY revoke existing access 2854 tokens after a modification has occurred. [[ See issue #96 2855 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/96) ]] 2857 If the modified request can be granted immediately by the AS, the 2858 Section 3 MAY contain any newly-created access tokens (Section 3.2) 2859 or newly-released subject claims (Section 3.4). The response MAY 2860 contain a new "continue" response (Section 3.1) as described above. 2861 If interaction can occur, the response SHOULD contain interaction 2862 responses (Section 3.3) as well. 2864 For example, an RC initially requests a set of resources using 2865 references: 2867 POST /tx HTTP/1.1 2868 Host: server.example.com 2869 Content-type: application/json 2870 Detached-JWS: ejy0... 2872 { 2873 "resources": [ 2874 "read", "write" 2875 ], 2876 "interact": { 2877 "redirect": true, 2878 "callback": { 2879 "method": "redirect", 2880 "uri": "https://client.example.net/return/123455", 2881 "nonce": "LKLTI25DK82FX4T4QFZC" 2882 } 2883 }, 2884 "client": "987YHGRT56789IOLK" 2885 } 2887 Access is granted by the RO, and a token is issued by the AS. In its 2888 final response, the AS includes a "continue" field: 2890 { 2891 "continue": { 2892 "access_token": { 2893 "value": "80UPRY5NM33OMUKMKSKU", 2894 "key": true 2895 }, 2896 "uri": "https://server.example.com/continue", 2897 "wait": 30 2898 }, 2899 "access_token": ... 2900 } 2902 This allows the RC to make an eventual continuation call. The RC 2903 realizes that it no longer needs "write" access and therefore 2904 modifies its ongoing request, here asking for just "read" access 2905 instead of both "read" and "write" as before. 2907 PATCH /continue HTTP/1.1 2908 Host: server.example.com 2909 Content-type: application/json 2910 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 2911 Detached-JWS: ejy0... 2913 { 2914 "resources": [ 2915 "read" 2916 ] 2917 ... 2918 } 2920 The AS replaces the previous "resources" from the first request, 2921 allowing the AS to determine if any previously-granted consent 2922 already applies. In this case, the AS would likely determine that 2923 reducing the breadth of the requested access means that new access 2924 tokens can be issued to the RC. The AS would likely revoke 2925 previously-issued access tokens that had the greater access rights 2926 associated with them. 2928 { 2929 "continue": { 2930 "access_token": { 2931 "value": "M33OMUK80UPRY5NMKSKU", 2932 "key": true 2933 }, 2934 "uri": "https://server.example.com/continue", 2935 "wait": 30 2936 }, 2937 "access_token": ... 2938 } 2940 For another example, the RC initially requests read-only access but 2941 later needs to step up its access. The initial request could look 2942 like this example. 2944 POST /tx HTTP/1.1 2945 Host: server.example.com 2946 Content-type: application/json 2947 Detached-JWS: ejy0... 2949 { 2950 "resources": [ 2951 "read" 2952 ], 2953 "interact": { 2954 "redirect": true, 2955 "callback": { 2956 "method": "redirect", 2957 "uri": "https://client.example.net/return/123455", 2958 "nonce": "LKLTI25DK82FX4T4QFZC" 2959 } 2960 }, 2961 "client": "987YHGRT56789IOLK" 2962 } 2964 Access is granted by the RO, and a token is issued by the AS. In its 2965 final response, the AS includes a "continue" field: 2967 { 2968 "continue": { 2969 "access_token": { 2970 "value": "80UPRY5NM33OMUKMKSKU", 2971 "key": true 2972 }, 2973 "uri": "https://server.example.com/continue", 2974 "wait": 30 2975 }, 2976 "access_token": ... 2977 } 2979 This allows the RC to make an eventual continuation call. The RC 2980 later realizes that it now needs "write" access in addition to the 2981 "read" access. Since this is an expansion of what it asked for 2982 previously, the RC also includes a new interaction section in case 2983 the AS needs to interact with the RO again to gather additional 2984 authorization. Note that the RC's nonce and callback are different 2985 from the initial request. Since the original callback was already 2986 used in the initial exchange, and the callback is intended for one- 2987 time-use, a new one needs to be included in order to use the callback 2988 again. 2990 [[ See issue #97 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 2991 issues/97) ]] 2992 PATCH /continue HTTP/1.1 2993 Host: server.example.com 2994 Content-type: application/json 2995 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 2996 Detached-JWS: ejy0... 2998 { 2999 "resources": [ 3000 "read", "write" 3001 ], 3002 "interact": { 3003 "redirect": true, 3004 "callback": { 3005 "method": "redirect", 3006 "uri": "https://client.example.net/return/654321", 3007 "nonce": "K82FX4T4LKLTI25DQFZC" 3008 } 3009 } 3010 } 3012 From here, the AS can determine that the RC is asking for more than 3013 it was previously granted, but since the RC has also provided a 3014 mechanism to interact with the RO, the AS can use that to gather the 3015 additional consent. The protocol continues as it would with a new 3016 request. Since the old access tokens are good for a subset of the 3017 rights requested here, the AS might decide to not revoke them. 3018 However, any access tokens granted after this update process are new 3019 access tokens and do not modify the rights of existing access tokens. 3021 5.4. Getting the Current State of a Grant Request 3023 If the RC needs to get the current state of an ongoing grant request, 3024 it makes an HTTP GET request to the continuation URI. This request 3025 MUST NOT alter the grant request in any fashion, including causing 3026 the issuance of new access tokens or modification of interaction 3027 parameters. 3029 The AS MAY include existing access tokens and previously-released 3030 subject claims in the response. The AS MUST NOT issue a new access 3031 token or release a new subject claim in response to this request. 3033 GET /continue HTTP/1.1 3034 Host: server.example.com 3035 Content-type: application/json 3036 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 3037 Detached-JWS: ejy0... 3039 The response MAY include any fields described Section 3 that are 3040 applicable to this ongoing request, including the most recently 3041 issued access tokens, any released subject claims, and any currently 3042 active interaction modes. The response MAY contain a new "continue" 3043 response (Section 3.1) as described above. 3045 [[ See issue #98 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 3046 issues/98) ]] 3048 5.5. Canceling a Grant Request 3050 If the RC wishes to cancel an ongoing grant request, it makes an HTTP 3051 DELETE request to the continuation URI. 3053 DELETE /continue HTTP/1.1 3054 Host: server.example.com 3055 Content-type: application/json 3056 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 3057 Detached-JWS: ejy0... 3059 If the request is successfully cancelled, the AS responds with an 3060 HTTP 202. The AS MUST revoke all associated access tokens, if 3061 possible. 3063 6. Token Management 3065 If an access token response includes the "manage" parameter as 3066 described in Section 3.2.1, the RC MAY call this URL to manage the 3067 access token with any of the actions defined in the following 3068 sections. Other actions are undefined by this specification. 3070 The access token being managed acts as the access element for its own 3071 management API. The RC MUST present proof of an appropriate key 3072 along with the access token. 3074 If the token is sender-constrained (i.e., not a bearer token), it 3075 MUST be sent with the appropriate binding for the access token 3076 (Section 7). 3078 If the token is a bearer token, the RC MUST present proof of the same 3079 key identified in the initial request (Section 2.3.2) as described in 3080 Section 8. 3082 The AS MUST validate the proof and assure that it is associated with 3083 either the token itself or the RC the token was issued to, as 3084 appropriate for the token's presentation type. 3086 [[ See issue #99 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ 3087 issues/99) ]] 3089 6.1. Rotating the Access Token 3091 The RC makes an HTTP POST to the token management URI, sending the 3092 access token in the appropriate header and signing the request with 3093 the appropriate key. 3095 POST /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1 3096 Host: server.example.com 3097 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 3098 Detached-JWS: eyj0.... 3100 [[ See issue #100 (https://github.com/ietf-wg-gnap/gnap-core- 3101 protocol/issues/100) ]] 3103 The AS validates that the token presented is associated with the 3104 management URL, that the AS issued the token to the given RC, and 3105 that the presented key is appropriate to the token. 3107 If the access token has expired, the AS SHOULD honor the rotation 3108 request to the token management URL since it is likely that the RC is 3109 attempting to refresh the expired token. To support this, the AS MAY 3110 apply different lifetimes for the use of the token in management vs. 3111 its use at an RS. An AS MUST NOT honor a rotation request for an 3112 access token that has been revoked, either by the AS or by the RC 3113 through the token management URI (Section 6.2). 3115 If the token is validated and the key is appropriate for the request, 3116 the AS MUST invalidate the current access token associated with this 3117 URL, if possible, and return a new access token response as described 3118 in Section 3.2.1, unless the "multi_token" flag is specified in the 3119 request. The value of the access token MUST NOT be the same as the 3120 current value of the access token used to access the management API. 3121 The response MAY include an updated access token management URL as 3122 well, and if so, the RC MUST use this new URL to manage the new 3123 access token. [[ See issue #101 (https://github.com/ietf-wg-gnap/ 3124 gnap-core-protocol/issues/101) ]] 3126 [[ See issue #102 (https://github.com/ietf-wg-gnap/gnap-core- 3127 protocol/issues/102) ]] 3129 { 3130 "access_token": { 3131 "value": "FP6A8H6HY37MH13CK76LBZ6Y1UADG6VEUPEER5H2", 3132 "key": false, 3133 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L", 3134 "resources": [ 3135 { 3136 "type": "photo-api", 3137 "actions": [ 3138 "read", 3139 "write", 3140 "dolphin" 3141 ], 3142 "locations": [ 3143 "https://server.example.net/", 3144 "https://resource.local/other" 3145 ], 3146 "datatypes": [ 3147 "metadata", 3148 "images" 3149 ] 3150 }, 3151 "read", "dolphin-metadata" 3152 ] 3153 } 3154 } 3156 [[ See issue #103 (https://github.com/ietf-wg-gnap/gnap-core- 3157 protocol/issues/103) ]] 3159 6.2. Revoking the Access Token 3161 If the RC wishes to revoke the access token proactively, such as when 3162 a user indicates to the RC that they no longer wish for it to have 3163 access or the RC application detects that it is being uninstalled, 3164 the RC can use the token management URI to indicate to the AS that 3165 the AS should invalidate the access token for all purposes. 3167 The RC makes an HTTP DELETE request to the token management URI, 3168 presenting the access token and signing the request with the 3169 appropriate key. 3171 DELETE /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1 3172 Host: server.example.com 3173 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 3174 Detached-JWS: eyj0.... 3176 If the key presented is associated with the token (or the RC, in the 3177 case of a bearer token), the AS MUST invalidate the access token, if 3178 possible, and return an HTTP 204 response code. 3180 204 No Content 3182 Though the AS MAY revoke an access token at any time for any reason, 3183 the token management function is specifically for the RC's use. If 3184 the access token has already expired or has been revoked through 3185 other means, the AS SHOULD honor the revocation request to the token 3186 management URL as valid, since the end result is still the token not 3187 being usable. 3189 7. Using Access Tokens 3191 The method the RC uses to send an access token to the RS depends on 3192 the value of the "key" and "proof" parameters in the access token 3193 response (Section 3.2.1). 3195 If the key value is the boolean "false", the access token is a bearer 3196 token sent using the HTTP Header method defined in [RFC6750]. 3198 Authorization: Bearer OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 3200 The form parameter and query parameter methods of [RFC6750] MUST NOT 3201 be used. 3203 If the "key" value is the boolean "true", the access token MUST be 3204 sent to the RS using the same key and proofing mechanism that the RC 3205 used in its initial request. 3207 If the "key" value is an object, the value of the "proof" field 3208 within the key indicates the particular proofing mechanism to use. 3209 The access token is sent using the HTTP authorization scheme "GNAP" 3210 along with a key proof as described in Section 8 for the key bound to 3211 the access token. For example, a "jwsd"-bound access token is sent 3212 as follows: 3214 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 3215 Detached-JWS: eyj0.... 3217 [[ See issue #104 (https://github.com/ietf-wg-gnap/gnap-core- 3218 protocol/issues/104) ]] 3220 8. Binding Keys 3222 Any keys presented by the RC to the AS or RS MUST be validated as 3223 part of the request in which they are presented. The type of binding 3224 used is indicated by the proof parameter of the key section in the 3225 initial request Section 2.3.2. Values defined by this specification 3226 are as follows: 3228 jwsd A detached JWS signature header 3230 jws Attached JWS payload 3232 mtls Mutual TLS certificate verification 3234 dpop OAuth Demonstration of Proof-of-Possession key proof header 3236 httpsig HTTP Signing signature header 3238 oauthpop OAuth PoP key proof authentication header 3240 Additional proofing methods are defined by a registry TBD 3241 (Section 12). 3243 All key binding methods used by this specification MUST cover all 3244 relevant portions of the request, including anything that would 3245 change the nature of the request, to allow for secure validation of 3246 the request by the AS. Relevant aspects include the URI being 3247 called, the HTTP method being used, any relevant HTTP headers and 3248 values, and the HTTP message body itself. The recipient of the 3249 signed message MUST validate all components of the signed message to 3250 ensure that nothing has been tampered with or substituted in a way 3251 that would change the nature of the request. 3253 When used for delegation in GNAP, these key binding mechanisms allow 3254 the AS to ensure that the keys presented by the RC in the initial 3255 request are in control of the party calling any follow-up or 3256 continuation requests. To facilitate this requirement, all keys in 3257 the initial request Section 2.3.2 MUST be proved in all continuation 3258 requests Section 5 and token management requests Section 6, modulo 3259 any rotations on those keys over time that the AS knows about. The 3260 AS MUST validate all keys presented by the RC (Section 2.3.2) or 3261 referenced in an ongoing request for each call within that request. 3263 [[ See issue #105 (https://github.com/ietf-wg-gnap/gnap-core- 3264 protocol/issues/105) ]] 3266 When used to bind to an access token, the access token MUST be 3267 covered by the signature method. 3269 8.1. Detached JWS 3271 This method is indicated by "jwsd" in the "proof" field. A JWS 3272 [RFC7515] signature object is created as follows: 3274 The header of the JWS MUST contain the "kid" field of the key bound 3275 to this RC for this request. The JWS header MUST contain an "alg" 3276 field appropriate for the key identified by kid and MUST NOT be 3277 "none". The "b64" field MUST be set to "false" and the "crit" field 3278 MUST contain at least "b64" as specified in [RFC7797] 3280 To protect the request, the JWS header MUST contain the following 3281 additional fields. 3283 htm (string) The HTTP Method used to make this request, as an 3284 uppercase ASCII string. 3286 htu (string) The HTTP URI used for this request, including all path 3287 and query components. 3289 ts (integer) A timestamp of the request in integer seconds 3291 at_hash (string) When to bind a request to an access token, the 3292 access token hash value. Its value is the base64url encoding of 3293 the left-most half of the hash of the octets of the ASCII 3294 representation of the "access_token" value, where the hash 3295 algorithm used is the hash algorithm used in the "alg" header 3296 parameter of the JWS's JOSE Header. For instance, if the "alg" is 3297 "RS256", hash the "access_token" value with SHA-256, then take the 3298 left-most 128 bits and base64url encode them. 3300 [[ See issue #106 (https://github.com/ietf-wg-gnap/gnap-core- 3301 protocol/issues/106) ]] 3303 The payload of the JWS object is the serialized body of the request, 3304 and the object is signed according to detached JWS [RFC7797]. 3306 The RC presents the signature in the Detached-JWS HTTP Header field. 3307 [[ See issue #107 (https://github.com/ietf-wg-gnap/gnap-core- 3308 protocol/issues/107) ]] 3310 POST /tx HTTP/1.1 3311 Host: server.example.com 3312 Content-Type: application/json 3313 Detached-JWS: eyJiNjQiOmZhbHNlLCJhbGciOiJSUzI1NiIsImtpZCI6Inh5ei0xIn0. 3314 .Y287HMtaY0EegEjoTd_04a4GC6qV48GgVbGKOhHdJnDtD0VuUlVjLfwne8AuUY3U7e8 3315 9zUWwXLnAYK_BiS84M8EsrFvmv8yDLWzqveeIpcN5_ysveQnYt9Dqi32w6IOtAywkNUD 3316 ZeJEdc3z5s9Ei8qrYFN2fxcu28YS4e8e_cHTK57003WJu-wFn2TJUmAbHuqvUsyTb-nz 3317 YOKxuCKlqQItJF7E-cwSb_xULu-3f77BEU_vGbNYo5ZBa2B7UHO-kWNMSgbW2yeNNLbL 3318 C18Kv80GF22Y7SbZt0e2TwnR2Aa2zksuUbntQ5c7a1-gxtnXzuIKa34OekrnyqE1hmVW 3319 peQ 3321 { 3322 "resources": [ 3323 "dolphin-metadata" 3324 ], 3325 "interact": { 3326 "redirect": true, 3327 "callback": { 3328 "method": "redirect", 3329 "uri": "https://client.foo", 3330 "nonce": "VJLO6A4CAYLBXHTR0KRO" 3331 } 3332 }, 3333 "client": { 3334 "proof": "jwsd", 3335 "key": { 3336 "jwk": { 3337 "kty": "RSA", 3338 "e": "AQAB", 3339 "kid": "xyz-1", 3340 "alg": "RS256", 3341 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8 3342 xYJCNaOKNJn_Oz0YhdHbXTeWO5AoyspDWJbN5w_7bdWDxgpD-y6jnD1u9YhBOCWObNPF 3343 vpkTM8LC7SdXGRKx2k8Me2r_GssYlyRpqvpBlY5-ejCywKRBfctRcnhTTGNztbbDBUyD 3344 SWmFMVCHe5mXT4cL0BwrZC6S-uu-LAx06aKwQOPwYOGOslK8WPm1yGdkaA1uF_FpS6LS 3345 63WYPHi_Ap2B7_8Wbw4ttzbMS_doJvuDagW8A1Ip3fXFAHtRAcKw7rdI4_Xln66hJxFe 3346 kpdfWdiPQddQ6Y1cK2U3obvUg7w" 3347 } 3348 } 3349 "display": { 3350 "name": "My Client Display Name", 3351 "uri": "https://example.net/client" 3352 }, 3353 } 3354 } 3355 If the request being made does not have a message body, such as an 3356 HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated 3357 over an empty payload. 3359 When the server (AS or RS) receives the Detached-JWS header, it MUST 3360 parse its contents as a detached JWS object. The HTTP Body is used 3361 as the payload for purposes of validating the JWS, with no 3362 transformations. 3364 [[ See issue #108 (https://github.com/ietf-wg-gnap/gnap-core- 3365 protocol/issues/108) ]] 3367 8.2. Attached JWS 3369 This method is indicated by "jws" in the "proof" field. A JWS 3370 [RFC7515] signature object is created as follows: 3372 The header of the JWS MUST contain the "kid" field of the key bound 3373 to this RC for this request. The JWS header MUST contain an "alg" 3374 field appropriate for the key identified by kid and MUST NOT be 3375 "none". 3377 To protect the request, the JWS header MUST contain the following 3378 additional fields. 3380 htm (string) The HTTP Method used to make this request, as an 3381 uppercase ASCII string. 3383 htu (string) The HTTP URI used for this request, including all path 3384 and query components. 3386 ts (integer) A timestamp of the request in integer seconds 3388 at_hash (string) When to bind a request to an access token, the 3389 access token hash value. Its value is the base64url encoding of 3390 the left-most half of the hash of the octets of the ASCII 3391 representation of the "access_token" value, where the hash 3392 algorithm used is the hash algorithm used in the "alg" header 3393 parameter of the JWS's JOSE Header. For instance, if the "alg" is 3394 "RS256", hash the "access_token" value with SHA-256, then take the 3395 left-most 128 bits and base64url encode them. 3397 [[ See issue #107 (https://github.com/ietf-wg-gnap/gnap-core- 3398 protocol/issues/107) ]] 3400 The payload of the JWS object is the JSON serialized body of the 3401 request, and the object is signed according to JWS and serialized 3402 into compact form [RFC7515]. 3404 The RC presents the JWS as the body of the request along with a 3405 content type of "application/jose". The AS MUST extract the payload 3406 of the JWS and treat it as the request body for further processing. 3408 POST /tx HTTP/1.1 3409 Host: server.example.com 3410 Content-Type: application/jose 3412 eyJhbGciOiJSUzI1NiIsImtpZCI6IktBZ05wV2JSeXk5T 3413 WYycmlrbDQ5OExUaE1ydmtiWldIVlNRT0JDNFZIVTQiLC 3414 JodG0iOiJwb3N0IiwiaHR1IjoiL3R4IiwidHMiOjE2MDM 3415 4MDA3ODN9.eyJjYXBhYmlsaXRpZXMiOltdLCJjbGllbnQ 3416 iOnsia2V5Ijp7Imp3ayI6eyJrdHkiOiJSU0EiLCJlIjoi 3417 QVFBQiIsImtpZCI6IktBZ05wV2JSeXk5TWYycmlrbDQ5O 3418 ExUaE1ydmtiWldIVlNRT0JDNFZIVTQiLCJuIjoibGxXbU 3419 hGOFhBMktOTGRteE9QM2t4RDlPWTc2cDBTcjM3amZoejk 3420 0YTkzeG0yRk5xb1NQY1JaQVBkMGxxRFM4TjNVaWE1M2RC 3421 MjNaNTlPd1k0YnBNX1ZmOEdKdnZwdExXbnhvMVB5aG1Qc 3422 i1lY2RTQ1JRZFRjX1pjTUY0aFJWNDhxcWx2dUQwbXF0Y0 3423 RiSWtTQkR2Y2NKbVpId2ZUcERIaW5UOHR0dmNWUDhWa0F 3424 NQXE0a1ZhenhPcE1vSVJzb3lFcF9lQ2U1cFN3cUhvMGRh 3425 Q1dOS1ItRXBLbTZOaU90ZWRGNE91bXQ4TkxLVFZqZllnR 3426 khlQkRkQ2JyckVUZDR2Qk13RHRBbmpQcjNDVkN3d3gyYk 3427 FRVDZTbHhGSjNmajJoaHlJcHE3cGM4clppYjVqTnlYS3d 3428 mQnVrVFZZWm96a3NodC1Mb2h5QVNhS3BZVHA4THROWi13 3429 In0sInByb29mIjoiandzIn0sIm5hbWUiOiJNeSBGaXN0I 3430 ENsaWVudCIsInVyaSI6Imh0dHA6Ly9sb2NhbGhvc3QvY2 3431 xpZW50L2NsaWVudElEIn0sImludGVyYWN0Ijp7ImNhbGx 3432 iYWNrIjp7Im1ldGhvZCI6InJlZGlyZWN0Iiwibm9uY2Ui 3433 OiJkOTAyMTM4ODRiODQwOTIwNTM4YjVjNTEiLCJ1cmkiO 3434 iJodHRwOi8vbG9jYWxob3N0L2NsaWVudC9yZXF1ZXN0LW 3435 RvbmUifSwicmVkaXJlY3QiOnRydWV9LCJyZXNvdXJjZXM 3436 iOnsiYWN0aW9ucyI6WyJyZWFkIiwicHJpbnQiXSwibG9j 3437 YXRpb25zIjpbImh0dHA6Ly9sb2NhbGhvc3QvcGhvdG9zI 3438 l0sInR5cGUiOiJwaG90by1hcGkifSwic3ViamVjdCI6ey 3439 JzdWJfaWRzIjpbImlzcy1zdWIiLCJlbWFpbCJdfX0.LUy 3440 Z8_fERmxbYARq8kBYMwzcd8GnCAKAlo2ZSYLRRNAYWPrp 3441 2XGLJOvg97WK1idf_LB08OJmLVsCXxCvn9mgaAkYNL_Zj 3442 HcusBvY1mNo0E1sdTEr31CVKfC-6WrZCscb8YqE4Ayhh0 3443 Te8kzSng3OkLdy7xN4xeKuHzpF7yGsM52JZ0cBcTo6WrY 3444 EfGdr08AWQJ59ht72n3jTsmYNy9A6I4Wrvfgj3TNxmwYo 3445 jpBAicfjnzA1UVcNm9F_xiSz1_y2tdH7j5rVqBMQife-k 3446 9Ewk95vr3lurthenliYSNiUinVfoW1ybnaIBcTtP1_YCx 3447 g_h1y-B5uZEvYNGCuoCqa6IQ 3449 This example's JWS header decodes to: 3451 { 3452 "alg": "RS256", 3453 "kid": "KAgNpWbRyy9Mf2rikl498LThMrvkbZWHVSQOBC4VHU4", 3454 "htm": "post", 3455 "htu": "/tx", 3456 "ts": 1603800783 3457 } 3459 And the JWS body decodes to: 3461 { 3462 "capabilities": [], 3463 "client": { 3464 "key": { 3465 "jwk": { 3466 "kty": "RSA", 3467 "e": "AQAB", 3468 "kid": "KAgNpWbRyy9Mf2rikl498LThMrvkbZWHVSQOBC4VHU4", 3469 "n": "llWmHF8XA2KNLdmxOP3kxD9OY76p0Sr37jfhz94a93xm2FNqoSPc 3470 RZAPd0lqDS8N3Uia53dB23Z59OwY4bpM_Vf8GJvvptLWnxo1PyhmPr-ecd 3471 SCRQdTc_ZcMF4hRV48qqlvuD0mqtcDbIkSBDvccJmZHwfTpDHinT8ttvcV 3472 P8VkAMAq4kVazxOpMoIRsoyEp_eCe5pSwqHo0daCWNKR-EpKm6NiOtedF4 3473 Oumt8NLKTVjfYgFHeBDdCbrrETd4vBMwDtAnjPr3CVCwwx2bAQT6SlxFJ3 3474 fj2hhyIpq7pc8rZib5jNyXKwfBukTVYZozksht-LohyASaKpYTp8LtNZ-w" 3475 }, 3476 "proof": "jws" 3477 }, 3478 "name": "My Fist Client", 3479 "uri": "http://localhost/client/clientID" 3480 }, 3481 "interact": { 3482 "callback": { 3483 "method": "redirect", 3484 "nonce": "d90213884b840920538b5c51", 3485 "uri": "http://localhost/client/request-done" 3486 }, 3487 "redirect": true 3488 }, 3489 "resources": { 3490 "actions": [ 3491 "read", 3492 "print" 3493 ], 3494 "locations": [ 3495 "http://localhost/photos" 3496 ], 3497 "type": "photo-api" 3498 }, 3499 "subject": { 3500 "sub_ids": [ 3501 "iss_sub", 3502 "email" 3503 ] 3504 } 3505 } 3506 If the request being made does not have a message body, such as an 3507 HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated 3508 over an empty payload and passed in the "Detached-JWS" header as 3509 described in Section 8.1. 3511 [[ See issue #109 (https://github.com/ietf-wg-gnap/gnap-core- 3512 protocol/issues/109) ]] 3514 8.3. Mutual TLS 3516 This method is indicated by "mtls" in the "proof" field. The RC 3517 presents its client certificate during TLS negotiation with the 3518 server (either AS or RS). The AS or RS takes the thumbprint of the 3519 client certificate presented during mutual TLS negotiation and 3520 compares that thumbprint to the thumbprint presented by the RC 3521 application as described in [RFC8705] section 3. 3523 POST /tx HTTP/1.1 3524 Host: server.example.com 3525 Content-Type: application/json 3526 SSL_CLIENT_CERT: MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmjE3MDUGA1UEAwwuQmVz 3527 cG9rZSBFbmdpbmVlcmluZyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTELMAkG 3528 A1UECAwCTUExCzAJBgNVBAYTAlVTMRkwFwYJKoZIhvcNAQkBFgpjYUBic3BrLmlv 3529 MRwwGgYDVQQKDBNCZXNwb2tlIEVuZ2luZWVyaW5nMQwwCgYDVQQLDANNVEkwHhcN 3530 MTkwNDEwMjE0MDI5WhcNMjQwNDA4MjE0MDI5WjB8MRIwEAYDVQQDDAlsb2NhbGhv 3531 c3QxCzAJBgNVBAgMAk1BMQswCQYDVQQGEwJVUzEgMB4GCSqGSIb3DQEJARYRdGxz 3532 Y2xpZW50QGJzcGsuaW8xHDAaBgNVBAoME0Jlc3Bva2UgRW5naW5lZXJpbmcxDDAK 3533 BgNVBAsMA01USTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmaXQHb 3534 s/wc1RpsQ6Orzf6rN+q2ijaZbQxD8oi+XaaN0P/gnE13JqQduvdq77OmJ4bQLokq 3535 sd0BexnI07Njsl8nkDDYpe8rNve5TjyUDCfbwgS7U1CluYenXmNQbaYNDOmCdHww 3536 UjV4kKREg6DGAx22Oq7+VHPTeeFgyw4kQgWRSfDENWY3KUXJlb/vKR6lQ+aOJytk 3537 vj8kVZQtWupPbvwoJe0na/ISNAOhL74w20DWWoDKoNltXsEtflNljVoi5nqsmZQc 3538 jfjt6LO0T7O1OX3Cwu2xWx8KZ3n/2ocuRqKEJHqUGfeDtuQNt6Jz79v/OTr8puLW 3539 aD+uyk6NbtGjoQsCAwEAAaOBiTCBhjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DBs 3540 BgNVHREEZTBjgglsb2NhbGhvc3SCD3Rsc2NsaWVudC5sb2NhbIcEwKgBBIERdGxz 3541 Y2xpZW50QGJzcGsuaW+GF2h0dHA6Ly90bHNjbGllbnQubG9jYWwvhhNzc2g6dGxz 3542 Y2xpZW50LmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IBAQCKKv8WlLrT4Z5NazaUrYtl 3543 TF+2v0tvZBQ7qzJQjlOqAcvxry/d2zyhiRCRS/v318YCJBEv4Iq2W3I3JMMyAYEe 3544 2573HzT7rH3xQP12yZyRQnetdiVM1Z1KaXwfrPDLs72hUeELtxIcfZ0M085jLboX 3545 hufHI6kqm3NCyCCTihe2ck5RmCc5l2KBO/vAHF0ihhFOOOby1v6qbPHQcxAU6rEb 3546 907/p6BW/LV1NCgYB1QtFSfGxowqb9FRIMD2kvMSmO0EMxgwZ6k6spa+jk0IsI3k 3547 lwLW9b+Tfn/daUbIDctxeJneq2anQyU2znBgQl6KILDSF4eaOqlBut/KNZHHazJh 3549 { 3550 "resources": [ 3551 "dolphin-metadata" 3552 ], 3553 "interact": { 3554 "redirect": true, 3555 "callback": { 3556 "method": "redirect", 3557 "uri": "https://client.foo", 3558 "nonce": "VJLO6A4CAYLBXHTR0KRO" 3559 } 3560 }, 3561 "client": { 3562 "display": { 3563 "name": "My Client Display Name", 3564 "uri": "https://example.net/client" 3565 }, 3566 "key": { 3567 "proof": "mtls", 3568 "cert": "MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmjE3 3569 MDUGA1UEAwwuQmVzcG9rZSBFbmdpbmVlcmluZyBSb290IENlcnRpZmljYXRlIEF1d 3570 Ghvcml0eTELMAkGA1UECAwCTUExCzAJBgNVBAYTAlVTMRkwFwYJKoZIhvcNAQkBFg 3571 pjYUBic3BrLmlvMRwwGgYDVQQKDBNCZXNwb2tlIEVuZ2luZWVyaW5nMQwwCgYDVQQ 3572 LDANNVEkwHhcNMTkwNDEwMjE0MDI5WhcNMjQwNDA4MjE0MDI5WjB8MRIwEAYDVQQD 3573 DAlsb2NhbGhvc3QxCzAJBgNVBAgMAk1BMQswCQYDVQQGEwJVUzEgMB4GCSqGSIb3D 3574 QEJARYRdGxzY2xpZW50QGJzcGsuaW8xHDAaBgNVBAoME0Jlc3Bva2UgRW5naW5lZX 3575 JpbmcxDDAKBgNVBAsMA01USTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggE 3576 BAMmaXQHbs/wc1RpsQ6Orzf6rN+q2ijaZbQxD8oi+XaaN0P/gnE13JqQduvdq77Om 3577 J4bQLokqsd0BexnI07Njsl8nkDDYpe8rNve5TjyUDCfbwgS7U1CluYenXmNQbaYND 3578 OmCdHwwUjV4kKREg6DGAx22Oq7+VHPTeeFgyw4kQgWRSfDENWY3KUXJlb/vKR6lQ+ 3579 aOJytkvj8kVZQtWupPbvwoJe0na/ISNAOhL74w20DWWoDKoNltXsEtflNljVoi5nq 3580 smZQcjfjt6LO0T7O1OX3Cwu2xWx8KZ3n/2ocuRqKEJHqUGfeDtuQNt6Jz79v/OTr8 3581 puLWaD+uyk6NbtGjoQsCAwEAAaOBiTCBhjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4 3582 DBsBgNVHREEZTBjgglsb2NhbGhvc3SCD3Rsc2NsaWVudC5sb2NhbIcEwKgBBIERdG 3583 xzY2xpZW50QGJzcGsuaW+GF2h0dHA6Ly90bHNjbGllbnQubG9jYWwvhhNzc2g6dGx 3584 zY2xpZW50LmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IBAQCKKv8WlLrT4Z5NazaUrYtl 3585 TF+2v0tvZBQ7qzJQjlOqAcvxry/d2zyhiRCRS/v318YCJBEv4Iq2W3I3JMMyAYEe2 3586 573HzT7rH3xQP12yZyRQnetdiVM1Z1KaXwfrPDLs72hUeELtxIcfZ0M085jLboXhu 3587 fHI6kqm3NCyCCTihe2ck5RmCc5l2KBO/vAHF0ihhFOOOby1v6qbPHQcxAU6rEb907 3588 /p6BW/LV1NCgYB1QtFSfGxowqb9FRIMD2kvMSmO0EMxgwZ6k6spa+jk0IsI3klwLW 3589 9b+Tfn/daUbIDctxeJneq2anQyU2znBgQl6KILDSF4eaOqlBut/KNZHHazJh" 3590 } 3591 } 3593 [[ See issue #110 (https://github.com/ietf-wg-gnap/gnap-core- 3594 protocol/issues/110) ]] 3596 8.4. Demonstration of Proof-of-Possession (DPoP) 3598 This method is indicated by "dpop" in the "proof" field. The RC 3599 creates a Demonstration of Proof-of-Possession signature header as 3600 described in [I-D.ietf-oauth-dpop] section 2. In addition to the 3601 required fields, the DPoP body MUST also contain a digest of the 3602 request body: 3604 digest (string) Digest of the request body as the value of the 3605 Digest header defined in [RFC3230]. 3607 POST /tx HTTP/1.1 3608 Host: server.example.com 3609 Content-Type: application/json 3610 DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IlJTMjU2IiwiandrIjp7Imt0eSI6Il 3611 JTQSIsImUiOiJBUUFCIiwia2lkIjoieHl6LWNsaWVudCIsImFsZyI6IlJTMjU2Iiwibi 3612 I6Inp3Q1RfM2J4LWdsYmJIcmhlWXBZcFJXaVk5SS1uRWFNUnBablJySWpDczZiX2VteV 3613 RrQmtEREVqU3lzaTM4T0M3M2hqMS1XZ3hjUGRLTkdaeUlvSDNRWmVuMU1LeXloUXBMSk 3614 cxLW9MTkxxbTdwWFh0ZFl6U2RDOU8zLW9peXk4eWtPNFlVeU5aclJSZlBjaWhkUUNiT1 3615 9PQzhRdWdtZzlyZ05ET1NxcHBkYU5lYXMxb3Y5UHhZdnhxcnoxLThIYTdna0QwMFlFQ1 3616 hIYUIwNXVNYVVhZEhxLU9fV0l2WVhpY2c2STVqNlM0NFZOVTY1VkJ3dS1BbHluVHhRZE 3617 1BV1AzYll4VlZ5NnAzLTdlVEpva3ZqWVRGcWdEVkRaOGxVWGJyNXlDVG5SaG5oSmd2Zj 3618 NWakRfbWFsTmU4LXRPcUs1T1NEbEhUeTZnRDlOcWRHQ20tUG0zUSJ9fQ.eyJodHRwX21 3619 ldGhvZCI6IlBPU1QiLCJodHRwX3VyaSI6Imh0dHA6XC9cL2hvc3QuZG9ja2VyLmludGV 3620 ybmFsOjk4MzRcL2FwaVwvYXNcL3RyYW5zYWN0aW9uIiwiaWF0IjoxNTcyNjQyNjEzLCJ 3621 qdGkiOiJIam9IcmpnbTJ5QjR4N2pBNXl5RyJ9.aUhftvfw2NoW3M7durkopReTvONng1 3622 fOzbWjAlKNSLL0qIwDgfG39XUyNvwQ23OBIwe6IuvTQ2UBBPklPAfJhDTKd8KHEAfidN 3623 B-LzUOzhDetLg30yLFzIpcEBMLCjb0TEsmXadvxuNkEzFRL-Q-QCg0AXSF1h57eAqZV8 3624 SYF4CQK9OUV6fIWwxLDd3cVTx83MgyCNnvFlG_HDyim1Xx-rxV4ePd1vgDeRubFb6QWj 3625 iKEO7vj1APv32dsux67gZYiUpjm0wEZprjlG0a07R984KLeK1XPjXgViEwEdlirUmpVy 3626 T9tyEYqGrTfm5uautELgMls9sgSyE929woZ59elg 3628 { 3629 "resources": [ 3630 "dolphin-metadata" 3631 ], 3632 "interact": { 3633 "redirect": true, 3634 "callback": { 3635 "method": "redirect", 3636 "uri": "https://client.foo", 3637 "nonce": "VJLO6A4CAYLBXHTR0KRO" 3638 } 3639 }, 3640 "client": { 3641 "display": { 3642 "name": "My Client Display Name", 3643 "uri": "https://example.net/client" 3645 }, 3646 "proof": "dpop", 3647 "key": { 3648 "jwk": { 3649 "kty": "RSA", 3650 "e": "AQAB", 3651 "kid": "xyz-1", 3652 "alg": "RS256", 3653 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xYJ 3654 CCNaOKNJn_Oz0YhdHbXTeWO5AoyspDWJbN5w_7bdWDxgpD-y6jnD1u9YhBOCWObNPFvpkTM 3655 8LC7SdXGRKx2k8Me2r_GssYlyRpqvpBlY5-ejCywKRBfctRcnhTTGNztbbDBUyDSWmFMVCH 3656 e5mXT4cL0BwrZC6S-uu-LAx06aKwQOPwYOGOslK8WPm1yGdkaA1uF_FpS6LS63WYPHi_Ap2 3657 B7_8Wbw4ttzbMS_doJvuDagW8A1Ip3fXFAHtRAcKw7rdI4_Xln66hJxFekpdfWdiPQddQ6Y 3658 1cK2U3obvUg7w" 3659 } 3660 } 3661 } 3662 } 3664 [[ See issue #111 (https://github.com/ietf-wg-gnap/gnap-core- 3665 protocol/issues/111) ]] 3667 8.5. HTTP Signing 3669 This method is indicated by "httpsig" in the "proof" field. The RC 3670 creates an HTTP Signature header as described in 3671 [I-D.ietf-httpbis-message-signatures] section 4. The RC MUST 3672 calculate and present the Digest header as defined in [RFC3230] and 3673 include this header in the signature. 3675 POST /tx HTTP/1.1 3676 Host: server.example.com 3677 Content-Type: application/json 3678 Content-Length: 716 3679 Signature: keyId="xyz-client", algorithm="rsa-sha256", 3680 headers="(request-target) digest content-length", 3681 signature="TkehmgK7GD/z4jGkmcHS67cjVRgm3zVQNlNrrXW32Wv7d 3682 u0VNEIVI/dMhe0WlHC93NP3ms91i2WOW5r5B6qow6TNx/82/6W84p5jqF 3683 YuYfTkKYZ69GbfqXkYV9gaT++dl5kvZQjVk+KZT1dzpAzv8hdk9nO87Xi 3684 rj7qe2mdAGE1LLc3YvXwNxuCQh82sa5rXHqtNT1077fiDvSVYeced0UEm 3685 rWwErVgr7sijtbTohC4FJLuJ0nG/KJUcIG/FTchW9rd6dHoBnY43+3Dzj 3686 CIthXpdH5u4VX3TBe6GJDO6Mkzc6vB+67OWzPwhYTplUiFFV6UZCsDEeu 3687 Sa/Ue1yLEAMg=="]} 3688 Digest: SHA=oZz2O3kg5SEFAhmr0xEBbc4jEfo= 3690 { 3691 "resources": [ 3692 "dolphin-metadata" 3694 ], 3695 "interact": { 3696 "redirect": true, 3697 "callback": { 3698 "method": "push", 3699 "uri": "https://client.foo", 3700 "nonce": "VJLO6A4CAYLBXHTR0KRO" 3701 } 3702 }, 3703 "client": { 3704 "display": { 3705 "name": "My Client Display Name", 3706 "uri": "https://example.net/client" 3707 }, 3708 "proof": "httpsig", 3709 "key": { 3710 "jwk": { 3711 "kty": "RSA", 3712 "e": "AQAB", 3713 "kid": "xyz-1", 3714 "alg": "RS256", 3715 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_J 3716 tffXyaSx8xYJCCNaOKNJn_Oz0YhdHbXTeWO5AoyspDWJbN5w_7bdWDxgpD- 3717 y6jnD1u9YhBOCWObNPFvpkTM8LC7SdXGRKx2k8Me2r_GssYlyRpqvpBlY5- 3718 ejCywKRBfctRcnhTTGNztbbDBUyDSWmFMVCHe5mXT4cL0BwrZC6S-uu-LAx 3719 06aKwQOPwYOGOslK8WPm1yGdkaA1uF_FpS6LS63WYPHi_Ap2B7_8Wbw4ttz 3720 bMS_doJvuDagW8A1Ip3fXFAHtRAcKw7rdI4_Xln66hJxFekpdfWdiPQddQ6 3721 Y1cK2U3obvUg7w" 3722 } 3723 } 3724 } 3725 } 3727 When used to present an access token as in Section 7, the 3728 Authorization header MUST be included in the signature. 3730 8.6. OAuth Proof of Possession (PoP) 3732 This method is indicated by "oauthpop" in the "proof" field. The RC 3733 creates an HTTP Authorization PoP header as described in 3734 [I-D.ietf-oauth-signed-http-request] section 4, with the following 3735 additional requirements: 3737 * The "at" (access token) field MUST be omitted unless this method 3738 is being used in conjunction with an access token as in Section 7. 3739 [[ See issue #112 (https://github.com/ietf-wg-gnap/gnap-core- 3740 protocol/issues/112) ]] 3742 * The "b" (body hash) field MUST be calculated and supplied, unless 3743 there is no entity body (such as a GET, OPTIONS, or DELETE 3744 request). 3746 * All components of the URL MUST be calculated and supplied 3748 * The m (method) field MUST be supplied 3750 POST /tx HTTP/1.1 3751 Host: server.example.com 3752 Content-Type: application/json 3753 PoP: eyJhbGciOiJSUzI1NiIsImp3ayI6eyJrdHkiOiJSU0EiLCJlIjoi 3754 QVFBQiIsImtpZCI6Inh5ei1jbGllbnQiLCJhbGciOiJSUzI1NiIsIm4iO 3755 iJ6d0NUXzNieC1nbGJiSHJoZVlwWXBSV2lZOUktbkVhTVJwWm5ScklqQ3 3756 M2Yl9lbXlUa0JrRERFalN5c2kzOE9DNzNoajEtV2d4Y1BkS05HWnlJb0g 3757 zUVplbjFNS3l5aFFwTEpHMS1vTE5McW03cFhYdGRZelNkQzlPMy1vaXl5 3758 OHlrTzRZVXlOWnJSUmZQY2loZFFDYk9fT0M4UXVnbWc5cmdORE9TcXBwZ 3759 GFOZWFzMW92OVB4WXZ4cXJ6MS04SGE3Z2tEMDBZRUNYSGFCMDV1TWFVYW 3760 RIcS1PX1dJdllYaWNnNkk1ajZTNDRWTlU2NVZCd3UtQWx5blR4UWRNQVd 3761 QM2JZeFZWeTZwMy03ZVRKb2t2allURnFnRFZEWjhsVVhicjV5Q1RuUmhu 3762 aEpndmYzVmpEX21hbE5lOC10T3FLNU9TRGxIVHk2Z0Q5TnFkR0NtLVBtM 3763 1EifX0.eyJwIjoiXC9hcGlcL2FzXC90cmFuc2FjdGlvbiIsImIiOiJxa0 3764 lPYkdOeERhZVBTZnc3NnFjamtqSXNFRmxDb3g5bTU5NFM0M0RkU0xBIiw 3765 idSI6Imhvc3QuZG9ja2VyLmludGVybmFsIiwiaCI6W1siQWNjZXB0Iiwi 3766 Q29udGVudC1UeXBlIiwiQ29udGVudC1MZW5ndGgiXSwiVjQ2OUhFWGx6S 3767 k9kQTZmQU5oMmpKdFhTd3pjSGRqMUloOGk5M0h3bEVHYyJdLCJtIjoiUE 3768 9TVCIsInRzIjoxNTcyNjQyNjEwfQ.xyQ47qy8bu4fyK1T3Ru1Sway8wp6 3769 5rfAKnTQQU92AUUU07I2iKoBL2tipBcNCC5zLH5j_WUyjlN15oi_lLHym 3770 fPdzihtt8_Jibjfjib5J15UlifakjQ0rHX04tPal9PvcjwnyZHFcKn-So 3771 Y3wsARn-gGwxpzbsPhiKQP70d2eG0CYQMA6rTLslT7GgdQheelhVFW29i 3772 27NcvqtkJmiAG6Swrq4uUgCY3zRotROkJ13qo86t2DXklV-eES4-2dCxf 3773 cWFkzBAr6oC4Qp7HnY_5UT6IWkRJt3efwYprWcYouOVjtRan3kEtWkaWr 3774 G0J4bPVnTI5St9hJYvvh7FE8JirIg 3776 { 3777 "resources": [ 3778 "dolphin-metadata" 3779 ], 3780 "interact": { 3781 "redirect": true, 3782 "callback": { 3783 "method": "redirect", 3784 "uri": "https://client.foo", 3785 "nonce": "VJLO6A4CAYLBXHTR0KRO" 3786 } 3787 }, 3788 "client": { 3789 "display": { 3790 "name": "My Client Display Name", 3791 "uri": "https://example.net/client" 3792 }, 3793 "proof": "oauthpop", 3794 "key": { 3795 "jwk": { 3796 "kty": "RSA", 3797 "e": "AQAB", 3798 "kid": "xyz-1", 3799 "alg": "RS256", 3800 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_J 3801 tffXyaSx8xYJCCNaOKNJn_Oz0YhdHbXTeWO5AoyspDWJbN5w_7bdWDxgpD- 3802 y6jnD1u9YhBOCWObNPFvpkTM8LC7SdXGRKx2k8Me2r_GssYlyRpqvpBlY5- 3803 ejCywKRBfctRcnhTTGNztbbDBUyDSWmFMVCHe5mXT4cL0BwrZC6S-uu-LAx 3804 06aKwQOPwYOGOslK8WPm1yGdkaA1uF_FpS6LS63WYPHi_Ap2B7_8Wbw4ttz 3805 bMS_doJvuDagW8A1Ip3fXFAHtRAcKw7rdI4_Xln66hJxFekpdfWdiPQddQ6 3806 Y1cK2U3obvUg7w" 3807 } 3808 } 3809 } 3810 } 3812 [[ See issue #113 (https://github.com/ietf-wg-gnap/gnap-core- 3813 protocol/issues/113) ]] 3815 9. Discovery 3817 By design, the protocol minimizes the need for any pre-flight 3818 discovery. To begin a request, the RC only needs to know the 3819 endpoint of the AS and which keys it will use to sign the request. 3820 Everything else can be negotiated dynamically in the course of the 3821 protocol. 3823 However, the AS can have limits on its allowed functionality. If the 3824 RC wants to optimize its calls to the AS before making a request, it 3825 MAY send an HTTP OPTIONS request to the grant request endpoint to 3826 retrieve the server's discovery information. The AS MUST respond 3827 with a JSON document containing the following information: 3829 grant_request_endpoint (string) REQUIRED. The full URL of the AS's 3830 grant request endpoint. This MUST match the URL the RC used to 3831 make the discovery request. 3833 capabilities (array of strings) OPTIONAL. A list of the AS's 3834 capabilities. The values of this result MAY be used by the RC in 3835 the capabilities section (Section 2.6) of the request. 3837 interaction_methods (array of strings) OPTIONAL. A list of the AS's 3838 interaction methods. The values of this list correspond to the 3839 possible fields in the interaction section (Section 2.5) of the 3840 request. 3842 key_proofs (array strings) OPTIONAL. A list of the AS's supported 3843 key proofing mechanisms. The values of this list correspond to 3844 possible values of the "proof" field of the key section 3845 (Section 2.3.2) of the request. 3847 sub_ids (array of strings) OPTIONAL. A list of the AS's supported 3848 identifiers. The values of this list correspond to possible 3849 values of the subject identifier section (Section 2.2) of the 3850 request. 3852 assertions (array of strings) OPTIONAL. A list of the AS's 3853 supported assertion formats. The values of this list correspond 3854 to possible values of the subject assertion section (Section 2.2) 3855 of the request. 3857 The information returned from this method is for optimization 3858 purposes only. The AS MAY deny any request, or any portion of a 3859 request, even if it lists a capability as supported. For example, a 3860 given RC can be registered with the "mtls" key proofing mechanism, 3861 but the AS also returns other proofing methods, then the AS will deny 3862 a request from that RC using a different proofing mechanism. 3864 10. Resource Servers 3866 In some deployments, a resource server will need to be able to call 3867 the AS for a number of functions. 3869 [[ See issue #114 (https://github.com/ietf-wg-gnap/gnap-core- 3870 protocol/issues/114) ]] 3872 10.1. Introspecting a Token 3874 When the RS receives an access token, it can call the introspection 3875 endpoint at the AS to get token information. [[ See issue #115 3876 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/115) ]] 3878 +------+ +------+ +------+ 3879 | RC |--(1)->| RS | | AS | 3880 | | | |--(2)->| | 3881 | | | |<-(3)--| | 3882 | | | | +------+ 3883 | |<-(4)--| | 3884 +------+ +------+ 3885 1. The RC calls the RS with its access token. 3887 2. The RS introspects the access token value at the AS. The RS 3888 signs the request with its own key (not the RC's key or the 3889 token's key). 3891 3. The AS validates the token value and the RC's request and returns 3892 the introspection response for the token. 3894 4. The RS fulfills the request from the RC. 3896 The RS signs the request with its own key and sends the access token 3897 as the body of the request. 3899 POST /introspect HTTP/1.1 3900 Host: server.example.com 3901 Content-type: application/json 3902 Detached-JWS: ejy0... 3904 { 3905 "access_token": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 3906 } 3908 The AS responds with a data structure describing the token's current 3909 state and any information the RS would need to validate the token's 3910 presentation, such as its intended proofing mechanism and key 3911 material. 3913 Content-type: application/json 3915 { 3916 "active": true, 3917 "resources": [ 3918 "dolphin-metadata", "some other thing" 3919 ], 3920 "client": { 3921 "key": { 3922 "proof": "httpsig", 3923 "jwk": { 3924 "kty": "RSA", 3925 "e": "AQAB", 3926 "kid": "xyz-1", 3927 "alg": "RS256", 3928 "n": "kOB5rR4Jv0GMeL...." 3929 } 3930 } 3931 } 3932 } 3934 10.2. Deriving a downstream token 3936 Some architectures require an RS to act as an RC and request a 3937 derived access token for a secondary RS. This internal token is 3938 issued in the context of the incoming access token. 3940 +------+ +-------+ +------+ +-------+ 3941 | RC |--(1)->| RS1 | | AS | | RS2 | 3942 | | | |--(2)->| | | | 3943 | | | |<-(3)--| | | | 3944 | | | | +------+ | | 3945 | | | | | | 3946 | | | |-----------(4)------->| | 3947 | | | |<----------(5)--------| | 3948 | |<-(6)--| | | | 3949 +------+ +-------+ +-------+ 3951 1. The RC calls RS1 with an access token. 3953 2. RS1 presents that token to the AS to get a derived token for use 3954 at RS2. RS1 indicates that it has no ability to interact with 3955 the RO. RS1 signs its request with its own key, not the token's 3956 key or the RC's key. 3958 3. The AS returns a derived token to RS1 for use at RS2. 3960 4. RS1 calls RS2 with the token from (3). 3962 5. RS2 fulfills the call from RS1. 3964 6. RS1 fulfills the call from RC. 3966 If the RS needs to derive a token from one presented to it, it can 3967 request one from the AS by making a token request as described in 3968 Section 2 and presenting the existing access token's value in the 3969 "existing_access_token" field. 3971 The RS MUST identify itself with its own key and sign the request. 3973 [[ See issue #116 (https://github.com/ietf-wg-gnap/gnap-core- 3974 protocol/issues/116) ]] 3976 POST /tx HTTP/1.1 3977 Host: server.example.com 3978 Content-type: application/json 3979 Detached-JWS: ejy0... 3981 { 3982 "resources": [ 3983 { 3984 "actions": [ 3985 "read", 3986 "write", 3987 "dolphin" 3988 ], 3989 "locations": [ 3990 "https://server.example.net/", 3991 "https://resource.local/other" 3992 ], 3993 "datatypes": [ 3994 "metadata", 3995 "images" 3996 ] 3997 }, 3998 "dolphin-metadata" 3999 ], 4000 "client": "7C7C4AZ9KHRS6X63AJAO", 4001 "existing_access_token": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0" 4002 } 4004 The AS responds with a token as described in Section 3. 4006 10.3. Registering a Resource Handle 4008 If the RS needs to, it can post a set of resources as described in 4009 Section 2.1.1 to the AS's resource registration endpoint. 4011 The RS MUST identify itself with its own key and sign the request. 4013 POST /resource HTTP/1.1 4014 Host: server.example.com 4015 Content-type: application/json 4016 Detached-JWS: ejy0... 4018 { 4019 "resources": [ 4020 { 4021 "actions": [ 4022 "read", 4023 "write", 4024 "dolphin" 4025 ], 4026 "locations": [ 4027 "https://server.example.net/", 4028 "https://resource.local/other" 4029 ], 4030 "datatypes": [ 4031 "metadata", 4032 "images" 4033 ] 4034 }, 4035 "dolphin-metadata" 4036 ], 4037 "client": "7C7C4AZ9KHRS6X63AJAO" 4039 } 4041 The AS responds with a handle appropriate to represent the resources 4042 list that the RS presented. 4044 Content-type: application/json 4046 { 4047 "resource_handle": "FWWIKYBQ6U56NL1" 4048 } 4050 The RS MAY make this handle available as part of a response 4051 (Section 10.4) or as documentation to developers. 4053 [[ See issue #117 (https://github.com/ietf-wg-gnap/gnap-core- 4054 protocol/issues/117) ]] 4056 10.4. Requesting Resources With Insufficient Access 4058 If the RC calls an RS without an access token, or with an invalid 4059 access token, the RS MAY respond to the RC with an authentication 4060 header indicating that GNAP needs to be used to access the resource. 4061 The address of the GNAP endpoint MUST be sent in the "as_uri" 4062 parameter. The RS MAY additionally return a resource reference that 4063 the RC MAY use in its resource request (Section 2.1). This resource 4064 reference handle SHOULD be sufficient for at least the action the RC 4065 was attempting to take at the RS. The RS MAY use the dynamic 4066 resource handle request (Section 10.3) to register a new resource 4067 handle, or use a handle that has been pre-configured to represent 4068 what the AS is protecting. The content of this handle is opaque to 4069 the RS and the RC. 4071 WWW-Authenticate: GNAP as_uri=http://server.example/tx,resource=FWWIKYBQ6U56NL1 4073 The RC then makes a call to the "as_uri" as described in Section 2, 4074 with the value of "resource" as one of the members of a "resources" 4075 array Section 2.1.1. The RC MAY request additional resources and 4076 other information, and MAY request multiple access tokens. 4078 [[ See issue #118 (https://github.com/ietf-wg-gnap/gnap-core- 4079 protocol/issues/118) ]] 4081 11. Acknowledgements 4083 The author would like to thank the feedback of the following 4084 individuals for their reviews, implementations, and contributions: 4085 Aaron Parecki, Annabelle Backman, Dick Hardt, Dmitri Zagidulin, 4086 Dmitry Barinov, Fabien Imbault, Francis Pouatcha, George Fletcher, 4087 Haardik Haardik, Hamid Massaoud, Jacky Yuan, Joseph Heenan, Kathleen 4088 Moriarty, Mike Jones, Mike Varley, Nat Sakimura, Takahiko Kawasaki, 4089 Takahiro Tsuchiya. 4091 In particular, the author would like to thank Aaron Parecki and Mike 4092 Jones for insights into how to integrate identity and authentication 4093 systems into the core protocol, and to Dick Hardt for the use cases, 4094 diagrams, and insights provided in the XAuth proposal that have been 4095 incorporated here. The author would like to especially thank Mike 4096 Varley and the team at SecureKey for feedback and development of 4097 early versions of the XYZ protocol that fed into this standards work. 4099 12. IANA Considerations 4101 [[ TBD: There are a lot of items in the document that are expandable 4102 through the use of value registries. ]] 4104 13. Security Considerations 4106 [[ TBD: There are a lot of security considerations to add. ]] 4108 All requests have to be over TLS or equivalent as per [BCP195]. Many 4109 handles act as shared secrets, though they can be combined with a 4110 requirement to provide proof of a key as well. 4112 14. Privacy Considerations 4114 [[ TBD: There are a lot of privacy considerations to add. ]] 4116 Handles are passed between parties and therefore should not contain 4117 any private data. 4119 When user information is passed to the RC, the AS needs to make sure 4120 that it has the permission to do so. 4122 15. Normative References 4124 [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 4125 "Recommendations for Secure Use of Transport Layer 4126 Security (TLS) and Datagram Transport Layer Security 4127 (DTLS)", May 2015, 4128 . 4130 [I-D.ietf-httpbis-message-signatures] 4131 Backman, A., Richer, J., and M. Sporny, "Signing HTTP 4132 Messages", Work in Progress, Internet-Draft, draft-ietf- 4133 httpbis-message-signatures-00, 10 April 2020, 4134 . 4137 [I-D.ietf-oauth-dpop] 4138 Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., 4139 Jones, M., and D. Waite, "OAuth 2.0 Demonstration of 4140 Proof-of-Possession at the Application Layer (DPoP)", Work 4141 in Progress, Internet-Draft, draft-ietf-oauth-dpop-01, 1 4142 May 2020, . 4145 [I-D.ietf-oauth-signed-http-request] 4146 Richer, J., Bradley, J., and H. Tschofenig, "A Method for 4147 Signing HTTP Requests for OAuth", Work in Progress, 4148 Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8 4149 August 2016, . 4152 [I-D.ietf-secevent-subject-identifiers] 4153 Backman, A. and M. Scurtescu, "Subject Identifiers for 4154 Security Event Tokens", Work in Progress, Internet-Draft, 4155 draft-ietf-secevent-subject-identifiers-06, 4 September 4156 2020, . 4159 [OIDC] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and 4160 C. Mortimore, "OpenID Connect Core 1.0 incorporating 4161 errata set 1", November 2014, 4162 . 4164 [OIDC4IA] Lodderstedt, T. and D. Fett, "OpenID Connect for Identity 4165 Assurance 1.0", October 2019, . 4168 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 4169 Requirement Levels", BCP 14, RFC 2119, 4170 DOI 10.17487/RFC2119, March 1997, 4171 . 4173 [RFC3230] Mogul, J. and A. Van Hoff, "Instance Digests in HTTP", 4174 RFC 3230, DOI 10.17487/RFC3230, January 2002, 4175 . 4177 [RFC5646] Phillips, A., Ed. and M. Davis, Ed., "Tags for Identifying 4178 Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, 4179 September 2009, . 4181 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 4182 RFC 6749, DOI 10.17487/RFC6749, October 2012, 4183 . 4185 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 4186 Framework: Bearer Token Usage", RFC 6750, 4187 DOI 10.17487/RFC6750, October 2012, 4188 . 4190 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 4191 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 4192 2015, . 4194 [RFC7797] Jones, M., "JSON Web Signature (JWS) Unencoded Payload 4195 Option", RFC 7797, DOI 10.17487/RFC7797, February 2016, 4196 . 4198 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 4199 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 4200 May 2017, . 4202 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 4203 Interchange Format", STD 90, RFC 8259, 4204 DOI 10.17487/RFC8259, December 2017, 4205 . 4207 [RFC8693] Jones, M., Nadalin, A., Campbell, B., Ed., Bradley, J., 4208 and C. Mortimore, "OAuth 2.0 Token Exchange", RFC 8693, 4209 DOI 10.17487/RFC8693, January 2020, 4210 . 4212 [RFC8705] Campbell, B., Bradley, J., Sakimura, N., and T. 4213 Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication 4214 and Certificate-Bound Access Tokens", RFC 8705, 4215 DOI 10.17487/RFC8705, February 2020, 4216 . 4218 Appendix A. Document History 4220 * -02 4222 - Moved all "editor's note" items to GitHub Issues. 4224 * -01 4226 - "updated_at" subject info timestamp now in ISO 8601 string 4227 format. 4229 - Editorial fixes. 4231 - Added Aaron and Fabien as document authors. 4233 * -00 4235 - Initial working group draft. 4237 Appendix B. Component Data Models 4239 While different implementations of this protocol will have different 4240 realizations of all the components and artifacts enumerated here, the 4241 nature of the protocol implies some common structures and elements 4242 for certain components. This appendix seeks to enumerate those 4243 common elements. 4245 TBD: Client has keys, allowed requested resources, identifier(s), 4246 allowed requested subjects, allowed 4248 TBD: AS has "grant endpoint", interaction endpoints, store of trusted 4249 client keys, policies 4251 TBD: Token has RO, user, client, resource list, RS list, 4253 Appendix C. Example Protocol Flows 4255 The protocol defined in this specification provides a number of 4256 features that can be combined to solve many different kinds of 4257 authentication scenarios. This section seeks to show examples of how 4258 the protocol would be applied for different situations. 4260 Some longer fields, particularly cryptographic information, have been 4261 truncated for display purposes in these examples. 4263 C.1. Redirect-Based User Interaction 4265 In this scenario, the user is the RO and has access to a web browser, 4266 and the client can take front-channel callbacks on the same device as 4267 the user. This combination is analogous to the OAuth 2 Authorization 4268 Code grant type. 4270 The client initiates the request to the AS. Here the client 4271 identifies itself using its public key. 4273 POST /tx HTTP/1.1 4274 Host: server.example.com 4275 Content-type: application/json 4276 Detached-JWS: ejy0... 4278 { 4279 "resources": [ 4280 { 4281 "actions": [ 4282 "read", 4283 "write", 4284 "dolphin" 4285 ], 4286 "locations": [ 4287 "https://server.example.net/", 4288 "https://resource.local/other" 4289 ], 4290 "datatypes": [ 4291 "metadata", 4292 "images" 4293 ] 4294 } 4295 ], 4296 "client": { 4297 "key": { 4298 "proof": "jwsd", 4299 "jwk": { 4300 "kty": "RSA", 4301 "e": "AQAB", 4302 "kid": "xyz-1", 4303 "alg": "RS256", 4304 "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xY..." 4305 } 4306 } 4307 }, 4308 "interact": { 4309 "redirect": true, 4310 "callback": { 4311 "method": "redirect", 4312 "uri": "https://client.example.net/return/123455", 4313 "nonce": "LKLTI25DK82FX4T4QFZC" 4314 } 4315 } 4316 } 4317 The AS processes the request and determines that the RO needs to 4318 interact. The AS returns the following response giving the client 4319 the information it needs to connect. The AS has also indicated to 4320 the client that it can use the given instance identifier to identify 4321 itself in future requests (Section 2.3.1). 4323 Content-type: application/json 4325 { 4326 "interact": { 4327 "redirect": "https://server.example.com/interact/4CF492MLVMSW9MKMXKHQ", 4328 "callback": "MBDOFXG4Y5CVJCX821LH" 4329 } 4330 "continue": { 4331 "access_token": { 4332 "value": "80UPRY5NM33OMUKMKSKU", 4333 "key": true 4334 }, 4335 "uri": "https://server.example.com/continue" 4336 }, 4337 "instance_id": "7C7C4AZ9KHRS6X63AJAO" 4338 } 4340 The client saves the response and redirects the user to the 4341 interaction_url by sending the following HTTP message to the user's 4342 browser. 4344 HTTP 302 Found 4345 Location: https://server.example.com/interact/4CF492MLVMSW9MKMXKHQ 4347 The user's browser fetches the AS's interaction URL. The user logs 4348 in, is identified as the RO for the resource being requested, and 4349 approves the request. Since the AS has a callback parameter, the AS 4350 generates the interaction reference, calculates the hash, and 4351 redirects the user back to the client with these additional values 4352 added as query parameters. 4354 HTTP 302 Found 4355 Location: https://client.example.net/return/123455 4356 ?hash=p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R2HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A 4357 &interact_ref=4IFWWIKYBC2PQ6U56NL1 4358 The client receives this request from the user's browser. The client 4359 ensures that this is the same user that was sent out by validating 4360 session information and retrieves the stored pending request. The 4361 client uses the values in this to validate the hash parameter. The 4362 client then calls the continuation URL and presents the handle and 4363 interaction reference in the request body. The client signs the 4364 request as above. 4366 POST /continue HTTP/1.1 4367 Host: server.example.com 4368 Content-type: application/json 4369 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 4370 Detached-JWS: ejy0... 4372 { 4373 "interact_ref": "4IFWWIKYBC2PQ6U56NL1" 4374 } 4376 The AS retrieves the pending request based on the handle and issues a 4377 bearer access token and returns this to the client. 4379 Content-type: application/json 4381 { 4382 "access_token": { 4383 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 4384 "key": false, 4385 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L", 4386 "resources": [{ 4387 "actions": [ 4388 "read", 4389 "write", 4390 "dolphin" 4391 ], 4392 "locations": [ 4393 "https://server.example.net/", 4394 "https://resource.local/other" 4395 ], 4396 "datatypes": [ 4397 "metadata", 4398 "images" 4399 ] 4400 }] 4401 }, 4402 "continue": { 4403 "access_token": { 4404 "value": "80UPRY5NM33OMUKMKSKU", 4405 "key": true 4406 }, 4407 "uri": "https://server.example.com/continue" 4408 } 4409 } 4411 C.2. Secondary Device Interaction 4413 In this scenario, the user does not have access to a web browser on 4414 the device and must use a secondary device to interact with the AS. 4415 The client can display a user code or a printable QR code. The 4416 client prefers a short URL if one is available, with a maximum of 255 4417 characters in length. The is not able to accept callbacks from the 4418 AS and needs to poll for updates while waiting for the user to 4419 authorize the request. 4421 The client initiates the request to the AS. 4423 POST /tx HTTP/1.1 4424 Host: server.example.com 4425 Content-type: application/json 4426 Detached-JWS: ejy0... 4428 { 4429 "resources": [ 4430 "dolphin-metadata", "some other thing" 4431 ], 4432 "client": "7C7C4AZ9KHRS6X63AJAO", 4433 "interact": { 4434 "redirect": 255, 4435 "user_code": true 4436 } 4437 } 4439 The AS processes this and determines that the RO needs to interact. 4440 The AS supports both long and short redirect URIs for interaction, so 4441 it includes both. Since there is no "callback" the AS does not 4442 include a nonce, but does include a "wait" parameter on the 4443 continuation section because it expects the client to poll for 4444 results. 4446 Content-type: application/json 4448 { 4449 "interact": { 4450 "redirect": "https://srv.ex/MXKHQ", 4451 "user_code": { 4452 "code": "A1BC-3DFF", 4453 "url": "https://srv.ex/device" 4454 } 4455 }, 4456 "continue": { 4457 "uri": "https://server.example.com/continue/80UPRY5NM33OMUKMKSKU", 4458 "wait": 60 4459 } 4460 } 4462 The client saves the response and displays the user code visually on 4463 its screen along with the static device URL. The client also 4464 displays the short interaction URL as a QR code to be scanned. 4466 If the user scans the code, they are taken to the interaction 4467 endpoint and the AS looks up the current pending request based on the 4468 incoming URL. If the user instead goes to the static page and enters 4469 the code manually, the AS looks up the current pending request based 4470 on the value of the user code. In both cases, the user logs in, is 4471 identified as the RO for the resource being requested, and approves 4472 the request. Once the request has been approved, the AS displays to 4473 the user a message to return to their device. 4475 Meanwhile, the client periodically polls the AS every 60 seconds at 4476 the continuation URL. The client signs the request using the same 4477 key and method that it did in the first request. 4479 POST /continue/80UPRY5NM33OMUKMKSKU HTTP/1.1 4480 Host: server.example.com 4481 Detached-JWS: ejy0... 4483 The AS retrieves the pending request based on the handle and 4484 determines that it has not yet been authorized. The AS indicates to 4485 the client that no access token has yet been issued but it can 4486 continue to call after another 60 second timeout. 4488 Content-type: application/json 4490 { 4491 "continue": { 4492 "uri": "https://server.example.com/continue/BI9QNW6V9W3XFJK4R02D", 4493 "wait": 60 4494 } 4495 } 4497 Note that the continuation URL has been rotated since it was used by 4498 the client to make this call. The client polls the continuation URL 4499 after a 60 second timeout using the new handle. 4501 POST /continue/BI9QNW6V9W3XFJK4R02D HTTP/1.1 4502 Host: server.example.com 4503 Authorization: GNAP 4504 Detached-JWS: ejy0... 4506 The AS retrieves the pending request based on the URL, determines 4507 that it has been approved, and issues an access token. 4509 Content-type: application/json 4511 { 4512 "access_token": { 4513 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 4514 "key": false, 4515 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L", 4516 "resources": [ 4517 "dolphin-metadata", "some other thing" 4518 ] 4519 } 4520 } 4522 Appendix D. No User Involvement 4524 In this scenario, the client is requesting access on its own behalf, 4525 with no user to interact with. 4527 The client creates a request to the AS, identifying itself with its 4528 public key and using MTLS to make the request. 4530 POST /tx HTTP/1.1 4531 Host: server.example.com 4532 Content-type: application/json 4534 { 4535 "resources": [ 4536 "backend service", "nightly-routine-3" 4537 ], 4538 "client": { 4539 "key": { 4540 "proof": "mtls", 4541 "cert#S256": "bwcK0esc3ACC3DB2Y5_lESsXE8o9ltc05O89jdN-dg2" 4542 } 4543 } 4544 } 4546 The AS processes this and determines that the client can ask for the 4547 requested resources and issues an access token. 4549 Content-type: application/json 4551 { 4552 "access_token": { 4553 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 4554 "key": true, 4555 "manage": "https://server.example.com/token", 4556 "resources": [ 4557 "backend service", "nightly-routine-3" 4558 ] 4559 } 4560 } 4562 D.1. Asynchronous Authorization 4564 In this scenario, the client is requesting on behalf of a specific 4565 RO, but has no way to interact with the user. The AS can 4566 asynchronously reach out to the RO for approval in this scenario. 4568 The client starts the request at the AS by requesting a set of 4569 resources. The client also identifies a particular user. 4571 POST /tx HTTP/1.1 4572 Host: server.example.com 4573 Content-type: application/json 4574 Detached-JWS: ejy0... 4576 { 4577 "resources": [ 4578 { 4579 "type": "photo-api", 4580 "actions": [ 4581 "read", 4582 "write", 4583 "dolphin" 4584 ], 4585 "locations": [ 4586 "https://server.example.net/", 4587 "https://resource.local/other" 4588 ], 4589 "datatypes": [ 4590 "metadata", 4591 "images" 4592 ] 4593 }, 4594 "read", "dolphin-metadata", 4595 { 4596 "type": "financial-transaction", 4597 "actions": [ 4598 "withdraw" 4599 ], 4600 "identifier": "account-14-32-32-3", 4601 "currency": "USD" 4602 }, 4603 "some other thing" 4604 ], 4605 "client": "7C7C4AZ9KHRS6X63AJAO", 4606 "user": { 4607 "sub_ids": [ { 4608 "subject_type": "email", 4609 "email": "user@example.com" 4610 } ] 4611 } 4612 } 4614 The AS processes this and determines that the RO needs to interact. 4615 The AS determines that it can reach the identified user 4616 asynchronously and that the identified user does have the ability to 4617 approve this request. The AS indicates to the client that it can 4618 poll for continuation. 4620 Content-type: application/json 4622 { 4623 "continue": { 4624 "access_token": { 4625 "value": "80UPRY5NM33OMUKMKSKU", 4626 "key": true 4627 }, 4628 "uri": "https://server.example.com/continue", 4629 "wait": 60 4630 } 4631 } 4633 The AS reaches out to the RO and prompts them for consent. In this 4634 example, the AS has an application that it can push notifications in 4635 to for the specified account. 4637 Meanwhile, the client periodically polls the AS every 60 seconds at 4638 the continuation URL. 4640 POST /continue HTTP/1.1 4641 Host: server.example.com 4642 Authorization: GNAP 80UPRY5NM33OMUKMKSKU 4643 Detached-JWS: ejy0... 4645 The AS retrieves the pending request based on the handle and 4646 determines that it has not yet been authorized. The AS indicates to 4647 the client that no access token has yet been issued but it can 4648 continue to call after another 60 second timeout. 4650 Content-type: application/json 4652 { 4653 "continue": { 4654 "access_token": { 4655 "value": "BI9QNW6V9W3XFJK4R02D", 4656 "key": true 4657 }, 4658 "uri": "https://server.example.com/continue", 4659 "wait": 60 4660 } 4661 } 4663 Note that the continuation handle has been rotated since it was used 4664 by the client to make this call. The client polls the continuation 4665 URL after a 60 second timeout using the new handle. 4667 POST /continue HTTP/1.1 4668 Host: server.example.com 4669 Authorization: GNAP BI9QNW6V9W3XFJK4R02D 4670 Detached-JWS: ejy0... 4672 The AS retrieves the pending request based on the handle and 4673 determines that it has been approved and it issues an access token. 4675 Content-type: application/json 4677 { 4678 "access_token": { 4679 "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", 4680 "key": false, 4681 "manage": "https://server.example.com/token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L", 4682 "resources": [ 4683 "dolphin-metadata", "some other thing" 4684 ] 4685 } 4686 } 4688 D.2. Applying OAuth 2 Scopes and Client IDs 4690 While GNAP is not designed to be directly compatible with OAuth 2 4691 [RFC6749], considerations have been made to enable the use of OAuth 2 4692 concepts and constructs more smoothly within GNAP. 4694 In this scenario, the client developer has a "client_id" and set of 4695 "scope" values from their OAuth 2 system and wants to apply them to 4696 the new protocol. Traditionally, the OAuth 2 client developer would 4697 put their "client_id" and "scope" values as parameters into a 4698 redirect request to the authorization endpoint. 4700 HTTP 302 Found 4701 Location: https://server.example.com/authorize 4702 ?client_id=7C7C4AZ9KHRS6X63AJAO 4703 &scope=read%20write%20dolphin 4704 &redirect_uri=https://client.example.net/return 4705 &response_type=code 4706 &state=123455 4708 Now the developer wants to make an analogous request to the AS using 4709 the new protocol. To do so, the client makes an HTTP POST and places 4710 the OAuth 2 values in the appropriate places. 4712 POST /tx HTTP/1.1 4713 Host: server.example.com 4714 Content-type: application/json 4715 Detached-JWS: ejy0... 4717 { 4718 "resources": [ 4719 "read", "write", "dolphin" 4720 ], 4721 "client": "7C7C4AZ9KHRS6X63AJAO", 4722 "interact": { 4723 "redirect": true, 4724 "callback": { 4725 "method": "redirect", 4726 "uri": "https://client.example.net/return?state=123455", 4727 "nonce": "LKLTI25DK82FX4T4QFZC" 4728 } 4729 } 4730 } 4732 The client_id can be used to identify the client's keys that it uses 4733 for authentication, the scopes represent resources that the client is 4734 requesting, and the "redirect_uri" and "state" value are pre-combined 4735 into a "callback" URI that can be unique per request. The client 4736 additionally creates a nonce to protect the callback, separate from 4737 the state parameter that it has added to its return URL. 4739 From here, the protocol continues as above. 4741 Appendix E. JSON Structures and Polymorphism 4743 GNAP makes use of polymorphism within the JSON [RFC8259] structures 4744 used for the protocol. Each portion of this protocol is defined in 4745 terms of the JSON data type that its values can take, whether it's a 4746 string, object, array, boolean, or number. For some fields, 4747 different data types offer different descriptive capabilities and are 4748 used in different situations for the same field. Each data type 4749 provides a different syntax to express the same underlying semantic 4750 protocol element, which allows for optimization and simplification in 4751 many common cases. 4753 Even though JSON is often used to describe strongly typed structures, 4754 JSON on its own is naturally polymorphic. In JSON, the named members 4755 of an object have no type associated with them, and any data type can 4756 be used as the value for any member. In practice, each member has a 4757 semantic type that needs to make sense to the parties creating and 4758 consuming the object. Within this protocol, each object member is 4759 defined in terms of its semantic content, and this semantic content 4760 might have expressions in different concrete data types for different 4761 specific purposes. Since each object member has exactly one value in 4762 JSON, each data type for an object member field is naturally mutually 4763 exclusive with other data types within a single JSON object. 4765 For example, a resource request for a single access token is composed 4766 of an array of resource request descriptions while a request for 4767 multiple access tokens is composed of an object whose member values 4768 are all arrays. Both of these represent requests for access, but the 4769 difference in syntax allows the RC and AS to differentiate between 4770 the two request types in the same request. 4772 Another form of polymorphism in JSON comes from the fact that the 4773 values within JSON arrays need not all be of the same JSON data type. 4774 However, within this protocol, each element within the array needs to 4775 be of the same kind of semantic element for the collection to make 4776 sense, even when the data types are different from each other. 4778 For example, each aspect of a resource request can be described using 4779 an object with multiple dimensional components, or the aspect can be 4780 requested using a string. In both cases, the resource request is 4781 being described in a way that the AS needs to interpret, but with 4782 different levels of specificity and complexity for the RC to deal 4783 with. An API designer can provide a set of common access scopes as 4784 simple strings but still allow RC developers to specify custom access 4785 when needed for more complex APIs. 4787 Extensions to this specification can use different data types for 4788 defined fields, but each extension needs to not only declare what the 4789 data type means, but also provide justification for the data type 4790 representing the same basic kind of thing it extends. For example, 4791 an extension declaring an "array" representation for a field would 4792 need to explain how the array represents something akin to the non- 4793 array element that it is replacing. 4795 Authors' Addresses 4797 Justin Richer (editor) 4798 Bespoke Engineering 4800 Email: ietf@justin.richer.org 4801 URI: https://bspk.io/ 4803 Aaron Parecki 4804 Okta 4806 Email: aaron@parecki.com 4807 URI: https://aaronparecki.com 4809 Fabien Imbault 4810 acert.io 4812 Email: fabien.imbault@acert.io 4813 URI: https://acert.io/