draft-ietf-gnap-core-protocol-05.txt   draft-ietf-gnap-core-protocol-06.txt 
GNAP J. Richer, Ed. GNAP J. Richer, Ed.
Internet-Draft Bespoke Engineering Internet-Draft Bespoke Engineering
Intended status: Standards Track A. Parecki Intended status: Standards Track A. Parecki
Expires: 30 October 2021 Okta Expires: 13 January 2022 Okta
F. Imbault F. Imbault
acert.io acert.io
28 April 2021 12 July 2021
Grant Negotiation and Authorization Protocol Grant Negotiation and Authorization Protocol
draft-ietf-gnap-core-protocol-05 draft-ietf-gnap-core-protocol-06
Abstract Abstract
GNAP defines a mechanism for delegating authorization to a piece of GNAP defines a mechanism for delegating authorization to a piece of
software, and conveying that delegation to the software. This software, and conveying that delegation to the software. This
delegation can include access to a set of APIs as well as information delegation can include access to a set of APIs as well as information
passed directly to the software. passed directly to the software.
Status of This Memo Status of This Memo
skipping to change at page 1, line 36 skipping to change at page 1, line 36
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on 30 October 2021. This Internet-Draft will expire on 13 January 2022.
Copyright Notice Copyright Notice
Copyright (c) 2021 IETF Trust and the persons identified as the Copyright (c) 2021 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/ Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document. license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components and restrictions with respect to this document. Code Components
extracted from this document must include Simplified BSD License text extracted from this document must include Simplified BSD License text
as described in Section 4.e of the Trust Legal Provisions and are as described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Simplified BSD License. provided without warranty as described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Roles . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2. Roles . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3. Elements . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3. Elements . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4. Sequences . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4. Sequences . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4.1. Redirect-based Interaction . . . . . . . . . . . . . 11 1.4.1. Redirect-based Interaction . . . . . . . . . . . . . 12
1.4.2. User-code Interaction . . . . . . . . . . . . . . . . 14 1.4.2. User-code Interaction . . . . . . . . . . . . . . . . 15
1.4.3. Asynchronous Authorization . . . . . . . . . . . . . 16 1.4.3. Asynchronous Authorization . . . . . . . . . . . . . 17
1.4.4. Software-only Authorization . . . . . . . . . . . . . 18 1.4.4. Software-only Authorization . . . . . . . . . . . . . 19
1.4.5. Refreshing an Expired Access Token . . . . . . . . . 19 1.4.5. Refreshing an Expired Access Token . . . . . . . . . 20
1.4.6. Requesting User Information . . . . . . . . . . . . . 21 1.4.6. Requesting User Information . . . . . . . . . . . . . 22
2. Requesting Access . . . . . . . . . . . . . . . . . . . . . . 22 2. Requesting Access . . . . . . . . . . . . . . . . . . . . . . 23
2.1. Requesting Access to Resources . . . . . . . . . . . . . 24 2.1. Requesting Access to Resources . . . . . . . . . . . . . 25
2.1.1. Requesting a Single Access Token . . . . . . . . . . 24 2.1.1. Requesting a Single Access Token . . . . . . . . . . 25
2.1.2. Requesting Multiple Access Tokens . . . . . . . . . . 27 2.1.2. Requesting Multiple Access Tokens . . . . . . . . . . 28
2.2. Requesting Subject Information . . . . . . . . . . . . . 29 2.2. Requesting Subject Information . . . . . . . . . . . . . 30
2.3. Identifying the Client Instance . . . . . . . . . . . . . 30 2.3. Identifying the Client Instance . . . . . . . . . . . . . 31
2.3.1. Identifying the Client Instance by Reference . . . . 31 2.3.1. Identifying the Client Instance by Reference . . . . 32
2.3.2. Providing Displayable Client Instance Information . . 32 2.3.2. Providing Displayable Client Instance Information . . 33
2.3.3. Authenticating the Client Instance . . . . . . . . . 33 2.3.3. Authenticating the Client Instance . . . . . . . . . 33
2.4. Identifying the User . . . . . . . . . . . . . . . . . . 33 2.4. Identifying the User . . . . . . . . . . . . . . . . . . 34
2.4.1. Identifying the User by Reference . . . . . . . . . . 34 2.4.1. Identifying the User by Reference . . . . . . . . . . 35
2.5. Interacting with the User . . . . . . . . . . . . . . . . 35 2.5. Interacting with the User . . . . . . . . . . . . . . . . 35
2.5.1. Start Mode Definitions . . . . . . . . . . . . . . . 36 2.5.1. Start Mode Definitions . . . . . . . . . . . . . . . 37
2.5.2. Finish Interaction Modes . . . . . . . . . . . . . . 38 2.5.2. Finish Interaction Modes . . . . . . . . . . . . . . 38
2.5.3. Hints . . . . . . . . . . . . . . . . . . . . . . . . 40 2.5.3. Hints . . . . . . . . . . . . . . . . . . . . . . . . 41
2.5.4. Extending Interaction Modes . . . . . . . . . . . . . 41 2.5.4. Extending Interaction Modes . . . . . . . . . . . . . 41
2.6. Declaring Client Capabilities . . . . . . . . . . . . . . 41 2.6. Extending The Grant Request . . . . . . . . . . . . . . . 41
2.7. Referencing an Existing Grant Request . . . . . . . . . . 41
2.8. Extending The Grant Request . . . . . . . . . . . . . . . 42
3. Grant Response . . . . . . . . . . . . . . . . . . . . . . . 42 3. Grant Response . . . . . . . . . . . . . . . . . . . . . . . 42
3.1. Request Continuation . . . . . . . . . . . . . . . . . . 44 3.1. Request Continuation . . . . . . . . . . . . . . . . . . 43
3.2. Access Tokens . . . . . . . . . . . . . . . . . . . . . . 45 3.2. Access Tokens . . . . . . . . . . . . . . . . . . . . . . 44
3.2.1. Single Access Token . . . . . . . . . . . . . . . . . 45 3.2.1. Single Access Token . . . . . . . . . . . . . . . . . 45
3.2.2. Multiple Access Tokens . . . . . . . . . . . . . . . 48 3.2.2. Multiple Access Tokens . . . . . . . . . . . . . . . 48
3.3. Interaction Modes . . . . . . . . . . . . . . . . . . . . 50 3.3. Interaction Modes . . . . . . . . . . . . . . . . . . . . 49
3.3.1. Redirection to an arbitrary URL . . . . . . . . . . . 51 3.3.1. Redirection to an arbitrary URL . . . . . . . . . . . 50
3.3.2. Launch of an application URL . . . . . . . . . . . . 51 3.3.2. Launch of an application URL . . . . . . . . . . . . 51
3.3.3. Display of a Short User Code . . . . . . . . . . . . 52 3.3.3. Display of a Short User Code . . . . . . . . . . . . 51
3.3.4. Interaction Finish . . . . . . . . . . . . . . . . . 53 3.3.4. Interaction Finish . . . . . . . . . . . . . . . . . 52
3.3.5. Extending Interaction Mode Responses . . . . . . . . 54 3.3.5. Extending Interaction Mode Responses . . . . . . . . 53
3.4. Returning User Information . . . . . . . . . . . . . . . 54 3.4. Returning User Information . . . . . . . . . . . . . . . 53
3.5. Returning Dynamically-bound Reference Handles . . . . . . 55 3.5. Returning Dynamically-bound Reference Handles . . . . . . 54
3.6. Error Response . . . . . . . . . . . . . . . . . . . . . 56 3.6. Error Response . . . . . . . . . . . . . . . . . . . . . 56
3.7. Extending the Response . . . . . . . . . . . . . . . . . 57 3.7. Extending the Response . . . . . . . . . . . . . . . . . 56
4. Determining Authorization and Consent . . . . . . . . . . . . 57 4. Determining Authorization and Consent . . . . . . . . . . . . 56
4.1. Interaction Start Methods . . . . . . . . . . . . . . . . 60 4.1. Interaction Start Methods . . . . . . . . . . . . . . . . 59
4.1.1. Interaction at a Redirected URI . . . . . . . . . . . 61 4.1.1. Interaction at a Redirected URI . . . . . . . . . . . 60
4.1.2. Interaction at the User Code URI . . . . . . . . . . 61 4.1.2. Interaction at the User Code URI . . . . . . . . . . 60
4.1.3. Interaction through an Application URI . . . . . . . 62 4.1.3. Interaction through an Application URI . . . . . . . 61
4.2. Post-Interaction Completion . . . . . . . . . . . . . . . 62 4.2. Post-Interaction Completion . . . . . . . . . . . . . . . 61
4.2.1. Completing Interaction with a Browser Redirect to the 4.2.1. Completing Interaction with a Browser Redirect to the
Callback URI . . . . . . . . . . . . . . . . . . . . 63 Callback URI . . . . . . . . . . . . . . . . . . . . 62
4.2.2. Completing Interaction with a Direct HTTP Request 4.2.2. Completing Interaction with a Direct HTTP Request
Callback . . . . . . . . . . . . . . . . . . . . . . 64 Callback . . . . . . . . . . . . . . . . . . . . . . 63
4.2.3. Calculating the interaction hash . . . . . . . . . . 65 4.2.3. Calculating the interaction hash . . . . . . . . . . 64
5. Continuing a Grant Request . . . . . . . . . . . . . . . . . 66 5. Continuing a Grant Request . . . . . . . . . . . . . . . . . 65
5.1. Continuing After a Completed Interaction . . . . . . . . 68 5.1. Continuing After a Completed Interaction . . . . . . . . 67
5.2. Continuing During Pending Interaction . . . . . . . . . . 69 5.2. Continuing During Pending Interaction . . . . . . . . . . 68
5.3. Modifying an Existing Request . . . . . . . . . . . . . . 70 5.3. Modifying an Existing Request . . . . . . . . . . . . . . 69
5.4. Canceling a Grant Request . . . . . . . . . . . . . . . . 75 5.4. Canceling a Grant Request . . . . . . . . . . . . . . . . 75
6. Token Management . . . . . . . . . . . . . . . . . . . . . . 76 6. Token Management . . . . . . . . . . . . . . . . . . . . . . 75
6.1. Rotating the Access Token . . . . . . . . . . . . . . . . 76 6.1. Rotating the Access Token . . . . . . . . . . . . . . . . 75
6.2. Revoking the Access Token . . . . . . . . . . . . . . . . 78 6.2. Revoking the Access Token . . . . . . . . . . . . . . . . 77
7. Securing Requests from the Client Instance . . . . . . . . . 79 7. Securing Requests from the Client Instance . . . . . . . . . 78
7.1. Key Formats . . . . . . . . . . . . . . . . . . . . . . . 79 7.1. Key Formats . . . . . . . . . . . . . . . . . . . . . . . 78
7.1.1. Key References . . . . . . . . . . . . . . . . . . . 81 7.1.1. Key References . . . . . . . . . . . . . . . . . . . 80
7.2. Presenting Access Tokens . . . . . . . . . . . . . . . . 81 7.2. Presenting Access Tokens . . . . . . . . . . . . . . . . 80
7.3. Proving Possession of a Key with a Request . . . . . . . 82 7.3. Proving Possession of a Key with a Request . . . . . . . 81
7.3.1. Detached JWS . . . . . . . . . . . . . . . . . . . . 84 7.3.1. HTTP Message Signing . . . . . . . . . . . . . . . . 83
7.3.2. Attached JWS . . . . . . . . . . . . . . . . . . . . 88 7.3.2. Mutual TLS . . . . . . . . . . . . . . . . . . . . . 87
7.3.3. Mutual TLS . . . . . . . . . . . . . . . . . . . . . 92 7.3.3. Detached JWS . . . . . . . . . . . . . . . . . . . . 89
7.3.4. Demonstration of Proof-of-Possession (DPoP) . . . . . 94 7.3.4. Attached JWS . . . . . . . . . . . . . . . . . . . . 93
7.3.5. HTTP Message Signing . . . . . . . . . . . . . . . . 96 8. Resource Access Rights . . . . . . . . . . . . . . . . . . . 97
7.3.6. OAuth Proof of Possession (PoP) . . . . . . . . . . . 99 8.1. Requesting Resources By Reference . . . . . . . . . . . . 100
8. Resource Access Rights . . . . . . . . . . . . . . . . . . . 102 9. Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.1. Requesting Resources By Reference . . . . . . . . . . . . 106 9.1. RS-first Method of AS Discovery . . . . . . . . . . . . . 103
9. Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . 108 10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 105
10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 109 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 105
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 110 12. Security Considerations . . . . . . . . . . . . . . . . . . . 105
12. Security Considerations . . . . . . . . . . . . . . . . . . . 110 13. Privacy Considerations . . . . . . . . . . . . . . . . . . . 105
13. Privacy Considerations . . . . . . . . . . . . . . . . . . . 110 14. Normative References . . . . . . . . . . . . . . . . . . . . 105
14. Normative References . . . . . . . . . . . . . . . . . . . . 110 Appendix A. Document History . . . . . . . . . . . . . . . . . . 108
Appendix A. Document History . . . . . . . . . . . . . . . . . . 113 Appendix B. Compared to OAuth 2.0 . . . . . . . . . . . . . . . 110
Appendix B. Compared to OAuth 2.0 . . . . . . . . . . . . . . . 115 Appendix C. Component Data Models . . . . . . . . . . . . . . . 113
Appendix C. Component Data Models . . . . . . . . . . . . . . . 117 Appendix D. Example Protocol Flows . . . . . . . . . . . . . . . 113
Appendix D. Example Protocol Flows . . . . . . . . . . . . . . . 117 D.1. Redirect-Based User Interaction . . . . . . . . . . . . . 113
D.1. Redirect-Based User Interaction . . . . . . . . . . . . . 118 D.2. Secondary Device Interaction . . . . . . . . . . . . . . 117
D.2. Secondary Device Interaction . . . . . . . . . . . . . . 122 D.3. No User Involvement . . . . . . . . . . . . . . . . . . . 120
D.3. No User Involvement . . . . . . . . . . . . . . . . . . . 125 D.4. Asynchronous Authorization . . . . . . . . . . . . . . . 121
D.4. Asynchronous Authorization . . . . . . . . . . . . . . . 126 D.5. Applying OAuth 2.0 Scopes and Client IDs . . . . . . . . 124
D.5. Applying OAuth 2.0 Scopes and Client IDs . . . . . . . . 129 Appendix E. JSON Structures and Polymorphism . . . . . . . . . . 126
Appendix E. JSON Structures and Polymorphism . . . . . . . . . . 131 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 127
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 132
1. Introduction 1. Introduction
This protocol allows a piece of software, the client instance, to This protocol allows a piece of software, the client instance, to
request delegated authorization to resource servers and to request request delegated authorization to resource servers and to request
direct information. This delegation is facilitated by an direct information. This delegation is facilitated by an
authorization server usually on behalf of a resource owner. The end- authorization server usually on behalf of a resource owner. The end-
user operating the software may interact with the authorization user operating the software may interact with the authorization
server to authenticate, provide consent, and authorize the request. server to authenticate, provide consent, and authorize the request.
The process by which the delegation happens is known as a grant, and The process by which the delegation happens is known as a grant, and
GNAP allows for the negotiation of the grant process over time by GNAP allows for the negotiation of the grant process over time by
multiple parties acting in distinct roles. multiple parties acting in distinct roles.
This specification focuses on the portions of the delegation process
facing the client instance. In particular, this specification
defines interoperable methods for a client instance to request,
negotiate, and receive access to information facilitated by the
authorization server. This specification also discusses discovery
mechanisms for the client instance to configure itself dynamically.
The means for an authorization server and resource server to
interoperate are discussed in the companion document,
[I-D.draft-ietf-gnap-resource-servers].
The focus of this protocol is to provide interoperability between the The focus of this protocol is to provide interoperability between the
different parties acting in each role, and is not to specify different parties acting in each role, and is not to specify
implementation details of each. Where appropriate, GNAP may make implementation details of each. Where appropriate, GNAP may make
recommendations about internal implementation details, but these recommendations about internal implementation details, but these
recommendations are to ensure the security of the overall deployment recommendations are to ensure the security of the overall deployment
rather than to be prescriptive in the implementation. rather than to be prescriptive in the implementation.
This protocol solves many of the same use cases as OAuth 2.0 This protocol solves many of the same use cases as OAuth 2.0
[RFC6749], OpenID Connect [OIDC], and the family of protocols that [RFC6749], OpenID Connect [OIDC], and the family of protocols that
have grown up around that ecosystem. However, GNAP is not an have grown up around that ecosystem. However, GNAP is not an
skipping to change at page 5, line 26 skipping to change at page 6, line 5
indicate line wrapping for long values, as per [RFC8792]. The "\" indicate line wrapping for long values, as per [RFC8792]. The "\"
character and leading spaces on wrapped lines are not part of the character and leading spaces on wrapped lines are not part of the
value. value.
1.2. Roles 1.2. Roles
The parties in GNAP perform actions under different roles. Roles are The parties in GNAP perform actions under different roles. Roles are
defined by the actions taken and the expectations leveraged on the defined by the actions taken and the expectations leveraged on the
role by the overall protocol. role by the overall protocol.
+-------------+ +------------+
| | | |
|Authorization| | Resource |
| Server | | Server |
| |<-+ +---->| |
+-------------+ | | +------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------+
+ | Client |
+ | Instance |
+ +----------+
+ +
+ +
+ +
+-----------+ + +------------+
| | + + + +| |
| Resource | | End |
| Owner | ~ ~ ~ ~ ~ ~ | User |
| | | |
+-----------+ +------------+
Legend
+ + + indicates interaction between a human and computer
----- indicates interaction between two pieces of software
~ ~ ~ indicates a potential equivalence or out-of-band communication between roles
Authorization Server (AS) server that grants delegated privileges to Authorization Server (AS) server that grants delegated privileges to
a particular instance of client software in the form of access a particular instance of client software in the form of access
tokens or other information (such as subject information). tokens or other information (such as subject information).
Client application operated by an end-user that consumes resources Client application operated by an end-user that consumes resources
from one or several RSs, possibly requiring access privileges from from one or several RSs, possibly requiring access privileges from
one or several ASs. one or several ASs.
Example: a client can be a mobile application, a web application, Example: a client can be a mobile application, a web application,
etc. etc.
skipping to change at page 9, line 5 skipping to change at page 10, line 5
In some circumstances, the information needed at a given stage is In some circumstances, the information needed at a given stage is
communicated out of band or is preconfigured between the components communicated out of band or is preconfigured between the components
or entities performing the roles. For example, one entity can fulfil or entities performing the roles. For example, one entity can fulfil
multiple roles, and so explicit communication between the roles is multiple roles, and so explicit communication between the roles is
not necessary within the protocol flow. Additionally some components not necessary within the protocol flow. Additionally some components
may not be involved in all use cases. For example, a client instance may not be involved in all use cases. For example, a client instance
could be calling the AS just to get direct user information and have could be calling the AS just to get direct user information and have
no need to get an access token to call an RS. no need to get an access token to call an RS.
+------------+ +------------+ +------------+ +------------+
| End-user | ~ ~ ~ ~ | Resource | | End-user | ~ ~ ~ ~ | Resource |
| | | Owner (RO) | | | | Owner (RO) |
+------------+ +------------+ +------------+ +------------+
+ + + +
+ + + +
(A) (B) (A) (B)
+ + + +
+ + + +
+--------+ + +------------+ +--------+ + +------------+
| Client | (1) + | Resource | | Client | (1) + | Resource |
|Instance| + | Server | |Instance| + | Server |
| | +---------------+ | (RS) | | | +---------------+ | (RS) |
| |--(2)->| Authorization | | | | |--(2)->| Authorization | | |
| |<-(3)--| Server | | | | |<-(3)--| Server | | |
| | | (AS) | | | | | | (AS) | | |
| |--(4)->| | | | | |--(4)->| | | |
| |<-(5)--| | | | | |<-(5)--| | | |
| |--------------(6)------------->| | | |--------------(6)------------->| |
| | | | (7) | | | | | | (7) | |
| |<-------------(8)------------->| | | |<-------------(8)------------->| |
| |--(9)->| | | | | |--(9)->| | | |
| |<-(10)-| | | | | |<-(10)-| | | |
| |--------------(11)------------>| | | |--------------(11)------------>| |
| | | | (12) | | | | | | (12) | |
| |-(13)->| | | | | |-(13)->| | | |
| | | | | | | | | | | |
+--------+ +---------------+ +------------+ +--------+ +---------------+ +------------+
Legend Legend
+ + + indicates a possible interaction with a human + + + indicates a possible interaction with a human
----- indicates an interaction between protocol roles ----- indicates an interaction between protocol roles
~ ~ ~ indicates a potential equivalence or out-of-band ~ ~ ~ indicates a potential equivalence or out-of-band
communication between roles communication between roles
* (A) The end-user interacts with the client instance to indicate a * (A) The end-user interacts with the client instance to indicate a
need for resources on behalf of the RO. This could identify the need for resources on behalf of the RO. This could identify the
RS the client instance needs to call, the resources needed, or the RS the client instance needs to call, the resources needed, or the
RO that is needed to approve the request. Note that the RO and RO that is needed to approve the request. Note that the RO and
end-user are often the same entity in practice, but some more end-user are often the same entity in practice, but some more
dynamic processes are discussed in dynamic processes are discussed in
[I-D.draft-ietf-gnap-resource-servers]. [I-D.draft-ietf-gnap-resource-servers].
* (1) The client instance determines what access is needed and which * (1) The client instance determines what access is needed and which
skipping to change at page 23, line 8 skipping to change at page 24, line 8
user (object / string) Identifies the end-user to the AS in a manner user (object / string) Identifies the end-user to the AS in a manner
that the AS can verify, either directly or by interacting with the that the AS can verify, either directly or by interacting with the
end-user to determine their status as the RO. Section 2.4 end-user to determine their status as the RO. Section 2.4
interact (object) Describes the modes that the client instance has interact (object) Describes the modes that the client instance has
for allowing the RO to interact with the AS and modes for the for allowing the RO to interact with the AS and modes for the
client instance to receive updates when interaction is complete. client instance to receive updates when interaction is complete.
Section 2.5 Section 2.5
capabilities (array of strings) Identifies named extension
capabilities that the client instance can use, signaling to the AS
which extensions it can use. Section 2.6
existing_grant (string) Identifies a previously-existing grant that
the client instance is extending with this request. Section 2.7
Additional members of this request object can be defined by Additional members of this request object can be defined by
extensions to this protocol as described in Section 2.8 extensions to this protocol as described in Section 2.6
A non-normative example of a grant request is below: A non-normative example of a grant request is below:
{ {
"access_token": { "access_token": {
"access": [ "access": [
{ {
"type": "photo-api", "type": "photo-api",
"actions": [ "actions": [
"read", "read",
skipping to change at page 23, line 48 skipping to change at page 24, line 41
}, },
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"client": { "client": {
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://example.net/client" "uri": "https://example.net/client"
}, },
"key": { "key": {
"proof": "jwsd", "proof": "httpsig",
"jwk": { "jwk": {
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"kid": "xyz-1", "kid": "xyz-1",
"alg": "RS256", "alg": "RS256",
"n": "kOB5rR4Jv0GMeL...." "n": "kOB5rR4Jv0GMeL...."
} }
} }
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.example.net/return/123455", "uri": "https://client.example.net/return/123455",
"nonce": "LKLTI25DK82FX4T4QFZC" "nonce": "LKLTI25DK82FX4T4QFZC"
} }
}, },
"capabilities": ["ext1", "ext2"],
"subject": { "subject": {
"formats": ["iss_sub", "opaque"], "formats": ["iss_sub", "opaque"],
"assertions": ["id_token"] "assertions": ["id_token"]
} }
} }
The request and response MUST be sent as a JSON object in the body of The request and response MUST be sent as a JSON object in the body of
the HTTP POST request with Content-Type "application/json", unless the HTTP POST request with Content-Type "application/json", unless
otherwise specified by the signature mechanism. otherwise specified by the signature mechanism.
skipping to change at page 25, line 17 skipping to change at page 26, line 8
field is REQUIRED if used as part of a multiple access token field is REQUIRED if used as part of a multiple access token
request (Section 2.1.2), and is OPTIONAL otherwise. request (Section 2.1.2), and is OPTIONAL otherwise.
flags (array of strings) A set of flags that indicate desired flags (array of strings) A set of flags that indicate desired
attributes or behavior to be attached to the access token by the attributes or behavior to be attached to the access token by the
AS. This field is OPTIONAL. AS. This field is OPTIONAL.
The values of the "flags" field defined by this specification are as The values of the "flags" field defined by this specification are as
follows: follows:
bearer If this flag is included, the access token being requested is "bearer" If this flag is included, the access token being requested
a bearer token. If this flag is omitted, the access token is is a bearer token. If this flag is omitted, the access token is
bound to the key used by the client instance in this request, or bound to the key used by the client instance in this request, or
the key's most recent rotation. Methods for presenting bound and the key's most recent rotation. Methods for presenting bound and
bearer access tokens are described in Section 7.2. [[ See issue bearer access tokens are described in Section 7.2. [[ See issue
#38 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/38) #38 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/38)
]] ]]
split If this flag is included, the client instance is capable of "split" If this flag is included, the client instance is capable of
receiving a different number of tokens than specified in the token receiving a different number of tokens than specified in the token
request (Section 2.1), including receiving multiple access tokens request (Section 2.1), including receiving multiple access tokens
(Section 3.2.2) in response to any single token request (Section 3.2.2) in response to any single token request
(Section 2.1.1) or a different number of access tokens than (Section 2.1.1) or a different number of access tokens than
requested in a multiple access token request (Section 2.1.2). The requested in a multiple access token request (Section 2.1.2). The
"label" fields of the returned additional tokens are chosen by the "label" fields of the returned additional tokens are chosen by the
AS. The client instance MUST be able to tell from the token AS. The client instance MUST be able to tell from the token
response where and how it can use each of the access tokens. [[ response where and how it can use each of the access tokens. [[
See issue #37 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ See issue #37 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/37) ]] issues/37) ]]
skipping to change at page 31, line 28 skipping to change at page 32, line 28
AS policy, attestations within the "client" request, and other AS policy, attestations within the "client" request, and other
mechanisms. mechanisms.
[[ See issue #44 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ [[ See issue #44 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/44) ]] issues/44) ]]
2.3.1. Identifying the Client Instance by Reference 2.3.1. Identifying the Client Instance by Reference
If the client instance has an instance identifier that the AS can use If the client instance has an instance identifier that the AS can use
to determine appropriate key information, the client instance can to determine appropriate key information, the client instance can
send this value in the "instance_id" field. The instance identifier send this instance identifier as a direct reference value in lieu of
MAY be assigned to a client instance at runtime through the the "client" object. The instance identifier MAY be assigned to a
Section 3.5 or MAY be obtained in another fashion, such as a static client instance at runtime through the Section 3.5 or MAY be obtained
registration process at the AS. in another fashion, such as a static registration process at the AS.
instance_id (string) An identifier string that the AS can use to
identify the particular instance of this client software. The
content and structure of this identifier is opaque to the client
instance.
"client": {
"instance_id": "client-541-ab"
}
If there are no additional fields to send, the client instance MAY
send the instance identifier as a direct reference value in lieu of
the object.
"client": "client-541-ab" "client": "client-541-ab"
When the AS receives a request with an instance identifier, the AS When the AS receives a request with an instance identifier, the AS
MUST ensure that the key used to sign the request (Section 7.3) is MUST ensure that the key used to sign the request (Section 7.3) is
associated with the instance identifier. associated with the instance identifier.
If the "instance_id" field is sent, it MUST NOT be accompanied by
other fields unless such fields are explicitly marked safe for
inclusion alongside the instance identifier.
[[ See issue #45 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/45) ]]
If the AS does not recognize the instance identifier, the request If the AS does not recognize the instance identifier, the request
MUST be rejected with an error. MUST be rejected with an error.
If the client instance is identified in this manner, the registered If the client instance is identified in this manner, the registered
key for the client instance MAY be a symmetric key known to the AS. key for the client instance MAY be a symmetric key known to the AS.
The client instance MUST NOT send a symmetric key by value in the The client instance MUST NOT send a symmetric key by value in the
request, as doing so would expose the key directly instead of proving request, as doing so would expose the key directly instead of proving
possession of it. possession of it.
2.3.2. Providing Displayable Client Instance Information 2.3.2. Providing Displayable Client Instance Information
skipping to change at page 41, line 28 skipping to change at page 41, line 45
If possible, the AS SHOULD use one of the locales in the array, with If possible, the AS SHOULD use one of the locales in the array, with
preference to the first item in the array supported by the AS. If preference to the first item in the array supported by the AS. If
none of the given locales are supported, the AS MAY use a default none of the given locales are supported, the AS MAY use a default
locale. locale.
2.5.4. Extending Interaction Modes 2.5.4. Extending Interaction Modes
Additional interaction start modes, finish modes, and hints are Additional interaction start modes, finish modes, and hints are
defined in a registry TBD (Section 11). defined in a registry TBD (Section 11).
2.6. Declaring Client Capabilities 2.6. Extending The Grant Request
If the client software supports extension capabilities, the client
instance MAY present them to the AS in the "capabilities" field.
This field is an array of strings representing specific extensions
and capabilities, as defined by a registry TBD (Section 11).
"capabilities": ["ext1", "ext2"]
2.7. Referencing an Existing Grant Request
If the client instance has a reference handle from a previously
granted request, it MAY send that reference in the "existing_grant"
field. This field is a single string consisting of the "value" of
the "access_token" returned in a previous request's continuation
response (Section 3.1).
"existing_grant": "80UPRY5NM33OMUKMKSKU"
The AS MUST dereference the grant associated with the reference and
process this request in the context of the referenced one. The AS
MUST NOT alter the existing grant associated with the reference.
[[ See issue #62 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/62) ]]
2.8. Extending The Grant Request
The request object MAY be extended by registering new items in a The request object MAY be extended by registering new items in a
registry TBD (Section 11). Extensions SHOULD be orthogonal to other registry TBD (Section 11). Extensions SHOULD be orthogonal to other
parameters. Extensions MUST document any aspects where the extension parameters. Extensions MUST document any aspects where the extension
item affects or influences the values or behavior of other request item affects or influences the values or behavior of other request
and response objects. and response objects.
3. Grant Response 3. Grant Response
In response to a client instance's request, the AS responds with a In response to a client instance's request, the AS responds with a
skipping to change at page 43, line 14 skipping to change at page 42, line 48
{ {
"interact": { "interact": {
"redirect": "https://server.example.com/interact/4CF492ML\ "redirect": "https://server.example.com/interact/4CF492ML\
VMSW9MKMXKHQ", VMSW9MKMXKHQ",
"finish": "MBDOFXG4Y5CVJCX821LH" "finish": "MBDOFXG4Y5CVJCX821LH"
}, },
"continue": { "continue": {
"access_token": { "access_token": {
"value": "80UPRY5NM33OMUKMKSKU", "value": "80UPRY5NM33OMUKMKSKU",
"bound": true
}, },
"uri": "https://server.example.com/tx" "uri": "https://server.example.com/tx"
} }
} }
In this example, the AS is returning a bearer access token In this example, the AS is returning a bearer access token
(Section 3.2.1) with a management URL and a subject identifier (Section 3.2.1) with a management URL and a subject identifier
(Section 3.4) in the form of an opaque identifier. (Section 3.4) in the form of an opaque identifier.
{ {
"access_token": { "access_token": {
"value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0",
"bound": false, "flags": ["bearer"],
"manage": "https://server.example.com/token/PRY5NM33O\ "manage": "https://server.example.com/token/PRY5NM33O\
M4TB8N6BW7OZB8CDFONP219RP1L", M4TB8N6BW7OZB8CDFONP219RP1L",
}, },
"subject": { "subject": {
"sub_ids": [ { "sub_ids": [ {
"format": "opaque", "format": "opaque",
"id": "J2G8G8O4AZ" "id": "J2G8G8O4AZ"
} ] } ]
} }
} }
In this example, the AS is returning only a pair of subject In this example, the AS is returning set of subject identifiers
identifiers (Section 3.4) as both an email address and an opaque (Section 3.4), simultaneously as an opaque identifier, an email
identifier. address, and a decentralized identifier (DID).
{ {
"subject": { "subject": {
"sub_ids": [ { "sub_ids": [ {
"subject_type": "opaque", "subject_type": "opaque",
"id": "J2G8G8O4AZ" "id": "J2G8G8O4AZ"
}, { }, {
"format": "email", "format": "email",
"email": "user@example.com" "email": "user@example.com"
}, {
"format": "did",
"url": "did:example:123456"
} ] } ]
} }
} }
3.1. Request Continuation 3.1. Request Continuation
If the AS determines that the request can be continued with If the AS determines that the request can be continued with
additional requests, it responds with the "continue" field. This additional requests, it responds with the "continue" field. This
field contains a JSON object with the following properties. field contains a JSON object with the following properties.
skipping to change at page 44, line 37 skipping to change at page 44, line 17
continuation request (Section 5). continuation request (Section 5).
wait (integer) RECOMMENDED. The amount of time in integer seconds wait (integer) RECOMMENDED. The amount of time in integer seconds
the client instance SHOULD wait after receiving this continuation the client instance SHOULD wait after receiving this continuation
handle and calling the URI. handle and calling the URI.
access_token (object) REQUIRED. A unique access token for access_token (object) REQUIRED. A unique access token for
continuing the request, in the format specified in Section 3.2.1. continuing the request, in the format specified in Section 3.2.1.
This access token MUST be bound to the client instance's key used This access token MUST be bound to the client instance's key used
in the request and MUST NOT be a "bearer" token. As a in the request and MUST NOT be a "bearer" token. As a
consequence, the "bound" field of this access token is always the consequence, the "flags" array of this access token MUST NOT
boolean value "true" and the "key" field MUST be omitted. This contain the string "bearer" and the "key" field MUST be omitted.
access token MUST NOT be usable at resources outside of the AS. This access token MUST NOT be usable at resources outside of the
The client instance MUST present the access token in all requests AS. The client instance MUST present the access token in all
to the continuation URI as described in Section 7.2. [[ See issue requests to the continuation URI as described in Section 7.2. [[
#66 (https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/66) See issue #66 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
]] issues/66) ]]
{ {
"continue": { "continue": {
"access_token": { "access_token": {
"value": "80UPRY5NM33OMUKMKSKU" "value": "80UPRY5NM33OMUKMKSKU"
}, },
"uri": "https://server.example.com/continue", "uri": "https://server.example.com/continue",
"wait": 60 "wait": 60
} }
} }
skipping to change at page 45, line 49 skipping to change at page 45, line 21
has granted that access token, the AS responds with the has granted that access token, the AS responds with the
"access_token" field. The value of this field is an object with the "access_token" field. The value of this field is an object with the
following properties. following properties.
value (string) REQUIRED. The value of the access token as a string. value (string) REQUIRED. The value of the access token as a string.
The value is opaque to the client instance. The value SHOULD be The value is opaque to the client instance. The value SHOULD be
limited to ASCII characters to facilitate transmission over HTTP limited to ASCII characters to facilitate transmission over HTTP
headers within other protocols without requiring additional headers within other protocols without requiring additional
encoding. encoding.
bound (boolean) RECOMMENDED. Flag indicating if the token is bound
to the client instance's key. If the boolean value is "true" or
the field is omitted, and the "key" field is omitted, the token is
bound to the key used by the client instance (Section 2.3) in its
request for access. If the boolean value is "true" or the field
is omitted, and the "key" field is present, the token is bound to
the key and proofing mechanism indicated in the "key" field. If
the boolean value is "false", the token is a bearer token with no
key bound to it and the "key" field MUST be omitted.
label (string) REQUIRED for multiple access tokens, OPTIONAL for label (string) REQUIRED for multiple access tokens, OPTIONAL for
single access token. The value of the "label" the client instance single access token. The value of the "label" the client instance
provided in the associated token request (Section 2.1), if provided in the associated token request (Section 2.1), if
present. If the token has been split by the AS, the value of the present. If the token has been split by the AS, the value of the
"label" field is chosen by the AS and the "split" field is "label" field is chosen by the AS and the "split" field is
included and set to "true". included and set to "true".
manage (string) OPTIONAL. The management URI for this access token. manage (string) OPTIONAL. The management URI for this access token.
If provided, the client instance MAY manage its access token as If provided, the client instance MAY manage its access token as
described in Section 6. This management URI is a function of the described in Section 6. This management URI is a function of the
skipping to change at page 46, line 42 skipping to change at page 46, line 5
token past this time. An RS MUST NOT accept an access token past token past this time. An RS MUST NOT accept an access token past
this time. Note that the access token MAY be revoked by the AS or this time. Note that the access token MAY be revoked by the AS or
RS at any point prior to its expiration. RS at any point prior to its expiration.
key (object / string) OPTIONAL. The key that the token is bound to, key (object / string) OPTIONAL. The key that the token is bound to,
if different from the client instance's presented key. The key if different from the client instance's presented key. The key
MUST be an object or string in a format described in Section 7.1. MUST be an object or string in a format described in Section 7.1.
The client instance MUST be able to dereference or process the key The client instance MUST be able to dereference or process the key
information in order to be able to sign the request. information in order to be able to sign the request.
durable (boolean) OPTIONAL. Flag indicating a hint of AS behavior flags (array of strings) OPTIONAL. A set of flags that represent
on token rotation. If this flag is set to the value "true", then attributes or behaviors of the access token issued by the AS.
the client instance can expect a previously-issued access token to
continue to work after it has been rotated (Section 6.1) or the
underlying grant request has been modified (Section 5.3),
resulting in the issuance of new access tokens. If this flag is
set to the boolean value "false" or is omitted, the client
instance can anticipate a given access token will stop working
after token rotation or grant request modification. Note that a
token flagged as "durable" can still expire or be revoked through
any normal means.
split (boolean) OPTIONAL. Flag indicating that this token was The values of the "flags" field defined by this specification are as
generated by issuing multiple access tokens in response to one of follows:
the client instance's token request (Section 2.1) objects. This
behavior MUST NOT be used unless the client instance has "bearer" This flag indicates whether the token is bound to the
specifically requested it by use of the "split" flag. client instance's key. If the "bearer" flag is present, the
access token is a bearer token, and the "key" field in this
response MUST be omitted. If the "bearer" flag is omitted and the
"key" field in this response is omitted, the token is bound the
key used by the client instance (Section 2.3) in its request for
access. If the "bearer" flag is omitted, and the "key" field is
present, the token is bound to the key and proofing mechanism
indicated in the "key" field.
"durable" OPTIONAL. Flag indicating a hint of AS behavior on token
rotation. If this flag is present, then the client instance can
expect a previously-issued access token to continue to work after
it has been rotated (Section 6.1) or the underlying grant request
has been modified (Section 5.3), resulting in the issuance of new
access tokens. If this flag is omitted, the client instance can
anticipate a given access token will stop working after token
rotation or grant request modification. Note that a token flagged
as "durable" can still expire or be revoked through any normal
means.
"split" OPTIONAL. Flag indicating that this token was generated by
issuing multiple access tokens in response to one of the client
instance's token request (Section 2.1) objects. This behavior
MUST NOT be used unless the client instance has specifically
requested it by use of the "split" flag.
Flag values MUST NOT be included more than once.
Additional flags can be defined by extensions using a registry TBD
(Section 11).
The following non-normative example shows a single access token bound The following non-normative example shows a single access token bound
to the client instance's key used in the initial request, with a to the client instance's key used in the initial request, with a
management URL, and that has access to three described resources (one management URL, and that has access to three described resources (one
using an object and two described by reference strings). using an object and two described by reference strings).
"access_token": { "access_token": {
"value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0",
"manage": "https://server.example.com/token/PRY5NM33O\ "manage": "https://server.example.com/token/PRY5NM33O\
M4TB8N6BW7OZB8CDFONP219RP1L", M4TB8N6BW7OZB8CDFONP219RP1L",
skipping to change at page 48, line 4 skipping to change at page 47, line 29
"https://resource.local/other" "https://resource.local/other"
], ],
"datatypes": [ "datatypes": [
"metadata", "metadata",
"images" "images"
] ]
}, },
"read", "dolphin-metadata" "read", "dolphin-metadata"
] ]
} }
The following non-normative example shows a single bearer access The following non-normative example shows a single bearer access
token with access to two described resources. token with access to two described resources.
"access_token": { "access_token": {
"value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0", "value": "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0",
"bound": false, "flags": ["bearer"],
"access": [ "access": [
"finance", "medical" "finance", "medical"
] ]
} }
If the client instance requested a single access token If the client instance requested a single access token
(Section 2.1.1), the AS MUST NOT respond with the multiple access (Section 2.1.1), the AS MUST NOT respond with the multiple access
token structure unless the client instance sends the "split" flag as token structure unless the client instance sends the "split" flag as
described in Section 2.1.1. described in Section 2.1.1.
If the AS has split the access token response, the response MUST If the AS has split the access token response, the response MUST
include the "split" flag set to "true". include the "split" flag.
[[ See issue #69 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ [[ See issue #69 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/69) ]] issues/69) ]]
3.2.2. Multiple Access Tokens 3.2.2. Multiple Access Tokens
If the client instance has requested multiple access tokens and the If the client instance has requested multiple access tokens and the
AS has granted at least one of them, the AS responds with the AS has granted at least one of them, the AS responds with the
"access_token" field. The value of this field is a JSON array, the "access_token" field. The value of this field is a JSON array, the
members of which are distinct access tokens as described in members of which are distinct access tokens as described in
skipping to change at page 49, line 39 skipping to change at page 49, line 6
tokens are included in the response the requested names appropriate tokens are included in the response the requested names appropriate
names. names.
If the client instance requested multiple access tokens If the client instance requested multiple access tokens
(Section 2.1.2), the AS MUST NOT respond with a single access token (Section 2.1.2), the AS MUST NOT respond with a single access token
structure, even if only a single access token is granted. In such structure, even if only a single access token is granted. In such
cases, the AS responds with a multiple access token structure cases, the AS responds with a multiple access token structure
containing one access token. containing one access token.
If the AS has split the access token response, the response MUST If the AS has split the access token response, the response MUST
include the "split" flag set to "true". include the "split" flag in the "flags" array.
"access_token": [ "access_token": [
{ {
"label": "split-1", "label": "split-1",
"value": "8N6BW7OZB8CDFONP219-OS9M2PMHKUR64TBRP1LT0", "value": "8N6BW7OZB8CDFONP219-OS9M2PMHKUR64TBRP1LT0",
"split": true, "flags": ["split"],
"manage": "https://server.example.com/token/PRY5NM33O\ "manage": "https://server.example.com/token/PRY5NM33O\
M4TB8N6BW7OZB8CDFONP219RP1L", M4TB8N6BW7OZB8CDFONP219RP1L",
"access": [ "fruits" ] "access": [ "fruits" ]
}, },
{ {
"label": "split-2", "label": "split-2",
"value": "FG7VGZZPJ3IZEMN21EVU71FHCAR-UFGLO2FDAP4J1", "value": "FG7VGZZPJ3IZEMN21EVU71FHCAR-UFGLO2FDAP4J1",
"split": true, "flags": ["split"],
"access": [ "vegetables" ] "access": [ "vegetables" ]
} }
} }
Each access token MAY be bound to different keys with different Each access token MAY be bound to different keys with different
proofing mechanisms. proofing mechanisms.
If token management (Section 6) is allowed, each access token SHOULD If token management (Section 6) is allowed, each access token SHOULD
have different "manage" URIs. have different "manage" URIs.
skipping to change at page 65, line 15 skipping to change at page 64, line 15
4.2.3. Calculating the interaction hash 4.2.3. Calculating the interaction hash
The "hash" parameter in the request to the client instance's callback The "hash" parameter in the request to the client instance's callback
URL ties the front channel response to an ongoing request by using URL ties the front channel response to an ongoing request by using
values known only to the parties involved. This security mechanism values known only to the parties involved. This security mechanism
allows the client instance to protect itself against several kinds of allows the client instance to protect itself against several kinds of
session fixation and injection attacks. The AS MUST always provide session fixation and injection attacks. The AS MUST always provide
this hash, and the client instance MUST validate the hash when this hash, and the client instance MUST validate the hash when
received. received.
To calculate the "hash" value, the party doing the calculation first To calculate the "hash" value, the party doing the calculation
takes the "nonce" value sent by the client instance in the creates a hash string by concatenating the following values in the
interaction section of the initial request (Section 2.5.2), the AS's following order using a single newline ("\\n") character to separate
nonce value from the interaction finish response (Section 3.3.4), and them:
the "interact_ref" sent to the client instance's callback URL. These
three values are concatenated to each other in this order using a * the "nonce" value sent by the client instance in the interaction
single newline character as a separator between the fields. There is "finish" section of the initial request (Section 2.5.2)
no padding or whitespace before or after any of the lines, and no
trailing newline character. * the AS's nonce value from the interaction finish response
(Section 3.3.4)
* the "interact_ref" returned from the AS as part of the interaction
finish method (Section 4.2)
* the grant endpoint URL the client instance used to make its
initial request (Section 2)
There is no padding or whitespace before or after any of the lines,
and no trailing newline character.
VJLO6A4CAYLBXHTR0KRO VJLO6A4CAYLBXHTR0KRO
MBDOFXG4Y5CVJCX821LH MBDOFXG4Y5CVJCX821LH
4IFWWIKYBC2PQ6U56NL1 4IFWWIKYBC2PQ6U56NL1
https://server.example.com/tx
The party then hashes this string with the appropriate algorithm The party then hashes this string with the appropriate algorithm
based on the "hash_method" parameter of the "callback". If the based on the "hash_method" parameter of the "callback". If the
"hash_method" value is not present in the client instance's request, "hash_method" value is not present in the client instance's request,
the algorithm defaults to "sha3". the algorithm defaults to "sha3".
[[ See issue #56 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ [[ See issue #56 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/56) ]] issues/56) ]]
4.2.3.1. SHA3-512 4.2.3.1. SHA3-512
skipping to change at page 66, line 39 skipping to change at page 65, line 48
Section 7.2 and present proof of the client instance's key (or its Section 7.2 and present proof of the client instance's key (or its
most recent rotation) by signing the request as described in most recent rotation) by signing the request as described in
Section 7.3. The AS MUST validate all keys presented by the client Section 7.3. The AS MUST validate all keys presented by the client
instance or referenced in an ongoing request for each call within instance or referenced in an ongoing request for each call within
that request. that request.
[[ See issue #85 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ [[ See issue #85 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/85) ]] issues/85) ]]
For example, here the client instance makes a POST request to a For example, here the client instance makes a POST request to a
unique URI and signs the request with detached JWS: unique URI and signs the request with HTTP Message Signatures:
POST /continue/KSKUOMUKM HTTP/1.1 POST /continue/KSKUOMUKM HTTP/1.1
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Host: server.example.com Host: server.example.com
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
The AS MUST be able to tell from the client instance's request which The AS MUST be able to tell from the client instance's request which
specific ongoing request is being accessed, using a combination of specific ongoing request is being accessed, using a combination of
the continuation URL, the provided access token, and the client the continuation URL, the provided access token, and the client
instance identified by the key signature. If the AS cannot determine instance identified by the key signature. If the AS cannot determine
a single active grant request to map the continuation request to, the a single active grant request to map the continuation request to, the
AS MUST return an error. AS MUST return an error.
The ability to continue an already-started request allows the client The ability to continue an already-started request allows the client
instance to perform several important functions, including presenting instance to perform several important functions, including presenting
additional information from interaction, modifying the initial additional information from interaction, modifying the initial
request, and getting the current state of the request. request, and getting the current state of the request.
All requests to the continuation API are protected by this bound All requests to the continuation API are protected by this bound
access token. For example, here the client instance makes a POST access token. For example, here the client instance makes a POST
request to a stable continuation endpoint URL with the interaction request to a stable continuation endpoint URL with the interaction
reference (Section 5.1), includes the access token, and signs with reference (Section 5.1), includes the access token, and signs with
detached JWS: HTTP Message Signatures:
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"interact_ref": "4IFWWIKYBC2PQ6U56NL1" "interact_ref": "4IFWWIKYBC2PQ6U56NL1"
} }
If a "wait" parameter was included in the continuation response If a "wait" parameter was included in the continuation response
(Section 3.1), the client instance MUST NOT call the continuation URI (Section 3.1), the client instance MUST NOT call the continuation URI
prior to waiting the number of seconds indicated. If no "wait" prior to waiting the number of seconds indicated. If no "wait"
period is indicated, the client instance SHOULD wait at least 5 period is indicated, the client instance SHOULD wait at least 5
seconds. If the client instance does not respect the given wait seconds. If the client instance does not respect the given wait
skipping to change at page 68, line 16 skipping to change at page 67, line 29
When the AS responds to the client instance's "finish" method as in When the AS responds to the client instance's "finish" method as in
Section 4.2.1, this response includes an interaction reference. The Section 4.2.1, this response includes an interaction reference. The
client instance MUST include that value as the field "interact_ref" client instance MUST include that value as the field "interact_ref"
in a POST request to the continuation URI. in a POST request to the continuation URI.
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"interact_ref": "4IFWWIKYBC2PQ6U56NL1" "interact_ref": "4IFWWIKYBC2PQ6U56NL1"
} }
Since the interaction reference is a one-time-use value as described Since the interaction reference is a one-time-use value as described
in Section 4.2.1, if the client instance needs to make additional in Section 4.2.1, if the client instance needs to make additional
continuation calls after this request, the client instance MUST NOT continuation calls after this request, the client instance MUST NOT
include the interaction reference. If the AS detects a client include the interaction reference. If the AS detects a client
instance submitting the same interaction reference multiple times, instance submitting the same interaction reference multiple times,
skipping to change at page 69, line 37 skipping to change at page 68, line 40
When the client instance does not include a "finish" parameter, the When the client instance does not include a "finish" parameter, the
client instance will often need to poll the AS until the RO has client instance will often need to poll the AS until the RO has
authorized the request. To do so, the client instance makes a POST authorized the request. To do so, the client instance makes a POST
request to the continuation URI as in Section 5.1, but does not request to the continuation URI as in Section 5.1, but does not
include a message body. include a message body.
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
The Section 3 MAY contain any newly-created access tokens The Section 3 MAY contain any newly-created access tokens
(Section 3.2) or newly-released subject claims (Section 3.4). The (Section 3.2) or newly-released subject claims (Section 3.4). The
response MAY contain a new "continue" response (Section 3.1) as response MAY contain a new "continue" response (Section 3.1) as
described above. If a "continue" field is included, it SHOULD described above. If a "continue" field is included, it SHOULD
include a "wait" field to facilitate a reasonable polling rate by the include a "wait" field to facilitate a reasonable polling rate by the
client instance. The response SHOULD NOT contain interaction client instance. The response SHOULD NOT contain interaction
responses (Section 3.3). responses (Section 3.3).
For example, if the request has not yet been authorized by the RO, For example, if the request has not yet been authorized by the RO,
skipping to change at page 72, line 8 skipping to change at page 71, line 8
contain a new "continue" response (Section 3.1) as described above. contain a new "continue" response (Section 3.1) as described above.
If interaction can occur, the response SHOULD contain interaction If interaction can occur, the response SHOULD contain interaction
responses (Section 3.3) as well. responses (Section 3.3) as well.
For example, a client instance initially requests a set of resources For example, a client instance initially requests a set of resources
using references: using references:
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"read", "write" "read", "write"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
skipping to change at page 73, line 9 skipping to change at page 72, line 14
This "continue" field allows the client instance to make an eventual This "continue" field allows the client instance to make an eventual
continuation call. In the future, the client instance realizes that continuation call. In the future, the client instance realizes that
it no longer needs "write" access and therefore modifies its ongoing it no longer needs "write" access and therefore modifies its ongoing
request, here asking for just "read" access instead of both "read" request, here asking for just "read" access instead of both "read"
and "write" as before. and "write" as before.
PATCH /continue HTTP/1.1 PATCH /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"read" "read"
] ]
} }
... ...
} }
skipping to change at page 73, line 44 skipping to change at page 73, line 4
"uri": "https://server.example.com/continue", "uri": "https://server.example.com/continue",
"wait": 30 "wait": 30
}, },
"access_token": { "access_token": {
"value": "0EVKC7-2ZKwZM_6N760", "value": "0EVKC7-2ZKwZM_6N760",
"access": [ "access": [
"read" "read"
] ]
} }
} }
For another example, the client instance initially requests read-only For another example, the client instance initially requests read-only
access but later needs to step up its access. The initial request access but later needs to step up its access. The initial request
could look like this example. could look like this example.
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"read" "read"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
skipping to change at page 75, line 16 skipping to change at page 74, line 22
and the callback is intended for one-time-use, a new one needs to be and the callback is intended for one-time-use, a new one needs to be
included in order to use the callback again. included in order to use the callback again.
[[ See issue #97 (https://github.com/ietf-wg-gnap/gnap-core-protocol/ [[ See issue #97 (https://github.com/ietf-wg-gnap/gnap-core-protocol/
issues/97) ]] issues/97) ]]
PATCH /continue HTTP/1.1 PATCH /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"read", "write" "read", "write"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
skipping to change at page 76, line 9 skipping to change at page 75, line 14
5.4. Canceling a Grant Request 5.4. Canceling a Grant Request
If the client instance wishes to cancel an ongoing grant request, it If the client instance wishes to cancel an ongoing grant request, it
makes an HTTP DELETE request to the continuation URI. makes an HTTP DELETE request to the continuation URI.
DELETE /continue HTTP/1.1 DELETE /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
If the request is successfully cancelled, the AS responds with an If the request is successfully cancelled, the AS responds with an
HTTP 202. The AS SHOULD revoke all associated access tokens. HTTP 202. The AS SHOULD revoke all associated access tokens.
6. Token Management 6. Token Management
If an access token response includes the "manage" parameter as If an access token response includes the "manage" parameter as
described in Section 3.2.1, the client instance MAY call this URL to described in Section 3.2.1, the client instance MAY call this URL to
manage the access token with any of the actions defined in the manage the access token with any of the actions defined in the
following sections. Other actions are undefined by this following sections. Other actions are undefined by this
skipping to change at page 76, line 47 skipping to change at page 76, line 8
6.1. Rotating the Access Token 6.1. Rotating the Access Token
The client instance makes an HTTP POST to the token management URI, The client instance makes an HTTP POST to the token management URI,
sending the access token in the appropriate header and signing the sending the access token in the appropriate header and signing the
request with the appropriate key. request with the appropriate key.
POST /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1 POST /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0
Detached-JWS: eyj0.... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
The AS validates that the token presented is associated with the The AS validates that the token presented is associated with the
management URL, that the AS issued the token to the given client management URL, that the AS issued the token to the given client
instance, and that the presented key is appropriate to the token. instance, and that the presented key is appropriate to the token.
If the access token has expired, the AS SHOULD honor the rotation If the access token has expired, the AS SHOULD honor the rotation
request to the token management URL since it is likely that the request to the token management URL since it is likely that the
client instance is attempting to refresh the expired token. To client instance is attempting to refresh the expired token. To
support this, the AS MAY apply different lifetimes for the use of the support this, the AS MAY apply different lifetimes for the use of the
token in management vs. its use at an RS. An AS MUST NOT honor a token in management vs. its use at an RS. An AS MUST NOT honor a
skipping to change at page 78, line 50 skipping to change at page 77, line 50
token management URI to indicate to the AS that the AS should token management URI to indicate to the AS that the AS should
invalidate the access token for all purposes. invalidate the access token for all purposes.
The client instance makes an HTTP DELETE request to the token The client instance makes an HTTP DELETE request to the token
management URI, presenting the access token and signing the request management URI, presenting the access token and signing the request
with the appropriate key. with the appropriate key.
DELETE /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1 DELETE /token/PRY5NM33OM4TB8N6BW7OZB8CDFONP219RP1L HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0
Detached-JWS: eyj0.... Signature-Input: sig1=...
Signature: sig1=...
If the key presented is associated with the token (or the client If the key presented is associated with the token (or the client
instance, in the case of a bearer token), the AS MUST invalidate the instance, in the case of a bearer token), the AS MUST invalidate the
access token, if possible, and return an HTTP 204 response code. access token, if possible, and return an HTTP 204 response code.
204 No Content 204 No Content
Though the AS MAY revoke an access token at any time for any reason, Though the AS MAY revoke an access token at any time for any reason,
the token management function is specifically for the client the token management function is specifically for the client
instance's use. If the access token has already expired or has been instance's use. If the access token has already expired or has been
skipping to change at page 79, line 38 skipping to change at page 78, line 38
* When a key proof is used with no access token, this is a non- * When a key proof is used with no access token, this is a non-
authorized signed request. This type of request is used for calls authorized signed request. This type of request is used for calls
to the AS to initiate a negotiation. to the AS to initiate a negotiation.
* When an access token is used with no key proof, this is a bearer * When an access token is used with no key proof, this is a bearer
token request. This type of request is used only for calls to the token request. This type of request is used only for calls to the
RS, and only with access tokens that are not bound to any key as RS, and only with access tokens that are not bound to any key as
described in Section 3.2.1. described in Section 3.2.1.
* When neither an access token nor key proof are used, this is an * When neither an access token nor key proof are used, this is an
unsecured request. This type of request is not used in the core unsecured request. This type of request is used optionally for
protocol of GNAP. calls to the RS as part of an RS-first discovery process as
described in Section 9.1.
7.1. Key Formats 7.1. Key Formats
Several different places in GNAP require the presentation of key Several different places in GNAP require the presentation of key
material by value. Proof of this key material MUST be bound to a material by value. Proof of this key material MUST be bound to a
request, the nature of which varies with the location in the protocol request, the nature of which varies with the location in the protocol
the key is used. For a key used as part of a client instance's the key is used. For a key used as part of a client instance's
initial request in Section 2.3, the key value is the client initial request in Section 2.3, the key value is the client
instance's public key, and proof of that key MUST be presented in instance's public key, and proof of that key MUST be presented in
that request. For a key used as part of an access token response in that request. For a key used as part of an access token response in
skipping to change at page 80, line 33 skipping to change at page 79, line 33
the request, with optional internal whitespace per [RFC7468]. The the request, with optional internal whitespace per [RFC7468]. The
PEM header and footer are optionally removed. PEM header and footer are optionally removed.
cert#S256 (string) The certificate thumbprint calculated as per cert#S256 (string) The certificate thumbprint calculated as per
OAuth-MTLS [RFC8705] in base64 URL encoding. Note that this OAuth-MTLS [RFC8705] in base64 URL encoding. Note that this
format does not include the full public key. format does not include the full public key.
Additional key formats are defined in a registry TBD (Section 11). Additional key formats are defined in a registry TBD (Section 11).
This non-normative example shows a single key presented in multiple This non-normative example shows a single key presented in multiple
formats. This key is intended to be used with the detached JWS formats. This example key is intended to be used with the HTTP
(Section 7.3.1) proofing mechanism, as indicated by the "proof" Message Signatures ({{httpsig-binding}}) proofing mechanism, as
field. indicated by the "httpsig" value of the "proof" field.
"key": { "key": {
"proof": "jwsd", "proof": "httpsig",
"jwk": { "jwk": {
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"kid": "xyz-1", "kid": "xyz-1",
"alg": "RS256", "alg": "RS256",
"n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xY..." "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8xY..."
}, },
"cert": "MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFA..." "cert": "MIIEHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFA..."
} }
skipping to change at page 81, line 31 skipping to change at page 80, line 31
specification. specification.
7.2. Presenting Access Tokens 7.2. Presenting Access Tokens
The method the client instance uses to send an access token depends The method the client instance uses to send an access token depends
on whether the token is bound to a key, and if so which proofing on whether the token is bound to a key, and if so which proofing
method is associated with the key. This information is conveyed in method is associated with the key. This information is conveyed in
the "bound" and "key" parameters in the single (Section 3.2.1) and the "bound" and "key" parameters in the single (Section 3.2.1) and
multiple access tokens (Section 3.2.2) responses. multiple access tokens (Section 3.2.2) responses.
If the "bound" value is the boolean "true" and the "key" is absent, If the "flags" field does not contain the "bearer" flag and the "key"
the access token MUST be sent using the same key and proofing is absent, the access token MUST be sent using the same key and
mechanism that the client instance used in its initial request (or proofing mechanism that the client instance used in its initial
its most recent rotation). request (or its most recent rotation).
If the "bound" value is the boolean "true" and the "key" value is an If the "flags" field does not contain the "bearer" flag and the "key"
object as described in Section 7.1, the access token MUST be sent value is an object as described in Section 7.1, the access token MUST
using the key and proofing mechanism defined by the value of the be sent using the key and proofing mechanism defined by the value of
"proof" field within the key object. the "proof" field within the key object.
The access token MUST be sent using the HTTP "Authorization" request The access token MUST be sent using the HTTP "Authorization" request
header field and the "GNAP" authorization scheme along with a key header field and the "GNAP" authorization scheme along with a key
proof as described in Section 7.3 for the key bound to the access proof as described in Section 7.3 for the key bound to the access
token. For example, a "jwsd"-bound access token is sent as follows: token. For example, an "httpsig"-bound access token is sent as
follows:
Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 Authorization: GNAP OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0
Detached-JWS: eyj0.... Signature-Input: sig1=(authorization);...
Signature: sig1=...
If the "bound" value is the boolean "false", the access token is a If the "flags" field contains the "bearer" flag, the access token is
bearer token that MUST be sent using the "Authorization Request a bearer token that MUST be sent using the "Authorization Request
Header Field" method defined in [RFC6750]. Header Field" method defined in [RFC6750].
Authorization: Bearer OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0 Authorization: Bearer OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0
The "Form-Encoded Body Parameter" and "URI Query Parameter" methods The "Form-Encoded Body Parameter" and "URI Query Parameter" methods
of [RFC6750] MUST NOT be used. of [RFC6750] MUST NOT be used.
[[ See issue #104 (https://github.com/ietf-wg-gnap/gnap-core- [[ See issue #104 (https://github.com/ietf-wg-gnap/gnap-core-
protocol/issues/104) ]] protocol/issues/104) ]]
The client software MUST reject as an error a situation where the The client software MUST reject as an error a situation where the
"bound" value is the boolean "false" and the "key" is present. "flags" field contains the "bearer" flag and the "key" field is
present with any value.
7.3. Proving Possession of a Key with a Request 7.3. Proving Possession of a Key with a Request
Any keys presented by the client instance to the AS or RS MUST be Any keys presented by the client instance to the AS or RS MUST be
validated as part of the request in which they are presented. The validated as part of the request in which they are presented. The
type of binding used is indicated by the proof parameter of the key type of binding used is indicated by the proof parameter of the key
object in Section 7.1. Values defined by this specification are as object in Section 7.1. Values defined by this specification are as
follows: follows:
jwsd A detached JWS signature header httpsig HTTP Signing signature header
jws Attached JWS payload
mtls Mutual TLS certificate verification mtls Mutual TLS certificate verification
dpop OAuth Demonstration of Proof-of-Possession key proof header jwsd A detached JWS signature header
httpsig HTTP Signing signature header
oauthpop OAuth PoP key proof authentication header jws Attached JWS payload
Additional proofing methods are defined by a registry TBD Additional proofing methods are defined by a registry TBD
(Section 11). (Section 11).
All key binding methods used by this specification MUST cover all All key binding methods used by this specification MUST cover all
relevant portions of the request, including anything that would relevant portions of the request, including anything that would
change the nature of the request, to allow for secure validation of change the nature of the request, to allow for secure validation of
the request. Relevant aspects include the URI being called, the HTTP the request. Relevant aspects include the URI being called, the HTTP
method being used, any relevant HTTP headers and values, and the HTTP method being used, any relevant HTTP headers and values, and the HTTP
message body itself. The verifier of the signed message MUST message body itself. The verifier of the signed message MUST
skipping to change at page 84, line 39 skipping to change at page 83, line 39
M40ql8u8J6vc2GmQGfokLlPQ6XLSCY68_xkTXrhoU1f-eDntkhP7L6XawSK\ M40ql8u8J6vc2GmQGfokLlPQ6XLSCY68_xkTXrhoU1f-eDntkhP7L6XawSK\
Onv5F2H7wyBQ75HUmHTg8AK2B_vRlMyFKjXbVlzKf4kvqChSGEz4IjQ", Onv5F2H7wyBQ75HUmHTg8AK2B_vRlMyFKjXbVlzKf4kvqChSGEz4IjQ",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8BfYdHsFzAt\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8BfYdHsFzAt\
YKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZGYX\ YKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZGYX\
jHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZx\ jHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZx\
e0jRETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0\ e0jRETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0\
bunS0K3bA_3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kO\ bunS0K3bA_3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kO\
zywzwPTuq-cVQDyEN7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" zywzwPTuq-cVQDyEN7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
7.3.1. Detached JWS 7.3.1. HTTP Message Signing
This method is indicated by "jwsd" in the "proof" field. A JWS
[RFC7515] object is created as follows:
To protect the request, the JOSE header of the signature contains the
following parameters:
kid (string) The key identifier. RECOMMENDED. If the key is
presented in JWK format, this MUST be the value of the "kid" field
of the key.
alg (string) The algorithm used to sign the request. REQUIRED.
MUST be appropriate to the key presented. If the key is presented
as a JWK, this MUST be equal to the "alg" parameter of the key.
MUST NOT be "none".
typ (string) The type header, value "gnap-binding+jwsd". REQUIRED
htm (string) The HTTP Method used to make this request, as an This method is indicated by "httpsig" in the "proof" field. The
uppercase ASCII string. REQUIRED sender creates an HTTP Message Signature as described in
[I-D.ietf-httpbis-message-signatures].
uri (string) The HTTP URI used for this request, including all path The covered content of the signature MUST include the following:
and query components and no fragment component. REQUIRED
created (integer) A timestamp of when the signature was created, in @request-target: the target of the HTTP request
integer seconds since UNIX Epoch
ath (string) When a request is bound to an access token, the access digest: The Digest header as defined in [RFC3230]. When the request
token hash value. The value MUST be the result of Base64url message has a body, the signer MUST calculate this header value
encoding (with no padding) the SHA-256 digest of the ASCII and the verifier MUST validate this header.
encoding of the associated access token's value. REQUIRED if the
request protects an access token.
If the HTTP request has a message body, such as an HTTP POST or PUT When the request is bound to an access token, the covered content
method, the payload of the JWS object is the Base64url encoding MUST also include:
(without padding) of the SHA256 digest of the bytes of the body. If
the request being made does not have a message body, such as an HTTP
GET, OPTIONS, or DELETE method, the JWS signature is calculated over
an empty payload.
The client instance presents the signed object in compact form authorization: The Authorization header used to present the access
[RFC7515] in the Detached-JWS HTTP Header field. token as discussed in Section 7.2.
In this example, the JOSE Header contains the following parameters: Other covered content MAY also be included.
{ If the signer's key presented is a JWK, the "keyid" parameter of the
"alg": "RS256", signature MUST be set to the "kid" value of the JWK, the signing
"kid": "gnap-rsa", algorithm used MUST be the JWS algorithm denoted by the key's "alg"
"uri": "https://server.example.com/gnap", field, and the explicit "alg" signature parameter MUST NOT be
"htm": "POST", included.
"typ": "gnap-binding+jwsd",
"created": 1618884475
}
The request body is the following JSON object: In this example, the message body is the following JSON object:
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.foo/callback", "uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO" "nonce": "VJLO6A4CAYLBXHTR0KRO"
} }
}, },
"client": { "client": {
"proof": "jwsd", "proof": "httpsig",
"key": { "key": {
"jwk": { "jwk": {
"kid": "gnap-rsa", "kid": "gnap-rsa",
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"alg": "RS256", "alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
skipping to change at page 86, line 42 skipping to change at page 85, line 42
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
} }
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://client.foo/" "uri": "https://client.foo/"
}, },
} }
} }
This is hashed to the following Base64 encoded value: This body is hashed for the Digest header using SHA-256 into the
following encoded value:
PGiVuOZUcN1tRtUS6tx2b4cBgw9mPgXG3IPB3wY7ctc SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw=
This leads to the following full HTTP request message: The HTTP message signature input string is calculated to be the
following:
"@request-target": post /gnap
"host": server.example.com
"content-type": application/json
"digest": SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw=
"content-length": 986
"@signature-params": ("@request-target" "host" "content-type" \
"digest" "content-length");created=1618884475;keyid="gnap-rsa"
This leads to the following full HTTP message request:
POST /gnap HTTP/1.1 POST /gnap HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Content-Length: 983 Content-Length: 986
Detached-JWS: eyJhbGciOiJSUzI1NiIsImNyZWF0ZWQiOjE2MTg4ODQ0NzUsImh0b\ Digest: SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw=
SI6IlBPU1QiLCJraWQiOiJnbmFwLXJzYSIsInR5cCI6ImduYXAtYmluZGluZytqd3\ Signature-Input: sig1=("@request-target" "host" "content-type" \
NkIiwidXJpIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vZ25hcCJ9.PGiVuO\ "digest" "content-length");created=1618884475;keyid="gnap-rsa"
ZUcN1tRtUS6tx2b4cBgw9mPgXG3IPB3wY7ctc.fUq-SV-A1iFN2MwCRW_yolVtT2_\ Signature: \
TZA2h5YeXUoi5F2Q2iToC0Tc4drYFOSHIX68knd68RUA7yHqCVP-ZQEd6aL32H69e\ sig1=:axj8FLOvEWBcwh+Xk6VTTKXxqo4XNygleTDJ8h3ZJfi1sSmWrRtyo9RG/dc\
9zuMiw6O_s4TBKB3vDOvwrhYtDH6fX2hP70cQoO-47OwbqP-ifkrvI3hVgMX9TfjV\ miZmdszRjWbg+/ixVZpA4BL3AOwEOxxtmHAXNB8uJ0I3tfbs6Suyk4sEo8zPr+MJq\
eKNwnhoNnw3vbu7SNKeqJEbbwZfpESaGepS52xNBlDNMYBQQXxM9OqKJaXffzLFEl\ MjxdJEUgAQAy2AH+wg5a7CKq4IdLTulFK9njUIeG7MygHumeiumM3DbDQAHgF46dV\
-Xe0UnfolVtBraz3aPrPy1C6a4uT7wLda3PaTOVtgysxzii3oJWpuz0WP5kRujzDF\ q5UC6KJnqhGM1rFC128jd2D0sgWKCUgKGCHtfR159zfKWcEO9krsLoOnCdTzm1UyD\
wX_EOzW0jsjCSkL-PXaKSpZgEjNjKDMg9irSxUISt1C1T6q3SzRgfuQ DMjkIjqeN/1j8PdMJaRAwV4On079O0DVu6bl1jVtkzo/e/ZmwPr/X436V4xiw/hZt\
w4sfNsSbmsT0+UAQ20X/xaw==:
{
"access_token": {
"access": [
"dolphin-metadata"
]
},
"interact": {
"start": ["redirect"],
"finish": {
"method": "redirect",
"uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO"
}
},
"client": {
"proof": "jwsd",
"key": {
"jwk": {
"kid": "gnap-rsa",
"kty": "RSA",
"e": "AQAB",
"alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
}
}
"display": {
"name": "My Client Display Name",
"uri": "https://client.foo/"
},
}
}
When the verifier receives the Detached-JWS header, it MUST parse and
validate the JWS object. The signature MUST be validated against the
expected key of the signer. All required fields MUST be present and
their values MUST be valid. If the HTTP message request contains a
body, the verifier MUST calculate the hash of body just as the signer
does, with no normalization or transformation of the request.
7.3.2. Attached JWS
This method is indicated by "jws" in the "proof" field. A JWS
[RFC7515] object is created as follows:
The JOSE header MUST contain the "kid" parameter of the key bound to
this client instance for this request. The "alg" parameter MUST be
set to a value appropriate for the key identified by kid and MUST NOT
be "none".
To protect the request, the JWS header MUST contain the following
additional parameters.
typ (string) The type header, value "gnap-binding+jws".
htm (string) The HTTP Method used to make this request, as an
uppercase ASCII string.
uri (string) The HTTP URI used for this request, including all path
and query components and no fragment component.
created (integer) A timestamp of when the signature was created, in
integer seconds since UNIX Epoch
ath (string) When a request is bound to an access token, the access
token hash value. The value MUST be the result of Base64url
encoding (with no padding) the SHA-256 digest of the ASCII
encoding of the associated access token's value.
If the HTTP request has a message body, such as an HTTP POST or PUT
method, the payload of the JWS object is the JSON serialized body of
the request, and the object is signed according to JWS and serialized
into compact form [RFC7515]. The client instance presents the JWS as
the body of the request along with a content type of "application/
jose". The AS MUST extract the payload of the JWS and treat it as
the request body for further processing.
If the request being made does not have a message body, such as an
HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated
over an empty payload and passed in the "Detached-JWS" header as
described in Section 7.3.1.
In this example, the JOSE header contains the following parameters:
{
"alg": "RS256",
"kid": "gnap-rsa",
"uri": "https://server.example.com/gnap",
"htm": "POST",
"typ": "gnap-binding+jwsd",
"created": 1618884475
}
The request body, used as the JWS Payload, is the following JSON
object:
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.foo/callback", "uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO" "nonce": "VJLO6A4CAYLBXHTR0KRO"
} }
}, },
"client": { "client": {
"proof": "jws", "proof": "httpsig",
"key": { "key": {
"jwk": { "jwk": {
"kid": "gnap-rsa", "kid": "gnap-rsa",
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"alg": "RS256", "alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\ 3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
} }
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://client.foo/" "uri": "https://client.foo/"
}, },
},
"subject": {
"formats": ["iss_sub", "opaque"]
} }
} }
This leads to the following full HTTP request message: If the HTTP Message includes a message body, the verifier MUST
calculate and verify the value of the "Digest" header. The verifier
POST /gnap HTTP/1.1 MUST ensure that the signature includes all required covered content.
Host: server.example.com The verifier MUST validate the signature against the expected key of
Content-Type: application/jose the signer.
Content-Length: 1047
eyJhbGciOiJSUzI1NiIsImNyZWF0ZWQiOjE2MTg4ODQ0NzUsImh0bSI6IlBPU1QiLCJ\
raWQiOiJnbmFwLXJzYSIsInR5cCI6ImduYXAtYmluZGluZytqd3NkIiwidXJpIjoiaH\
R0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vZ25hcCJ9.CnsKICAgICJhY2Nlc3NfdG9r\
ZW4iOiB7CiAgICAgICAgImFjY2VzcyI6IFsKICAgICAgICAgICAgImRvbHBoaW4tbWV\
0YWRhdGEiCiAgICAgICAgXQogICAgfSwKICAgICJpbnRlcmFjdCI6IHsKICAgICAgIC\
Aic3RhcnQiOiBbInJlZGlyZWN0Il0sCiAgICAgICAgImZpbmlzaCI6IHsKICAgICAgI\
CAgICAgIm1ldGhvZCI6ICJyZWRpcmVjdCIsCiAgICAgICAgICAgICJ1cmkiOiAiaHR0\
cHM6Ly9jbGllbnQuZm9vL2NhbGxiYWNrIiwKICAgICAgICAgICAgIm5vbmNlIjogIlZ\
KTE82QTRDQVlMQlhIVFIwS1JPIgogICAgICAgIH0KICAgIH0sCiAgICAiY2xpZW50Ij\
ogewogICAgICAicHJvb2YiOiAiandzIiwKICAgICAgImtleSI6IHsKICAgICAgICAia\
ndrIjogewogICAgICAgICAgICAia2lkIjogImduYXAtcnNhIiwKICAgICAgICAgICAg\
Imt0eSI6ICJSU0EiLAogICAgICAgICAgICAiZSI6ICJBUUFCIiwKICAgICAgICAgICA\
gImFsZyI6ICJSUzI1NiIsCiAgICAgICAgICAgICJuIjogImhZT0otWE9LSVNkTU1TaG\
5fRzRXOW0yMG1UMFZXdFFCc21CQmtJMmNtUnQ0QWk4QmZZZEhzRnpBdFlLT2pwQlIxU\
nBLcEptVkt4SUdOeTBnNlozYWQyWFlzaDhLb3dseVZ5OElrWjhOTXdTcmNVSUJaR1lY\
akhwd2p6dmZHdlhIXzVLSmxuUjNfdVJVcDRaNFVqazJiQ2FLZWdEbjExVjJ2eEU0MWh\
xYVBVbmhSWnhlMGpSRVRkZHpzRTNtdTFTSzhkVENST2p3VWwxNG1VTm84aVRyVG00bj\
BxRGFkejhCa1BvLXV2NEJDMGJ1blMwSzNiQV8zVWdWcDd6QmxRRm9GbkxUTzJ1V3Bfb\
XVMRVdHbDY3Z0JxOU1PM2JyS1hmR2hpM2tPenl3endQVHVxLWNWUUR5RU43YUwwU3hD\
YjNIYzRJZHFEYU1nOHFIVXlPYnBQaXREUSIKICAgICAgICB9CiAgICAgIH0KICAgICA\
gImRpc3BsYXkiOiB7CiAgICAgICAgIm5hbWUiOiAiTXkgQ2xpZW50IERpc3BsYXkgTm\
FtZSIsCiAgICAgICAgInVyaSI6ICJodHRwczovL2NsaWVudC5mb28vIgogICAgICB9L\
AogICAgfSwKICAgICJzdWJqZWN0IjogewogICAgICAgICJmb3JtYXRzIjogWyJpc3Nf\
c3ViIiwgIm9wYXF1ZSJdCiAgICB9Cn0K.MwNoVMQp5hVxI0mCs9LlOUdFtkDXaA1_eT\
vOXq7DOGrtDKH7q4vP2xUq3fH2jRAZqnobo0WdPP3eM3NH5QUjW8pa6_QpwdIWkK7r-\
u_52puE0lPBp7J4U2w4l9gIbg8iknsmWmXeY5F6wiGT8ptfuEYGgmloAJd9LIeNvD3U\
LW2h2dz1Pn2eDnbyvgB0Ugae0BoZB4f69fKWj8Z9wvTIjk1LZJN1PcL7_zT8Lrlic9a\
PyzT7Q9ovkd1s-4whE7TrnGUzFc5mgWUn_gsOpsP5mIIljoEEv-FqOW2RyNYulOZl0Q\
8EnnDHV_vPzrHlUarbGg4YffgtwkQhdK72-JOxYQ
[[ See issue #109 (https://github.com/ietf-wg-gnap/gnap-core-
protocol/issues/109) ]]
When the verifier receives an attached JWS request, it MUST parse and
validate the JWS object. The signature MUST be validated against the
expected key of the signer. All required fields MUST be present and
their values MUST be valid. If the HTTP message request contains a
body, the verifier MUST decode the payload of the JWS object and
treat this as the HTTP message body.
7.3.3. Mutual TLS 7.3.2. Mutual TLS
This method is indicated by "mtls" in the "proof" field. The signer This method is indicated by "mtls" in the "proof" field. The signer
presents its TLS client certificate during TLS negotiation with the presents its TLS client certificate during TLS negotiation with the
verifier. verifier.
In this example, the certificate is communicated to the application In this example, the certificate is communicated to the application
through the "Client-Cert" header from a TLS reverse proxy, leading to through the "Client-Cert" header from a TLS reverse proxy, leading to
the following full HTTP request message: the following full HTTP request message:
POST /gnap HTTP/1.1 POST /gnap HTTP/1.1
skipping to change at page 94, line 5 skipping to change at page 89, line 21
Note that in many instances, the verifier will not do a full Note that in many instances, the verifier will not do a full
certificate chain validation of the presented TLS client certificate, certificate chain validation of the presented TLS client certificate,
as the means of trust for this certificate could be in something as the means of trust for this certificate could be in something
other than a PKI system, such as a static registration or trust-on- other than a PKI system, such as a static registration or trust-on-
first-use. first-use.
[[ See issue #110 (https://github.com/ietf-wg-gnap/gnap-core- [[ See issue #110 (https://github.com/ietf-wg-gnap/gnap-core-
protocol/issues/110) ]] protocol/issues/110) ]]
7.3.4. Demonstration of Proof-of-Possession (DPoP) 7.3.3. Detached JWS
This method is indicated by "dpop" in the "proof" field. The signer
creates a Demonstration of Proof-of-Possession signature header as
described in [I-D.ietf-oauth-dpop] section 2. In addition, this
specification defines the following fields to be added to the DPoP
payload:
htd (string) Digest of the request body as the value of the Digest
header defined in [RFC3230]. When a request contains a message
body, such as a POST or PUT request, this field is REQUIRED.
In this example, the request body is the following JSON object: ~~~ {
"access_token": { "access": [ "dolphin-metadata" ] }, "interact": {
"start": ["redirect"], "finish": { "method": "redirect", "uri":
"https://client.foo/callback", "nonce": "VJLO6A4CAYLBXHTR0KRO" } },
"client": { "proof": "dpop", "key": { "jwk": { "kid": "gnap-rsa",
"kty": "RSA", "e": "AQAB", "alg": "RS256", "n": "hYOJ-
XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" } } "display": { "name": "My
Client Display Name", "uri": "https://client.foo/" }, } } ~~~
The JOSE header contains the following parameters, including the
public key:
{
"alg": "RS256",
"typ": "dpop+jwt",
"jwk": {
"kid": "gnap-rsa",
"kty": "RSA",
"e": "AQAB",
"alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8BfYdHs\
FzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZGYXjH\
pwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jRETdd\
zsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_3UgV\
p7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyEN7aL\
0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
}
}
The JWS Payload contains the following JWT claims, including a hash
of the body:
{
"htu": "https://server.example.com/gnap",
"htm": "POST",
"iat": 1618884475,
"jti": "HjoHrjgm2yB4x7jA5yyG",
"htd": "SHA-256=tnPQ2GXm8r/rTTKdbQ8pc7EjiFFPy1ExSX6OZVG3JVI="
}
This results in the following full HTTP message request: This method is indicated by "jwsd" in the "proof" field. A JWS
[RFC7515] object is created as follows:
POST /gnap HTTP/1.1 To protect the request, the JOSE header of the signature contains the
Host: server.example.com following parameters:
Content-Type: application/json
Content-Length: 983
DPoP: eyJhbGciOiJSUzI1NiIsImp3ayI6eyJhbGciOiJSUzI1NiIsImUiOiJBUUFCI\
iwia2lkIjoiZ25hcC1yc2EiLCJrdHkiOiJSU0EiLCJuIjoiaFlPSi1YT0tJU2RNTV\
Nobl9HNFc5bTIwbVQwVld0UUJzbUJCa0kyY21SdDRBaThCZllkSHNGekF0WUtPanB\
CUjFScEtwSm1WS3hJR055MGc2WjNhZDJYWXNoOEtvd2x5Vnk4SWtaOE5Nd1NyY1VJ\
QlpHWVhqSHB3anp2Zkd2WEhfNUtKbG5SM191UlVwNFo0VWprMmJDYUtlZ0RuMTFWM\
nZ4RTQxaHFhUFVuaFJaeGUwalJFVGRkenNFM211MVNLOGRUQ1JPandVbDE0bVVObz\
hpVHJUbTRuMHFEYWR6OEJrUG8tdXY0QkMwYnVuUzBLM2JBXzNVZ1ZwN3pCbFFGb0Z\
uTFRPMnVXcF9tdUxFV0dsNjdnQnE5TU8zYnJLWGZHaGkza096eXd6d1BUdXEtY1ZR\
RHlFTjdhTDBTeENiM0hjNElkcURhTWc4cUhVeU9icFBpdERRIn0sInR5cCI6ImRwb\
3Arand0In0.eyJodHUiOiJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbS9nbmFwIi\
wiaHRtIjoiUE9TVCIsImlhdCI6MTYxODg4NDQ3NSwianRpIjoiSGpvSHJqZ20yeUI\
0eDdqQTV5eUciLCJodGQiOiJTSEEtMjU2PXRuUFEyR1htOHIvclRUS2RiUThwYzdF\
amlGRlB5MUV4U1g2T1pWRzNKVkk9In0.HLRh7n-3uwnSGCBGbSFitNCxgmJnpp6hs\
sF8o_u2Xbuzu3pyR4v8SJVP17tjqxuySf91lmC1gjJeK4pXvWOtfeWGuDjD7nr6aw\
pBOtiQXeBtoqiiK2ByBZO-mhccJeNkTkRfxGDtU0iJo6iarWjRgQOsPbt69FIwTP4\
Abovwv7yBCthQs3TMsBtb8-l4Lu30wNLwXEWcB-o8nFNpT4zgV9ETGoCOcBFwBjjt\
0khsCarleTBsOZ2zUuFwZMWi_bQYfd-M0pahWYro9Mdy3Fts-aUqZjS2LwHHNWvjw\
rTzz6icCHwnr9dm1Ls6orbM7xMzvHAOA5TZW39yFg_Xr5PNYg
{ kid (string) The key identifier. RECOMMENDED. If the key is
"access_token": { presented in JWK format, this MUST be the value of the "kid" field
"access": [ of the key.
"dolphin-metadata"
]
},
"interact": {
"start": ["redirect"],
"finish": {
"method": "redirect",
"uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO"
}
},
"client": {
"proof": "dpop",
"key": {
"jwk": {
"kid": "gnap-rsa",
"kty": "RSA",
"e": "AQAB",
"alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
}
}
"display": {
"name": "My Client Display Name",
"uri": "https://client.foo/"
},
}
}
The verifier MUST parse and validate the DPoP proof header as defined alg (string) The algorithm used to sign the request. REQUIRED.
in [I-D.ietf-oauth-dpop]. If the HTTP message request includes a MUST be appropriate to the key presented. If the key is presented
message body, the verifier MUST calculate the digest of the body and as a JWK, this MUST be equal to the "alg" parameter of the key.
compare it to the "htd" value. The verifier MUST ensure the key MUST NOT be "none".
presented in the DPoP proof header is the same as the expected key of
the signer.
7.3.5. HTTP Message Signing typ (string) The type header, value "gnap-binding+jwsd". REQUIRED
This method is indicated by "httpsig" in the "proof" field. The htm (string) The HTTP Method used to make this request, as an
sender creates an HTTP Message Signature as described in uppercase ASCII string. REQUIRED
[I-D.ietf-httpbis-message-signatures].
The covered content of the signature MUST include the following: uri (string) The HTTP URI used for this request, including all path
and query components and no fragment component. REQUIRED
@request-target: the target of the HTTP request created (integer) A timestamp of when the signature was created, in
integer seconds since UNIX Epoch
digest: The Digest header as defined in [RFC3230]. When the request ath (string) When a request is bound to an access token, the access
message has a body, the signer MUST calculate this header value token hash value. The value MUST be the result of Base64url
and the verifier MUST validate this header. encoding (with no padding) the SHA-256 digest of the ASCII
encoding of the associated access token's value. REQUIRED if the
request protects an access token.
When the request is bound to an access token, the covered content If the HTTP request has a message body, such as an HTTP POST or PUT
MUST also include: method, the payload of the JWS object is the Base64url encoding
(without padding) of the SHA256 digest of the bytes of the body. If
the request being made does not have a message body, such as an HTTP
GET, OPTIONS, or DELETE method, the JWS signature is calculated over
an empty payload.
authorization: The Authorization header used to present the access The client instance presents the signed object in compact form
token as discussed in Section 7.2. [RFC7515] in the Detached-JWS HTTP Header field.
Other covered content MAY also be included. In this example, the JOSE Header contains the following parameters:
If the signer's key presented is a JWK, the "keyid" parameter of the {
signature MUST be set to the "kid" value of the JWK, the signing "alg": "RS256",
algorithm used MUST be the JWS algorithm denoted by the key's "alg" "kid": "gnap-rsa",
field, and the explicit "alg" signature parameter MUST NOT be "uri": "https://server.example.com/gnap",
included. "htm": "POST",
"typ": "gnap-binding+jwsd",
"created": 1618884475
}
In this example, the message body is the following JSON object: The request body is the following JSON object:
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.foo/callback", "uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO" "nonce": "VJLO6A4CAYLBXHTR0KRO"
} }
}, },
"client": { "client": {
"proof": "httpsig", "proof": "jwsd",
"key": { "key": {
"jwk": { "jwk": {
"kid": "gnap-rsa", "kid": "gnap-rsa",
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"alg": "RS256", "alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\ 3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
} }
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://client.foo/" "uri": "https://client.foo/"
}, },
} }
} }
This body is hashed for the Digest header using SHA-256 into the
following encoded value:
SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw= This is hashed to the following Base64 encoded value:
The HTTP message signature input string is calculated to be the
following:
"@request-target": post /gnap PGiVuOZUcN1tRtUS6tx2b4cBgw9mPgXG3IPB3wY7ctc
"host": server.example.com
"content-type": application/json
"digest": SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw=
"content-length": 986
"@signature-params": ("@request-target" "host" "content-type" \
"digest" "content-length");created=1618884475;keyid="gnap-rsa"
This leads to the following full HTTP message request: This leads to the following full HTTP request message:
POST /gnap HTTP/1.1 POST /gnap HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Content-Length: 986 Content-Length: 983
Digest: SHA-256=98QzyNVYpdgTrWBKpC4qFSCmmR+CrwwvUoiaDCSjKxw= Detached-JWS: eyJhbGciOiJSUzI1NiIsImNyZWF0ZWQiOjE2MTg4ODQ0NzUsImh0b\
Signature-Input: sig1=("@request-target" "host" "content-type" \ SI6IlBPU1QiLCJraWQiOiJnbmFwLXJzYSIsInR5cCI6ImduYXAtYmluZGluZytqd3\
"digest" "content-length");created=1618884475;keyid="gnap-rsa" NkIiwidXJpIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vZ25hcCJ9.PGiVuO\
Signature: \ ZUcN1tRtUS6tx2b4cBgw9mPgXG3IPB3wY7ctc.fUq-SV-A1iFN2MwCRW_yolVtT2_\
sig1=:axj8FLOvEWBcwh+Xk6VTTKXxqo4XNygleTDJ8h3ZJfi1sSmWrRtyo9RG/dc\ TZA2h5YeXUoi5F2Q2iToC0Tc4drYFOSHIX68knd68RUA7yHqCVP-ZQEd6aL32H69e\
miZmdszRjWbg+/ixVZpA4BL3AOwEOxxtmHAXNB8uJ0I3tfbs6Suyk4sEo8zPr+MJq\ 9zuMiw6O_s4TBKB3vDOvwrhYtDH6fX2hP70cQoO-47OwbqP-ifkrvI3hVgMX9TfjV\
MjxdJEUgAQAy2AH+wg5a7CKq4IdLTulFK9njUIeG7MygHumeiumM3DbDQAHgF46dV\ eKNwnhoNnw3vbu7SNKeqJEbbwZfpESaGepS52xNBlDNMYBQQXxM9OqKJaXffzLFEl\
q5UC6KJnqhGM1rFC128jd2D0sgWKCUgKGCHtfR159zfKWcEO9krsLoOnCdTzm1UyD\ -Xe0UnfolVtBraz3aPrPy1C6a4uT7wLda3PaTOVtgysxzii3oJWpuz0WP5kRujzDF\
DMjkIjqeN/1j8PdMJaRAwV4On079O0DVu6bl1jVtkzo/e/ZmwPr/X436V4xiw/hZt\ wX_EOzW0jsjCSkL-PXaKSpZgEjNjKDMg9irSxUISt1C1T6q3SzRgfuQ
w4sfNsSbmsT0+UAQ20X/xaw==:
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.foo/callback", "uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO" "nonce": "VJLO6A4CAYLBXHTR0KRO"
} }
}, },
"client": { "client": {
"proof": "httpsig", "proof": "jwsd",
"key": { "key": {
"jwk": { "jwk": {
"kid": "gnap-rsa", "kid": "gnap-rsa",
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"alg": "RS256", "alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
skipping to change at page 99, line 23 skipping to change at page 93, line 4
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\ 3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
} }
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://client.foo/" "uri": "https://client.foo/"
}, },
} }
} }
If the HTTP Message includes a message body, the verifier MUST When the verifier receives the Detached-JWS header, it MUST parse and
calculate and verify the value of the "Digest" header. The verifier validate the JWS object. The signature MUST be validated against the
MUST ensure that the signature includes all required covered content. expected key of the signer. All required fields MUST be present and
The verifier MUST validate the signature against the expected key of their values MUST be valid. If the HTTP message request contains a
the signer. body, the verifier MUST calculate the hash of body just as the signer
does, with no normalization or transformation of the request.
7.3.6. OAuth Proof of Possession (PoP) 7.3.4. Attached JWS
This method is indicated by "oauthpop" in the "proof" field. The This method is indicated by "jws" in the "proof" field. A JWS
signer creates an HTTP Authorization PoP header as described in [RFC7515] object is created as follows:
[I-D.ietf-oauth-signed-http-request] section 4, with the following
additional requirements:
* The "at" (access token) field MUST be omitted unless this method The JOSE header MUST contain the "kid" parameter of the key bound to
is being used in conjunction with an access token as in this client instance for this request. The "alg" parameter MUST be
Section 7.2. [[ See issue #112 (https://github.com/ietf-wg-gnap/ set to a value appropriate for the key identified by kid and MUST NOT
gnap-core-protocol/issues/112) ]] be "none".
* The "b" (body hash) field MUST be calculated and included, if the To protect the request, the JWS header MUST contain the following
message includes an entity body (such as a PUT or PATCH request). additional parameters.
* All components of the URL MUST be calculated and included, typ (string) The type header, value "gnap-binding+jws".
including query parameters "q", path "p", and host "u".
* The "m" (method) field MUST be included htm (string) The HTTP Method used to make this request, as an
In this example, the request message body is the following JSON uppercase ASCII string.
object
{ uri (string) The HTTP URI used for this request, including all path
"access_token": { and query components and no fragment component.
"access": [
"dolphin-metadata"
]
},
"interact": {
"start": ["redirect"],
"finish": {
"method": "redirect",
"uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO"
}
},
"client": {
"proof": "oauthpop",
"key": {
"jwk": {
"kid": "gnap-rsa",
"kty": "RSA",
"e": "AQAB",
"alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
}
}
"display": {
"name": "My Client Display Name",
"uri": "https://client.foo/"
},
}
}
The JOSE header for the PoP token is the following: created (integer) A timestamp of when the signature was created, in
integer seconds since UNIX Epoch
{ ath (string) When a request is bound to an access token, the access
"alg": "RS256", token hash value. The value MUST be the result of Base64url
"kid": "gnap-rsa" encoding (with no padding) the SHA-256 digest of the ASCII
} encoding of the associated access token's value.
After calculating the hashes for the body, headers, and URL
components, the JWS Payload is the following: If the HTTP request has a message body, such as an HTTP POST or PUT
method, the payload of the JWS object is the JSON serialized body of
the request, and the object is signed according to JWS and serialized
into compact form [RFC7515]. The client instance presents the JWS as
the body of the request along with a content type of "application/
jose". The AS MUST extract the payload of the JWS and treat it as
the request body for further processing.
If the request being made does not have a message body, such as an
HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated
over an empty payload and passed in the "Detached-JWS" header as
described in Section 7.3.3.
In this example, the JOSE header contains the following parameters:
{ {
"u": "server.example.com", "alg": "RS256",
"p": "/gnap", "kid": "gnap-rsa",
"m": "POST", "uri": "https://server.example.com/gnap",
"ts": 1618884475, "htm": "POST",
"b": "sCvbP9VqOcq4LHkVDcayon2MoT4xPGc49TEnqsr6WYE", "typ": "gnap-binding+jwsd",
"h": [ "created": 1618884475
[
"content-type",
"content-length"
],
"EJit2-669uk8JUzLJbidMFRkATuZOimvCOieXPjtEmU"
]
} }
This leads to the following HTTP message request: The request body, used as the JWS Payload, is the following JSON
object:
POST /gnap HTTP/1.1
Host: server.example.com
Content-Type: application/json
Content-Length: 987
PoP: eyJhbGciOiJSUzI1NiIsImtpZCI6ImduYXAtcnNhIn0.eyJ1Ijoic2VydmVyLm\
V4YW1wbGUuY29tIiwicCI6Ii9nbmFwIiwibSI6IlBPU1QiLCJ0cyI6MTYxODg4NDQ\
3NSwiYiI6InNDdmJQOVZxT2NxNExIa1ZEY2F5b24yTW9UNHhQR2M0OVRFbnFzcjZX\
WUUiLCJoIjpbWyJjb250ZW50LXR5cGUiLCJjb250ZW50LWxlbmd0aCJdLCJFSml0M\
i02Njl1azhKVXpMSmJpZE1GUmtBVHVaT2ltdkNPaWVYUGp0RW1VIl19.doLbW-VA7\
HnyeyEbl4qmcPUkiQrXIG53oSZLGrUHhs7CL9X9kd_-1j8lxyT7tWJLtjoIgDtVVn\
PN69xP-Vs9-Cx5uV4VfLKRO7O9GmdGUOXx9eP53Q4hf8UPMrfbyAEeluznajC21o9\
AriBDMyjmV4A4JkZn3A7v72zE0z1CQfqUsdfomeB_SmFlMhcsO8KsT1vG6iOmuE0x\
3rGjJvyohNUQvkzWvaP37nLTZol8VFWinlXGv-4cOx3YWgZUn_RNk7cH6ALHlzgnl\
8t1YhA14AFdVmCGaeJMDKmb5Jt7g0UnOp1BYR9j1DeUP64RQU6lH_8A1MMIc5iBwD\
yx433wxQ
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata" "dolphin-metadata"
] ]
}, },
"interact": { "interact": {
"start": ["redirect"], "start": ["redirect"],
"finish": { "finish": {
"method": "redirect", "method": "redirect",
"uri": "https://client.foo/callback", "uri": "https://client.foo/callback",
"nonce": "VJLO6A4CAYLBXHTR0KRO" "nonce": "VJLO6A4CAYLBXHTR0KRO"
} }
}, },
"client": { "client": {
"proof": "oauthpop", "proof": "jws",
"key": { "key": {
"jwk": { "jwk": {
"kid": "gnap-rsa", "kid": "gnap-rsa",
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"alg": "RS256", "alg": "RS256",
"n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\ "n": "hYOJ-XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf\
YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\ YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG\
YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\ YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR\
ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\ ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_\
3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\ 3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE\
N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ"
} }
} }
"display": { "display": {
"name": "My Client Display Name", "name": "My Client Display Name",
"uri": "https://client.foo/" "uri": "https://client.foo/"
}, },
},
"subject": {
"formats": ["iss_sub", "opaque"]
} }
} }
[[ See issue #113 (https://github.com/ietf-wg-gnap/gnap-core- This leads to the following full HTTP request message:
protocol/issues/113) ]]
The verifier MUST parse the JWS object of the PoP header. The POST /gnap HTTP/1.1
verifier MUST validate the signature of the header against the Host: server.example.com
expected key of the signer. The verifier MUST ensure that all Content-Type: application/jose
required parts of the message are covered by the signature. The Content-Length: 1047
verifier MUST ensure that all components of the signature contain
correct values. eyJhbGciOiJSUzI1NiIsImNyZWF0ZWQiOjE2MTg4ODQ0NzUsImh0bSI6IlBPU1QiLCJ\
raWQiOiJnbmFwLXJzYSIsInR5cCI6ImduYXAtYmluZGluZytqd3NkIiwidXJpIjoiaH\
R0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vZ25hcCJ9.CnsKICAgICJhY2Nlc3NfdG9r\
ZW4iOiB7CiAgICAgICAgImFjY2VzcyI6IFsKICAgICAgICAgICAgImRvbHBoaW4tbWV\
0YWRhdGEiCiAgICAgICAgXQogICAgfSwKICAgICJpbnRlcmFjdCI6IHsKICAgICAgIC\
Aic3RhcnQiOiBbInJlZGlyZWN0Il0sCiAgICAgICAgImZpbmlzaCI6IHsKICAgICAgI\
CAgICAgIm1ldGhvZCI6ICJyZWRpcmVjdCIsCiAgICAgICAgICAgICJ1cmkiOiAiaHR0\
cHM6Ly9jbGllbnQuZm9vL2NhbGxiYWNrIiwKICAgICAgICAgICAgIm5vbmNlIjogIlZ\
KTE82QTRDQVlMQlhIVFIwS1JPIgogICAgICAgIH0KICAgIH0sCiAgICAiY2xpZW50Ij\
ogewogICAgICAicHJvb2YiOiAiandzIiwKICAgICAgImtleSI6IHsKICAgICAgICAia\
ndrIjogewogICAgICAgICAgICAia2lkIjogImduYXAtcnNhIiwKICAgICAgICAgICAg\
Imt0eSI6ICJSU0EiLAogICAgICAgICAgICAiZSI6ICJBUUFCIiwKICAgICAgICAgICA\
gImFsZyI6ICJSUzI1NiIsCiAgICAgICAgICAgICJuIjogImhZT0otWE9LSVNkTU1TaG\
5fRzRXOW0yMG1UMFZXdFFCc21CQmtJMmNtUnQ0QWk4QmZZZEhzRnpBdFlLT2pwQlIxU\
nBLcEptVkt4SUdOeTBnNlozYWQyWFlzaDhLb3dseVZ5OElrWjhOTXdTcmNVSUJaR1lY\
akhwd2p6dmZHdlhIXzVLSmxuUjNfdVJVcDRaNFVqazJiQ2FLZWdEbjExVjJ2eEU0MWh\
xYVBVbmhSWnhlMGpSRVRkZHpzRTNtdTFTSzhkVENST2p3VWwxNG1VTm84aVRyVG00bj\
BxRGFkejhCa1BvLXV2NEJDMGJ1blMwSzNiQV8zVWdWcDd6QmxRRm9GbkxUTzJ1V3Bfb\
XVMRVdHbDY3Z0JxOU1PM2JyS1hmR2hpM2tPenl3endQVHVxLWNWUUR5RU43YUwwU3hD\
YjNIYzRJZHFEYU1nOHFIVXlPYnBQaXREUSIKICAgICAgICB9CiAgICAgIH0KICAgICA\
gImRpc3BsYXkiOiB7CiAgICAgICAgIm5hbWUiOiAiTXkgQ2xpZW50IERpc3BsYXkgTm\
FtZSIsCiAgICAgICAgInVyaSI6ICJodHRwczovL2NsaWVudC5mb28vIgogICAgICB9L\
AogICAgfSwKICAgICJzdWJqZWN0IjogewogICAgICAgICJmb3JtYXRzIjogWyJpc3Nf\
c3ViIiwgIm9wYXF1ZSJdCiAgICB9Cn0K.MwNoVMQp5hVxI0mCs9LlOUdFtkDXaA1_eT\
vOXq7DOGrtDKH7q4vP2xUq3fH2jRAZqnobo0WdPP3eM3NH5QUjW8pa6_QpwdIWkK7r-\
u_52puE0lPBp7J4U2w4l9gIbg8iknsmWmXeY5F6wiGT8ptfuEYGgmloAJd9LIeNvD3U\
LW2h2dz1Pn2eDnbyvgB0Ugae0BoZB4f69fKWj8Z9wvTIjk1LZJN1PcL7_zT8Lrlic9a\
PyzT7Q9ovkd1s-4whE7TrnGUzFc5mgWUn_gsOpsP5mIIljoEEv-FqOW2RyNYulOZl0Q\
8EnnDHV_vPzrHlUarbGg4YffgtwkQhdK72-JOxYQ
[[ See issue #109 (https://github.com/ietf-wg-gnap/gnap-core-
protocol/issues/109) ]]
When the verifier receives an attached JWS request, it MUST parse and
validate the JWS object. The signature MUST be validated against the
expected key of the signer. All required fields MUST be present and
their values MUST be valid. If the HTTP message request contains a
body, the verifier MUST decode the payload of the JWS object and
treat this as the HTTP message body.
8. Resource Access Rights 8. Resource Access Rights
GNAP provides a rich structure for describing the protected resources GNAP provides a rich structure for describing the protected resources
hosted by RSs and accessed by client software. This structure is hosted by RSs and accessed by client software. This structure is
used when the client instance requests an access token (Section 2.1) used when the client instance requests an access token (Section 2.1)
and when an access token is returned (Section 3.2). and when an access token is returned (Section 3.2).
The root of this structure is a JSON array. The elements of the JSON The root of this structure is a JSON array. The elements of the JSON
array represent rights of access that are associated with the the array represent rights of access that are associated with the the
skipping to change at page 103, line 46 skipping to change at page 98, line 9
datatypes (array of strings) The kinds of data available to the datatypes (array of strings) The kinds of data available to the
client instance at the RS's API as an array of strings. For client instance at the RS's API as an array of strings. For
example, a client instance asking for access to raw "image" data example, a client instance asking for access to raw "image" data
and "metadata" at a photograph API. and "metadata" at a photograph API.
identifier (string) A string identifier indicating a specific identifier (string) A string identifier indicating a specific
resource at the RS. For example, a patient identifier for a resource at the RS. For example, a patient identifier for a
medical API or a bank account number for a financial API. medical API or a bank account number for a financial API.
privileges (array of strings) The types or levels of privilege being
requested at the resource. For example, a client instance asking
for administrative level access, or access when the resource owner
is no longer online.
The following non-normative example is describing three kinds of The following non-normative example is describing three kinds of
access (read, write, delete) to each of two different locations and access (read, write, delete) to each of two different locations and
two different data types (metadata, images) for a single access token two different data types (metadata, images) for a single access token
using the fictitious "photo-api" type definition. using the fictitious "photo-api" type definition.
"access": [ "access": [
{ {
"type": "photo-api", "type": "photo-api",
"actions": [ "actions": [
"read", "read",
skipping to change at page 109, line 10 skipping to change at page 103, line 10
endpoint to retrieve the server's discovery information. The AS MUST endpoint to retrieve the server's discovery information. The AS MUST
respond with a JSON document containing the following information: respond with a JSON document containing the following information:
grant_request_endpoint (string) REQUIRED. The location of the AS's grant_request_endpoint (string) REQUIRED. The location of the AS's
grant request endpoint. The location MUST be a URL [RFC3986] with grant request endpoint. The location MUST be a URL [RFC3986] with
a scheme component that MUST be https, a host component, and a scheme component that MUST be https, a host component, and
optionally, port, path and query components and no fragment optionally, port, path and query components and no fragment
components. This URL MUST match the URL the client instance used components. This URL MUST match the URL the client instance used
to make the discovery request. to make the discovery request.
capabilities (array of strings) OPTIONAL. A list of the AS's interaction_start_modes_supported (array of strings) OPTIONAL. A
capabilities. The values of this result MAY be used by the client list of the AS's interaction start methods. The values of this
instance in the capabilities section (Section 2.6) of the request. list correspond to the possible values for the interaction start
section (Section 2.5.1) of the request.
interaction_methods_supported (array of strings) OPTIONAL. A list interaction_finish_methods_supported (array of strings) OPTIONAL. A
of the AS's interaction methods. The values of this list list of the AS's interaction finish methods. The values of this
correspond to the possible fields in the interaction section list correspond to the possible values for the method element of
(Section 2.5) of the request. the interaction finish section (Section 2.5.2) of the request.
key_proofs_supported (array of strings) OPTIONAL. A list of the key_proofs_supported (array of strings) OPTIONAL. A list of the
AS's supported key proofing mechanisms. The values of this list AS's supported key proofing mechanisms. The values of this list
correspond to possible values of the "proof" field of the key correspond to possible values of the "proof" field of the key
section (Section 7.1) of the request. section (Section 7.1) of the request.
subject_formats_supported (array of strings) OPTIONAL. A list of subject_formats_supported (array of strings) OPTIONAL. A list of
the AS's supported subject identifier types. The values of this the AS's supported subject identifier types. The values of this
list correspond to possible values of the subject identifier list correspond to possible values of the subject identifier
section (Section 2.2) of the request. section (Section 2.2) of the request.
skipping to change at page 109, line 42 skipping to change at page 103, line 43
(Section 2.2) of the request. (Section 2.2) of the request.
The information returned from this method is for optimization The information returned from this method is for optimization
purposes only. The AS MAY deny any request, or any portion of a purposes only. The AS MAY deny any request, or any portion of a
request, even if it lists a capability as supported. For example, a request, even if it lists a capability as supported. For example, a
given client instance can be registered with the "mtls" key proofing given client instance can be registered with the "mtls" key proofing
mechanism, but the AS also returns other proofing methods, then the mechanism, but the AS also returns other proofing methods, then the
AS will deny a request from that client instance using a different AS will deny a request from that client instance using a different
proofing mechanism. proofing mechanism.
9.1. RS-first Method of AS Discovery
If the client instance calls an RS without an access token, or with
an invalid access token, the RS MAY respond to the client instance
with an authentication header indicating that GNAP needs to be used
to access the resource. The address of the GNAP endpoint MUST be
sent in the "as_uri" parameter. The RS MAY additionally return a
resource reference that the client instance MAY use in its access
token request. This resource reference MUST be sufficient for at
least the action the client instance was attempting to take at the RS
and MAY be more powerful. The means for the RS to determine the
resource reference are out of scope of this specification, but some
dynamic methods are discussed in
[I-D.draft-ietf-gnap-resource-servers]. The content of the resource
handle is opaque to the client instance.
WWW-Authenticate: \
GNAP as_uri=https://server.example/tx,access=FWWIKYBQ6U56NL1
The client instance then makes a request to the "as_uri" as described
in Section 2, with the value of "access" as one of the members of the
"access" array in the "access_token" portion of the request. The
client instance MAY request additional resources and other
information. The client instance MAY request multiple access tokens.
In this non-normative example, the client instance is requesting a
single access token using the resource reference "FWWIKYBQ6U56NL1"
received from the RS in addition to the "dolphin-metadata" resource
reference that the client instance has been configured with out of
band.
POST /tx HTTP/1.1
Host: server.example.com
Content-Type: application/json
Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{
"access_token": {
"access": [
"FWWIKYBQ6U56NL1",
"dolphin-metadata"
]
},
"client": "KHRS6X63AJ7C7C4AZ9AO"
}
If issued, the resulting access token would contain sufficient access
to be used at both referenced resources.
10. Acknowledgements 10. Acknowledgements
The editors would like to thank the feedback of the following The editors would like to thank the feedback of the following
individuals for their reviews, implementations, and contributions: individuals for their reviews, implementations, and contributions:
Aaron Parecki, Annabelle Backman, Dick Hardt, Dmitri Zagidulin, Aeke Axeland, Aaron Parecki, Adam Omar Oueidat, Annabelle Backman,
Dmitry Barinov, Fabien Imbault, Francis Pouatcha, George Fletcher, Dick Hardt, Dmitri Zagidulin, Dmitry Barinov, Fabien Imbault, Francis
Haardik Haardik, Hamid Massaoud, Jacky Yuan, Joseph Heenan, Justin Pouatcha, George Fletcher, Haardik Haardik, Hamid Massaoud, Jacky
Richer, Kathleen Moriarty, Mike Jones, Mike Varley, Nat Sakimura, Yuan, Joseph Heenan, Justin Richer, Kathleen Moriarty, Mike Jones,
Takahiko Kawasaki, Takahiro Tsuchiya. Mike Varley, Nat Sakimura, Takahiko Kawasaki, Takahiro Tsuchiya.
The editors would also like to thank the GNAP working group design The editors would also like to thank the GNAP working group design
team of Kathleen Moriarty, Fabien Imbault, Dick Hardt, Mike Jones, team of Kathleen Moriarty, Fabien Imbault, Dick Hardt, Mike Jones,
and Justin Richer, who incorporated elements from the XAuth and XYZ and Justin Richer, who incorporated elements from the XAuth and XYZ
proposals to create the first version of this document. proposals to create the first version of this document.
In addition, the editors would like to thank Aaron Parecki and Mike In addition, the editors would like to thank Aaron Parecki and Mike
Jones for insights into how to integrate identity and authentication Jones for insights into how to integrate identity and authentication
systems into the core protocol, and Justin Richer and Dick Hardt for systems into the core protocol, and Justin Richer and Dick Hardt for
the use cases, diagrams, and insights provided in the XYZ and XAuth the use cases, diagrams, and insights provided in the XYZ and XAuth
skipping to change at page 110, line 51 skipping to change at page 106, line 12
14. Normative References 14. Normative References
[BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre,
"Recommendations for Secure Use of Transport Layer "Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security Security (TLS) and Datagram Transport Layer Security
(DTLS)", May 2015, (DTLS)", May 2015,
<https://www.rfc-editor.org/info/bcp195>. <https://www.rfc-editor.org/info/bcp195>.
[I-D.draft-ietf-gnap-resource-servers] [I-D.draft-ietf-gnap-resource-servers]
"*** BROKEN REFERENCE ***". Richer, J., Parecki, A., and F. Imbault, "Grant
Negotiation and Authorization Protocol Resource Server
Connections", Work in Progress, Internet-Draft, draft-
ietf-gnap-resource-servers-00, 28 April 2021,
<https://www.ietf.org/archive/id/draft-ietf-gnap-resource-
servers-00.txt>.
[I-D.ietf-httpbis-message-signatures] [I-D.ietf-httpbis-message-signatures]
Backman, A., Richer, J., and M. Sporny, "Signing HTTP Backman, A., Richer, J., and M. Sporny, "Signing HTTP
Messages", Work in Progress, Internet-Draft, draft-ietf- Messages", Work in Progress, Internet-Draft, draft-ietf-
httpbis-message-signatures-04, 21 April 2021, httpbis-message-signatures-05, 8 June 2021,
<https://www.ietf.org/archive/id/draft-ietf-httpbis- <https://www.ietf.org/archive/id/draft-ietf-httpbis-
message-signatures-04.txt>. message-signatures-05.txt>.
[I-D.ietf-oauth-dpop]
Fett, D., Campbell, B., Bradley, J., Lodderstedt, T.,
Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof-
of-Possession at the Application Layer (DPoP)", Work in
Progress, Internet-Draft, draft-ietf-oauth-dpop-03, 7
April 2021, <https://www.ietf.org/archive/id/draft-ietf-
oauth-dpop-03.txt>.
[I-D.ietf-oauth-rar] [I-D.ietf-oauth-rar]
Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0 Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0
Rich Authorization Requests", Work in Progress, Internet- Rich Authorization Requests", Work in Progress, Internet-
Draft, draft-ietf-oauth-rar-04, 7 February 2021, Draft, draft-ietf-oauth-rar-05, 15 May 2021,
<https://www.ietf.org/archive/id/draft-ietf-oauth-rar- <https://www.ietf.org/archive/id/draft-ietf-oauth-rar-
04.txt>. 05.txt>.
[I-D.ietf-oauth-signed-http-request] [I-D.ietf-oauth-signed-http-request]
Richer, J., Bradley, J., and H. Tschofenig, "A Method for Richer, J., Bradley, J., and H. Tschofenig, "A Method for
Signing HTTP Requests for OAuth", Work in Progress, Signing HTTP Requests for OAuth", Work in Progress,
Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8 Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8
August 2016, <https://www.ietf.org/archive/id/draft-ietf- August 2016, <https://www.ietf.org/archive/id/draft-ietf-
oauth-signed-http-request-03.txt>. oauth-signed-http-request-03.txt>.
[I-D.ietf-secevent-subject-identifiers] [I-D.ietf-secevent-subject-identifiers]
Backman, A. and M. Scurtescu, "Subject Identifiers for Backman, A. and M. Scurtescu, "Subject Identifiers for
Security Event Tokens", Work in Progress, Internet-Draft, Security Event Tokens", Work in Progress, Internet-Draft,
draft-ietf-secevent-subject-identifiers-07, 8 March 2021, draft-ietf-secevent-subject-identifiers-08, 24 May 2021,
<https://www.ietf.org/archive/id/draft-ietf-secevent- <https://www.ietf.org/archive/id/draft-ietf-secevent-
subject-identifiers-07.txt>. subject-identifiers-08.txt>.
[OIDC] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and [OIDC] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and
C. Mortimore, "OpenID Connect Core 1.0 incorporating C. Mortimore, "OpenID Connect Core 1.0 incorporating
errata set 1", November 2014, errata set 1", November 2014,
<https://openiD.net/specs/openiD-connect-core-1_0.html>. <https://openiD.net/specs/openiD-connect-core-1_0.html>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
skipping to change at page 113, line 18 skipping to change at page 108, line 23
DOI 10.17487/RFC8705, February 2020, DOI 10.17487/RFC8705, February 2020,
<https://www.rfc-editor.org/info/rfc8705>. <https://www.rfc-editor.org/info/rfc8705>.
[RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu,
"Handling Long Lines in Content of Internet-Drafts and "Handling Long Lines in Content of Internet-Drafts and
RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020,
<https://www.rfc-editor.org/info/rfc8792>. <https://www.rfc-editor.org/info/rfc8792>.
Appendix A. Document History Appendix A. Document History
* -05 * -06
- Removed "capabilities" and "existing_grant" protocol fields.
- Removed separate "instance_id" field.
- Split "interaction_methods_supported" into
"interaction_start_modes_supported" and
"interaction_finish_methods_supported".
- Added AS endpoint to hash calculation to fix mix-up attack.
- Added "privileges" field to resource access request object.
- Moved client-facing RS response back from GNAP-RS document.
- Removed oauthpop key binding.
- Removed dpop key binding.
- Added example DID identifier.
- Changed token response booleans to flag structure to match
request.
- Updated signature examples to use HTTP Message Signatures.
* -05
- Changed "interaction_methods" to - Changed "interaction_methods" to
"interaction_methods_supported". "interaction_methods_supported".
- Changed "key_proofs" to "key_proofs_supported". - Changed "key_proofs" to "key_proofs_supported".
- Changed "assertions" to "assertions_supported". - Changed "assertions" to "assertions_supported".
- Updated discovery and field names for subject formats. - Updated discovery and field names for subject formats.
- Add an appendix to provide protocol rationale, compared to - Add an appendix to provide protocol rationale, compared to
skipping to change at page 119, line 8 skipping to change at page 114, line 8
and the client instance can take front-channel callbacks on the same and the client instance can take front-channel callbacks on the same
device as the user. This combination is analogous to the OAuth 2.0 device as the user. This combination is analogous to the OAuth 2.0
Authorization Code grant type. Authorization Code grant type.
The client instance initiates the request to the AS. Here the client The client instance initiates the request to the AS. Here the client
instance identifies itself using its public key. instance identifies itself using its public key.
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
{ {
"actions": [ "actions": [
"read", "read",
"write", "write",
"dolphin" "dolphin"
], ],
skipping to change at page 119, line 32 skipping to change at page 114, line 34
], ],
"datatypes": [ "datatypes": [
"metadata", "metadata",
"images" "images"
] ]
} }
], ],
}, },
"client": { "client": {
"key": { "key": {
"proof": "jwsd", "proof": "httpsig",
"jwk": { "jwk": {
"kty": "RSA", "kty": "RSA",
"e": "AQAB", "e": "AQAB",
"kid": "xyz-1", "kid": "xyz-1",
"alg": "RS256", "alg": "RS256",
"n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8..." "n": "kOB5rR4Jv0GMeLaY6_It_r3ORwdf8ci_JtffXyaSx8..."
} }
} }
}, },
"interact": { "interact": {
skipping to change at page 121, line 13 skipping to change at page 116, line 13
out by validating session information and retrieves the stored out by validating session information and retrieves the stored
pending request. The client instance uses the values in this to pending request. The client instance uses the values in this to
validate the hash parameter. The client instance then calls the validate the hash parameter. The client instance then calls the
continuation URL and presents the handle and interaction reference in continuation URL and presents the handle and interaction reference in
the request body. The client instance signs the request as above. the request body. The client instance signs the request as above.
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"interact_ref": "4IFWWIKYBC2PQ6U56NL1" "interact_ref": "4IFWWIKYBC2PQ6U56NL1"
} }
The AS retrieves the pending request based on the handle and issues a The AS retrieves the pending request based on the handle and issues a
bearer access token and returns this to the client instance. bearer access token and returns this to the client instance.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
skipping to change at page 123, line 8 skipping to change at page 118, line 8
The client instance can display a user code or a printable QR code. The client instance can display a user code or a printable QR code.
The client instance is not able to accept callbacks from the AS and The client instance is not able to accept callbacks from the AS and
needs to poll for updates while waiting for the user to authorize the needs to poll for updates while waiting for the user to authorize the
request. request.
The client instance initiates the request to the AS. The client instance initiates the request to the AS.
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"dolphin-metadata", "some other thing" "dolphin-metadata", "some other thing"
], ],
}, },
"client": "7C7C4AZ9KHRS6X63AJAO", "client": "7C7C4AZ9KHRS6X63AJAO",
"interact": { "interact": {
"start": ["redirect", "user_code"] "start": ["redirect", "user_code"]
skipping to change at page 124, line 26 skipping to change at page 119, line 26
the user a message to return to their device. the user a message to return to their device.
Meanwhile, the client instance periodically polls the AS every 60 Meanwhile, the client instance periodically polls the AS every 60
seconds at the continuation URL. The client instance signs the seconds at the continuation URL. The client instance signs the
request using the same key and method that it did in the first request using the same key and method that it did in the first
request. request.
POST /continue/VGJKPTKC50 HTTP/1.1 POST /continue/VGJKPTKC50 HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
The AS retrieves the pending request based on the handle and The AS retrieves the pending request based on the handle and
determines that it has not yet been authorized. The AS indicates to determines that it has not yet been authorized. The AS indicates to
the client instance that no access token has yet been issued but it the client instance that no access token has yet been issued but it
can continue to call after another 60 second timeout. can continue to call after another 60 second timeout.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Cache-Control: no-store Cache-Control: no-store
skipping to change at page 124, line 46 skipping to change at page 120, line 4
{ {
"continue": { "continue": {
"access_token": { "access_token": {
"value": "G7YQT4KQQ5TZY9SLSS5E" "value": "G7YQT4KQQ5TZY9SLSS5E"
}, },
"uri": "https://server.example.com/continue/ATWHO4Q1WV", "uri": "https://server.example.com/continue/ATWHO4Q1WV",
"wait": 60 "wait": 60
} }
} }
Note that the continuation URL and access token have been rotated Note that the continuation URL and access token have been rotated
since they were used by the client instance to make this call. The since they were used by the client instance to make this call. The
client instance polls the continuation URL after a 60 second timeout client instance polls the continuation URL after a 60 second timeout
using this new information. using this new information.
POST /continue/ATWHO4Q1WV HTTP/1.1 POST /continue/ATWHO4Q1WV HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP G7YQT4KQQ5TZY9SLSS5E Authorization: GNAP G7YQT4KQQ5TZY9SLSS5E
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
The AS retrieves the pending request based on the URL and access The AS retrieves the pending request based on the URL and access
token, determines that it has been approved, and issues an access token, determines that it has been approved, and issues an access
token for the client to use at the RS. token for the client to use at the RS.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Cache-Control: no-store Cache-Control: no-store
{ {
skipping to change at page 127, line 8 skipping to change at page 122, line 8
In this scenario, the client instance is requesting on behalf of a In this scenario, the client instance is requesting on behalf of a
specific RO, but has no way to interact with the user. The AS can specific RO, but has no way to interact with the user. The AS can
asynchronously reach out to the RO for approval in this scenario. asynchronously reach out to the RO for approval in this scenario.
The client instance starts the request at the AS by requesting a set The client instance starts the request at the AS by requesting a set
of resources. The client instance also identifies a particular user. of resources. The client instance also identifies a particular user.
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
{ {
"type": "photo-api", "type": "photo-api",
"actions": [ "actions": [
"read", "read",
"write", "write",
"dolphin" "dolphin"
skipping to change at page 128, line 34 skipping to change at page 123, line 34
The AS reaches out to the RO and prompts them for consent. In this The AS reaches out to the RO and prompts them for consent. In this
example, the AS has an application that it can push notifications in example, the AS has an application that it can push notifications in
to for the specified account. to for the specified account.
Meanwhile, the client instance periodically polls the AS every 60 Meanwhile, the client instance periodically polls the AS every 60
seconds at the continuation URL. seconds at the continuation URL.
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP 80UPRY5NM33OMUKMKSKU Authorization: GNAP 80UPRY5NM33OMUKMKSKU
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
The AS retrieves the pending request based on the handle and The AS retrieves the pending request based on the handle and
determines that it has not yet been authorized. The AS indicates to determines that it has not yet been authorized. The AS indicates to
the client instance that no access token has yet been issued but it the client instance that no access token has yet been issued but it
can continue to call after another 60 second timeout. can continue to call after another 60 second timeout.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Cache-Control: no-store Cache-Control: no-store
skipping to change at page 129, line 26 skipping to change at page 124, line 26
} }
} }
Note that the continuation handle has been rotated since it was used Note that the continuation handle has been rotated since it was used
by the client instance to make this call. The client instance polls by the client instance to make this call. The client instance polls
the continuation URL after a 60 second timeout using the new handle. the continuation URL after a 60 second timeout using the new handle.
POST /continue HTTP/1.1 POST /continue HTTP/1.1
Host: server.example.com Host: server.example.com
Authorization: GNAP BI9QNW6V9W3XFJK4R02D Authorization: GNAP BI9QNW6V9W3XFJK4R02D
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
The AS retrieves the pending request based on the handle and The AS retrieves the pending request based on the handle and
determines that it has been approved and it issues an access token. determines that it has been approved and it issues an access token.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Cache-Control: no-store Cache-Control: no-store
{ {
"access_token": { "access_token": {
skipping to change at page 130, line 26 skipping to change at page 125, line 26
&response_type=code &response_type=code
&state=123455 &state=123455
Now the developer wants to make an analogous request to the AS using Now the developer wants to make an analogous request to the AS using
GNAP. To do so, the client instance makes an HTTP POST and places GNAP. To do so, the client instance makes an HTTP POST and places
the OAuth 2.0 values in the appropriate places. the OAuth 2.0 values in the appropriate places.
POST /tx HTTP/1.1 POST /tx HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/json Content-Type: application/json
Detached-JWS: ejy0... Signature-Input: sig1=...
Signature: sig1=...
Digest: sha256=...
{ {
"access_token": { "access_token": {
"access": [ "access": [
"read", "write", "dolphin" "read", "write", "dolphin"
], ],
"flags": [ "bearer" ] "flags": [ "bearer" ]
}, },
"client": "7C7C4AZ9KHRS6X63AJAO", "client": "7C7C4AZ9KHRS6X63AJAO",
"interact": { "interact": {
 End of changes. 155 change blocks. 
796 lines changed or deleted 641 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/