error since the client instance will be unable to complete the request without authorization. <del> The AS SHOULD apply suitable timeouts to any interaction mechanisms </del>  provided, including user codes and redirection URLs.  The client instance SHOULD apply suitable timeouts to any callback URLs.

Deploy Preview for gnap-core-protocol-editors-draft ready! Built Explore the source changes: 72feabe3d5e229b7516edd76777e3186dfd09f91 Inspect the deploy log: Browse the preview:
Still need to explain better how to do that, will track as part of lifecycle discussion
explains how an existing request can be modified by a PATCH request to the continuation endpoint. My question is, what happens if such a PATCH request is sent while the interaction for the associated grant request is not yet finished? I feel like this should not be allowed, but could not find any information anywhere in Section 5 that this is actually forbidden. Section 5.3 also says that the PATCH request may include post-interaction responses. I assume this means that by specifying an interaction reference in the PATCH request the interaction can be finished by the PATCH request, so the question would be what happens if the interaction is not finished and the PATCH request does not contain an interaction reference?
In Section 3.3.4 it says If the PATCH request is considered a continuation request (which is reasonable since it is sent to the continuation URI), this would prohibit a PATCH request before the interaction finishes. However, if no interaction finish mode is used, this does not apply.
I believe the cases are covered (a PATCH can't be done when it is pending), even if we could make things clearer probably : using PATCH instead of POST aims to provide better signal/control of when the partial update can be made as part of a continuation request (and it needs to use the continue access token) when the client can't receive a finish method (redirect or push), then it will need to poll regularly (cf 5.2)
Summary from editor's discussion: The grant process is stateful, a grant goes from (requested) -> (pending approval) -> (approved), at least. The PATCH request only makes sense to an (approved) grant, the post-interaction requests only make sense for the (pending) grant. We can call out this stateful nature and constrain different requests and inputs to specific states.
Proposed solution to make a state diagram and add state description in the overall protocol discussion.
Modifying an Existing Request: Editor's note: The net result of this is that interaction requests are really only meant to be responded to exactly once by the AS. This isn't spelled out explicitly, but could be included in Section 2.5 and/or Section 3.3.
This feeds into the overall discussion of "what can be sent when" and the lifecycle of the grant within the API; I do think that these artifacts should be one-time-use, especially the nonces.

error since the client instance will be unable to complete the request without authorization.  <ins> The AS SHOULD handle any interact request as a one-time-use mechanism and SHOULD apply suitable timeouts to any interaction mechanisms </ins> provided, including user codes and redirection URLs.  The client instance SHOULD apply suitable timeouts to any callback URLs.


Each access token MAY be bound to different keys with different proofing mechanisms. <del> If token-management is allowed, each access token SHOULD have different "manage" URIs. </del>  [[ See issue #70 [9] ]]

Deploy Preview for gnap-core-protocol-editors-draft ready! Built Explore the source changes: 00d478c5ff0bc5603d237c1ab0bd3cacb76b353d Inspect the deploy log: Browse the preview:
I do like that this requirement goes away. Now, assuming we don't have it anymore... why don't make it available through the sever's discovery information? Furthermore, you might want to have all examples/references with to be consistent as right now it doesn't appear to be true.
NAME It is still allowed and even intended that you can return different management URIs per token, so putting it in the discovery document is not reasonable. The client needs to be ready to take any value handed back in this space at runtime, and that's up to the AS's discretion.
NAME I understand that the AS can return different management URIs and the clients should "obey" that. Although, in the most simple use cases, you can definitely make a life a bit easier for certain types of clients and don't require them to store somewhere an extra piece of the information along with ATs or even without them... For example, for the latter, should be a client on an RS' side be able to revoke ATs and if so, how would it know where their mngt endpoints?
A client would only be able to revoke an access token if the AS provides a management URI with the access token. It's a significantly simpler model for clients if the information can only show up in one place, instead of potentially being in one place (discovery doc) and maybe being overridden at runtime (token response). Nothing requires the client to store the information if they don't want to revoke or rotate the tokens. An RS revoking an access token is outside the scope of this draft, but could be discussed in the RS draft. (I haven't heard a call for that functionality before, though it's interesting.)
I would love you guys to take care of as this is something I was failed to understand before but never brought to the table before as always considered it to be a minor detail.
NAME I filed a new issue for that at ietf-wg-gnap/gnap-resource-servers, please add comments about the use case and utility there. Thank you!
NAME thank you, I will do that. Regarding the clients who obtain, store and use ATs, or in other words, these clients that don't reside on RS' side... all those clients need to store information about the mngt URI along with ATs they have. This is just a bit of extra work and isn't a big deal at the first glance but let's consider that a client is implemented and deployed as something like a service/lambda function in one of the cloud providers without the luxury to (easily) store something say on the filesystem and/or with a bunch of requirements or specific restrictions on where and how things should be stored. This is the first thing. It's still solvable... yes, I agree... but there is also another thing; you aren't a developer of the client and your goal is to explain what should happen to dozens of other teams who might have a little interest and tell you they we want to have/store only ATs and the location of the AS as they used to work this way before with OAuth 2, etc. you are working on the "generic" GNAP client library for your most liked programming language and you want to provide a convenient API for its consumers taking into account that your client in some cases knows what's the location of the token mngr URI and in some cases, it simply doesn't
NAME the client in (1) still needs to store the access token, which is a dynamic value. This is another dynamic value next to it. Your proposed optimization makes that case much more difficult because now the code needs to be able to pull the value either from the previously-configured place or the dynamic place, instead of always in the dynamic place. For the library in (2) it's even more simple: the client never "knows" ahead of time what the URI is, it's always told by the protocol, so the library always just handles it directly. But that's only if you want to do the revocation/rotation for the client. You can ignore it entirely if all you want to store is the AS's base URI and the token value. In both (1) and (2), if the client doesn't know how to deal with dynamic management URI values then it simply doesn't deal with them. Yes, this is a different model from OAuth 2, but that's on purpose. Several of the major attacks against OAuth 2 (like AS mix-up) stem from the discovery document containing a bunch of different URLs that the client needs to knit together to make a single picture of the AS.
Multiple Access Tokens: Editor's note: Do we need to specify that the management URIs are different if we require the token to be presented?
I think we can actually remove this requirement, or make this a MAY; as long as the URI is required in the response, it's up to the AS how to manage things; we do want to say that it can't contain the access token value itself
Interacting with the User: Editor's note: There need to be more examples (Appendix C) that knit together the interaction modes into common flows, like an authz-code equivalent. But it's important for the protocol design that these are separate pieces to allow such knitting to take place.
There are actually more examples that have been documented (sequences and appendix), seems enough for now.

Each access token MAY be bound to different keys with different proofing mechanisms.  <ins> The "manage" URI MUST NOT contain the access token "value". </ins> [[ See issue #70 [9] ]]


If an access token response includes the "manage" parameter as described in response-token-single, the client instance MAY call this URL to manage the access token with any of the actions defined in the <del> following sections.  Other actions are undefined by this specification. </del>  The access token being managed acts as the access element for its own management API.  The client instance MUST present proof of an

Actually a very minor editorial change to specify the actions.
Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: b874cebd8f241746631e4c73c3c9056b190bfb1e Inspect the deploy log: Browse the preview:
So I was starting to have a look at rotation/revocation issues (keys or tokens), as we have many open issues that relate to that Interesting insight from DIF KERI (Universal Identifier Theory paper) "The term revocation has two completely different meanings in the identity space. In key management one may speak of revoking keys. With statement issuance, authorization issuance, or credential issuance, one may speak of revoking an authorization statement, a token, or a credential. This becomes confusing when the act of revoking keys also implicitly revokes the authorization of statements signed with those keys." and "KERI terminology usually avoids that confusion between rotation and revocation because a key rotation operation is the equivalent of a key revocation operation followed by a key replacement operation. So one operation, rotate, is implemented instead of two operations (revoke and replace)."
Related question: what is persistent (drawback, need to store that info somewhere, safely) ? what is ephemeral ? what's the lifecycle of related objects? And more specifically: every new request needs to provide a key -> don't need long term persistance for that, we simply need to handle key rotations during a single request (as described in issue ) objets derived from some underlying key however (including bound tokens) might be more tricky ( ex ). Do we need some kind of registry to keep track of the changes over time, to keep them alive even if the key changes? Or do we just consider that they get revoked? (and what happens if you fall into that case at some point, what's your next action?)
This is already managed by section 7.2 "If the flags field does not contain the bearer flag and the key is absent, the access token MUST be sent using the same key and proofing mechanism that the client instance used in its initial request (or its most recent rotation)"

If an access token response includes the "manage" parameter as described in response-token-single, the client instance MAY call this URL to manage the access token with any of the actions defined in the  <ins> following sections: rotate and revoke.  Other actions are undefined by this specification. </ins> The access token being managed acts as the access element for its own management API.  The client instance MUST present proof of an


If a "wait" parameter was included in the response-continue, the client instance MUST NOT call the continuation URI prior to waiting the number of seconds indicated.  If no "wait" period is indicated, <del> the client instance SHOULD wait at least 5 seconds.  If the client instance does not respect the given wait period, the AS MUST return an error. </del>  The response from the AS is a JSON object and MAY contain any of the fields described in response, as described in more detail in the

Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: c7e84a97cc589eff531c783bfcaf307fa8ee92a6 Inspect the deploy log: Browse the preview:
As a bit random comment... I always wondered if it's allowed for the AS to provide a "delayed" response, or in other words, leverage the HTTP long polling mechanism just like for this response with the field. Of course, there will be definitely upsides and downsides to it. See URL for more info.
Since it's over HTTP, long polling is allowed regardless of whether we mention it or not. I personally don't see a reason to mention it explicitly here.
It's a continuation of the discussion started in URL which I would like to track as a separate issue. If we want to have that then the client should be able to wait and handle a delayed response say after 60 - 120 seconds, and the client should be able to gracefully handle various timeous (client and from the network infrastructure) and make a subsequent call, and the client should know what to do with the "wait" field when a timeout occurs in the previous step. I think it could be a great addition to this specification. Furthermore, take a look at and how they leverage the HTTP long polling mechanism.
The specification allows using the HTTP long polling mechanism against the OAuth2 token endpoint in somewhat similar circumstances. I had some spare time to research this topic a bit deeper and don't have a good answer on how it was possible for me to have the abovementioned specification out of sight. Again, it would be such a great thing to have a bit more instant notification mechanism in the specification core, I mean, not in its extensions or in one or another out of band/vendor-specific solution.
Continuing a Grant Request: Editor's note: What's a reasonable amount of time to wait by default so as not to DOS the server if the field is missing?
Might have to broaden the perspective and provide more general guidance on how to avoid/limit DDoS
I think we need general considerations as well, but this is a specific case where a naive implementation could accidentally DoS the system by polling too quickly.
yes. Then it's simple, anything around the minute should work.
Discussed in security considerations URL However, still no normative requirement in the polling section so this issue is staying open until that's in.
Need to add this to the interaction response section. I suggest "SHOULD NOT be less than five seconds" and "omission MUST NOT be treated as zero".

If a "wait" parameter was included in the response-continue, the client instance MUST NOT call the continuation URI prior to waiting the number of seconds indicated.  If no "wait" period is indicated,  <ins> the client instance MUST NOT poll immediately and SHOULD wait at least 5 seconds.  If the client instance does not respect the given wait period, the AS MUST return the error "too_fast" defined in response-error. </ins> The response from the AS is a JSON object and MAY contain any of the fields described in response, as described in more detail in the


client instance wants to optimize its calls to the AS before making a request, it MAY send an HTTP OPTIONS request to the grant request endpoint to retrieve the server's discovery information.  The AS MUST <del> respond with a JSON document containing the following information: </del>  The information returned from this method is for optimization purposes only.  The AS MAY deny any request, or any portion of a

The specification can also say a bit stricter A response MUST use the 200 OK (HTTP status code) and return a JSON object using content type.
Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: 9f7633b4fd5b90bbac20a33ade1e56045a47b3c1 Inspect the deploy log: Browse the preview:

client instance wants to optimize its calls to the AS before making a request, it MAY send an HTTP OPTIONS request to the grant request endpoint to retrieve the server's discovery information.  The AS MUST  <ins> respond with a JSON document with Content-Type "application/json" containing a single object with the following information: </ins> The information returned from this method is for optimization purposes only.  The AS MAY deny any request, or any portion of a


publishing a public key at a URI.  For interoperability, this method could later be described as an extension.  7.2. The method the client instance uses to send an access token depends Both the AS and client software can use systems such as hardware security modules to strengthen their key security storage and <del> generation for both asymmetric and symmetric keys. </del>  12.6.

Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: b424033c5fa3a51c49ad97bd194f5607cebce955 Inspect the deploy log: Browse the preview:
Please take a look a BCP 107 (a.k.a. RFC 4107). You may need a reference here.
Please take a look a BCP 107 (a.k.a. RFC 4107). You may need a reference here. Originally posted by NAME in URL
Ok but should this text be updated ? In 2005, potential quantum threats were not even anticipated (with impacts on key size for instance)
I think the overall message remains accurate, but you are right that quantum computing was not a concern when RFC 4107 was written. Any updates to RFC 4107 are not part of your task in the GNAP WG.
Sure, thanks for the feedback.
I don't see any reason to support symmetric keys for Client identification etc. Removing them will remove a (small) point of complexity, at zero cost. Moreover, whenever people use "shared keys" nowadays these are usually passwords (even if we say explicitly not to use passwords as keys) and those come with a bunch of security issues. In other words, is anybody still using shared symmetric keys in a justified and secure way?
I take the opposite view about their inclusion -- it doesn't make sense to disallow them because there's no added complexity. Symmetric keys can be referenced just like public keys/keypairs, and if we are referring to keys by reference rather than value, then the security is comparable in many ways. The security problems with symmetric crypto tends not to be in the actual crypto but in the key management and distribution. GNAP firmly says that it doesn't have any part in symmetric key management: any key you present by value has to be a public key. You can also do secure key derivation that ends up with a symmetric algorithm in the end, so you take the registered key and some other part of the request to create the derived key to be used with the actual request, and we shouldn't disallow those schemes. Right now we don't even mention those, but that's more for the security considerations as it doesn't have a direct effect on the protocol itself. Another argument for allowing symmetric cryptography is to look toward post-quantum signatures. I'm not an expert here but it's my understanding that many symmetric algorithms are more robust against quantum attacks. I'd like to see this raised as part of a larger security review. Maybe this is an issue to bring to CRFG or a similar crowd?
I tend to worry about implementation barriers for novices like me. Unless there are major security benefits, I hope we consider if symmetric keys could be an easier way for developers to transition from OAuth or other authorization schemes into GNAP. This is the kind of stuff that I'm having trouble understanding as we move our project from UMA 2 and OIDC to GNAP, RAR, DIDs, and VCs.
NAME I'll try to say it without sounding obnoxius... This is exactly what I'm worried about. Developers who have a hard time using public/private key pairs (and I understand why it is difficult and totally agree we should document specific implementations and how these keys can be et up) are the same developers who'd easily end up using passwords instead of symmetric keys and NOT using sophisticated key management. I understand Justin's position but given that he's talking about sophisticated large scale systems, it still makes sense to leave it for a future extension. BTW, symmetric keys have been the root cause of as well, which further proves my point that they are a footgun.
Symmetric keys are only supported by reference, so I think it's quite explicit their management needs to be external to gnap. And anyways, as soon as you authorize the management of keys by reference (meaning: that doesn't necessarily have to be managed within GNAP itself), the case will happen. Having some wording calling for caution, as is done currently in the text, seems the best we can do.
answered by
The more I'm reading the new Security Considerations, the more I am convinced that we need to get rid of symmetric keys. They add complexity, and they basically prevent any meaningful security proofs (because any system role can pretend to be any other role). Again, this is best left to an extension. BTW, even if we authorize management of keys by reference, we can still restrict the type of keys allowed by the protocol.
I don't think that changes anything to security proofs of the GNAP protocol itself. Of course the assumption is that keys are well managed and that each party maintains the identity of its counterparts. So there's always the need to make the correspondance between the keys and the roles. Or am I missing something?
As far as security proofs are concerned, if you have access to a secret key you might as well be the key's owner. So, the AS can impersonate the Client etc. Security proofs (usually) do not assume that people are playing by the rules.
Well, sharing a secret between the client and the AS seems far stretched (but ok, if you read the spec very literally without refering to security considerations, maybe someone could come up with the idea). I was more thinking of a scenarii like a joint RS-AS service backed by some cloud KMS (usually they don't support asymmetric keys). But I get your point.
Summarizing some offline discussion, we might relax the sentence related to PQ threats and symmetric keys, and enhance the security considerations (symmetric keys aren't intended as human memorable password or a value derived from one).

publishing a public key at a URI.  For interoperability, this method could later be described as an extension. <ins> 7.1.2. The security of GNAP relies on the cryptographic security of the keys themselves.  When symmetric keys are used in GNAP, a key management system or secure key derivation mechanism MUST be used to supply the keys.  Symmetric keys MUST NOT be a human memorable password or a value derived from one.  Symmetric keys MUST NOT be passed by value from the client instance to the AS. </ins> 7.2. The method the client instance uses to send an access token depends Both the AS and client software can use systems such as hardware security modules to strengthen their key security storage and  <ins> generation for both asymmetric and symmetric keys (see also key- protection). </ins> 12.6.


Dynamically generated client instance identifiers are string values that MUST be protected by the client instance as secrets.  Instance identifier values MUST be unguessable and MUST NOT contain any <del> sensitive information.  Instance identifier values are opaque to the client instance. </del>  This non-normative example shows an instance identifier along side an issued access token.

Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: 7e9a352ebd6b48adb5f0a834a94bd083c38cb53c Inspect the deploy log: Browse the preview:
The text says: protected by the client instance as secrets. Instance identifier values MUST be unguessable and MUST NOT contain any sensitive information. This is weird, because we're saying both that they should be treated as secrets and that they are not sensitive. I would suggest instead: protected by the client instance as secrets. Instance identifier values MUST be unguessable and MUST NOT contain any information that would compromise the AS if revealed.
We're not saying that they're not sensitive, we're saying that they can't contain sensitive information. This is like saying your password is sensitive and it also shouldn't contain your medical record number at your hospital, because that's also a sensitive piece of information. Still I think the wording is an improvement, thanks!
I agree the proposed wording is better, thanks !

Dynamically generated client instance identifiers are string values that MUST be protected by the client instance as secrets.  Instance identifier values MUST be unguessable and MUST NOT contain any  <ins> information that would compromise any party if revealed.  Instance identifier values are opaque to the client instance. </ins> This non-normative example shows an instance identifier along side an issued access token.


could be calling the AS just to get direct user information and have no need to get an access token to call an RS.  (A) The end user interacts with the client instance to indicate a need for resources on behalf of the RO.  This could identify the RS the client instance needs to call, the resources needed, or the and never call an RS, just as it is possible for there not to be a user involved in the delegation process. <del> 1.5.1. </del>  In this example flow, the client instance is a web application that wants access to resources on behalf of the current user, who acts as An example set of protocol messages for this method can be found in example-auth-code. <del> 1.5.2. </del>  In this example flow, the client instance is a device that is capable of presenting a short, human-readable code to the user and directing An example set of protocol messages for this method can be found in example-device. <del> 1.5.3. </del>  In this example flow, the end user and RO roles are fulfilled by different parties, and the RO does not interact with the client An example set of protocol messages for this method can be found in example-async. <del> 1.5.4. </del>  In this example flow, the AS policy allows the client instance to make a call on its own behalf, without the need for an RO to be An example set of protocol messages for this method can be found in example-no-user. <del> 1.5.5. </del>  In this example flow, the client instance receives an access token to access a resource server through some valid GNAP process.  The client token management information, which the client instance will store in place of the values returned in (2). <del> 1.5.6. </del>  In this scenario, the client instance does not call an RS and does not request an access token.  Instead, the client instance only

Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: a48ba2e1204e2294f34f8550971f65f684ea7992 Inspect the deploy log: Browse the preview:
Sec. 1.5 (Sequences) would be clearer if we named the top sequence - all other sequences have been named. Maybe "main authorization flow"?
The sequences have not been names per say, they just happen to be related to a subtitle. We could of course create a new subsection, but the idea was to place this sequence above the others.
This is purely editorial. Naming it would make it easier to refer to this sequence.

could be calling the AS just to get direct user information and have no need to get an access token to call an RS. <ins> 1.5.1. The following diagram provides a general overview of GNAP, including many different optional phases and connections.  The diagrams in the following sections provide views of GNAP under more specific circumstances. </ins> (A) The end user interacts with the client instance to indicate a need for resources on behalf of the RO.  This could identify the RS the client instance needs to call, the resources needed, or the and never call an RS, just as it is possible for there not to be a user involved in the delegation process.  <ins> 1.5.2. </ins> In this example flow, the client instance is a web application that wants access to resources on behalf of the current user, who acts as An example set of protocol messages for this method can be found in example-auth-code.  <ins> 1.5.3. </ins> In this example flow, the client instance is a device that is capable of presenting a short, human-readable code to the user and directing An example set of protocol messages for this method can be found in example-device.  <ins> 1.5.4. </ins> In this example flow, the end user and RO roles are fulfilled by different parties, and the RO does not interact with the client An example set of protocol messages for this method can be found in example-async.  <ins> 1.5.5. </ins> In this example flow, the AS policy allows the client instance to make a call on its own behalf, without the need for an RO to be An example set of protocol messages for this method can be found in example-no-user.  <ins> 1.5.6. </ins> In this example flow, the client instance receives an access token to access a resource server through some valid GNAP process.  The client token management information, which the client instance will store in place of the values returned in (2).  <ins> 1.5.7. </ins> In this scenario, the client instance does not call an RS and does not request an access token.  Instead, the client instance only


In this example, the AS is returning set of response-subject, simultaneously as an opaque identifier, an email address, and a <del> decentralized identifier URL (DID). </del>  3.1.

updated examples updated examples for httpsig
Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: a6cdcdcaf974e575a7e246dca7ada0e9b72e25cf Inspect the deploy log: Browse the preview:

In this example, the AS is returning set of response-subject, simultaneously as an opaque identifier, an email address, and a  <ins> decentralized identifier (DID). </ins> 3.1.


If the client instance indicates that it can request-interact- usercode and the AS supports this mode for the client instance's <del> request, the AS responds with a "user_code" field.  This field is an object that contains the following members. The client instance MUST communicate the "code" to the end user in some fashion, such as displaying it on a screen or reading it out audibly.  This code is used by the interaction component of the AS as a means of identifying the pending grant request and does not </del>  function as an authentication factor for the RO. The URI that the end user is intended to enter the code into MUST be

Instead of using an object with a single member, the interaction start method now uses a simple string, in line with the and methods.
To edit notification comments on pull requests, go to your .

If the client instance indicates that it can request-interact- usercode and the AS supports this mode for the client instance's  <ins> request, the AS responds with a "user_code" field.  This field is string containing a unique short code that the user can type into a web page.  This string MUST be case-insensitive, MUST consist of only easily typeable characters (such as letters or numbers).  The time in which this code will be accepted SHOULD be short lived, such as several minutes.  It is RECOMMENDED that this code be no more than eight characters in length.  REQUIRED. The client instance MUST communicate the "user_code" value to the end user in some fashion, such as displaying it on a screen or reading it out audibly.  This code is used by the interaction component of the AS as a means of identifying the pending grant request and does not </ins> function as an authentication factor for the RO. The URI that the end user is intended to enter the code into MUST be


If access is approved, the resulting access token is valid for the described resource and is bound to the client instance's key (or its <del> most recent rotation).  The token is labeled "token1-23" and could be split into multiple access tokens by the AS, if the AS chooses.  The token response structure is described in response-token-single. </del>  2.1.2. token with access to two described resources. If the client instance request-token-single, the AS MUST NOT respond <del> with the multiple access token structure unless the client instance sends the "split" flag as described in request-token-single. If the AS has split the access token response, the response MUST include the "split" flag. </del>  [[ See issue #69 [6] ]] access token is granted.  In such cases, the AS responds with a multiple access token structure containing one access token. <del> If the AS has split the access token response, the response MUST include the "split" flag in the "flags" array. </del> Each access token MAY be bound to different keys with different proofing mechanisms.

To edit notification comments on pull requests, go to your .
Signaling Token Behavior: Editor's note: This functionality is controversial at best as it requires significantly more complexity on the client in order to solve one class of AS/RS deployment choices.
Yaron (referring to ): I suggest to extend the editor's note to clarify what is the use case, so that the group can decide whether split tokens are indeed necessary. Justin: I think we should have a more detailed conversation about this potential feature than an editor’s note could reasonably get into. There are a number of large items (splitting access tokens, directing access tokens to specific portions of API or RS’s, among others) that I think will be big conversations for the WG, and all the context of these don’t necessarily need to be documented inside the notes in the document itself. But for discussion and context, this feature was proposed to deal with cases where the AS might decide to issue several access tokens in any case where the client requested one, because the AS wants to have restricted audiences for individual access tokens but the client doesn’t know about the audiences ahead of time. I agree that it’s a compelling use case, and it puts security of the protected domains in the hands of the AS where it belongs, but it would require a client to be smart enough to know what to do with these tokens downstream, and if OAuth has taught us anything it’s that we can’t rely on client software to be smart about most anything. :)
See also
I always considered the "split_token" functionality as a nice addition to the protocol. It gets available for the client when it explicitly requests it + the AS can issue multiple ATs. Among other described scenarios above, I had in mind this particular one; let's say there are two almost identical RSs, the difference is only in the way how much you need to pay to use them, for example, our client wants to store video recordings, RS2 works a bit faster and guarantees more protection against data loss. At the same time, RS1 and RS2 belong to different organizations that have nothing in common + the client knows nothing about RS1 and RS2 in advance.
NAME For this scenario, you'd also need a way to explicitly direct the client instance to either RS1 or RS2 along with the token. There's nothing in the protocol that does that today (see ). Both of these could be handled as an extension. The current view of the editors is that this is a "nice to have", which isn't enough for it to be in core, especially not without implementation experience.
NAME I agree that there's nothing in the protocol that does that as of today. I was thinking about why the AS cannot pass a piece of the information along with an AT or ATs (for the split token feature) it issues. This is what would happen in my implementation of the AS and the client library (SDK). This piece of information is nothing more than a JSON object and it's assumed that the AS and the client both know how to deal with it (there is already a bright example of the information we pass in a similar fashion, it's "expires_in" parameter). I also assume that might have something like that. I wouldn't say my implementation counts as it's a POC. Please, note that RS1 and RS2 aren't mutually exclusive for the client in my example. The client may use them both at the same time. The client wants to store the video recordings and these RSs might do something meaningful with them even say in real-time. It's up to you to decide what and what not to have at the very core of the protocol. The split-token feature and seem to be controversial topics that might bring lots of complexity.

If access is approved, the resulting access token is valid for the described resource and is bound to the client instance's key (or its  <ins> most recent rotation).  The token is labeled "token1-23".  The token response structure is described in response-token-single. </ins> 2.1.2. token with access to two described resources. If the client instance request-token-single, the AS MUST NOT respond  <ins> with the multiple access token structure. </ins> [[ See issue #69 [6] ]] access token is granted.  In such cases, the AS responds with a multiple access token structure containing one access token.  Each access token MAY be bound to different keys with different proofing mechanisms.


8.1. Instead of sending an resource-access-rights, access rights MAY be <del> communicated as a string known to the AS or RS representing the access being requested.  Each string SHOULD correspond to a specific expanded object representation at the AS. </del>  This value is opaque to the client instance and MAY be any valid JSON string, and therefore could include spaces, unicode characters, and not easily confused by a developer, such as by limiting the strings to easily disambiguated characters.  This functionality is similar in practice to OAuth 2.0's "scope" parameter RFC6749, where a single string represents the set of access rights requested by the client instance.  As such, the reference

Removes the normative suggestion that access right string values be always expandable to objects, but instead adds an example of one way to do it.
To edit notification comments on pull requests, go to your .
We say: But then we give examples like "some other thing" that clearly do not correspond to anything. We also don't specify any kind of semantics, such as if I request the reference string, I might get back the expanded access right representation. I suggest to remove or weaken that sentence:
I don't see a reason for it not being a SHOULD -- it provides guidance to API developers that the strings a short-hand for the expanded objects. And since it's only a SHOULD, the AS is still free to treat it differently.
No, this would be a MAY. With a SHOULD, you're supposed to have a good, documented reason to do something else. Quoting the original, may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. If we keep the SHOULD, our examples in the text should reflect that.
Probably we could improve the examples. But as an implementer, I wouldn't understand what you mean by MAY. Because then it suggests there can be reasonable alternatives to something known to the AS, which I don't think we have.
NAME I've proposed a change to the text in question in . Also, please note that the example string of is intended to be an actual value, with spaces and all. If it's not clear that this is a real and valid value in this context, please suggest an alternative that might fit here. We don't want people to assume that it has the same restrictions as OAuth scopes (which can't have spaces).

8.1. Instead of sending an resource-access-rights, access rights MAY be  <ins> communicated as a string known to the AS representing the access being requested.  Just like access rights communicated as an object, access rights communicated as reference strings indicate a specific access at a protected resource.  In the following non-normative example, three distinct resource access rights are being requested. </ins> This value is opaque to the client instance and MAY be any valid JSON string, and therefore could include spaces, unicode characters, and not easily confused by a developer, such as by limiting the strings to easily disambiguated characters. <ins> In order to facilitate the use of both object and reference strings to access the same kind of APIs, the API designer can define a clear mapping between these forms.  One possible approach for choosing reference string values is to use the same value as the "type" parameter from the fully-specified object, with the API defining a set of default behaviors in this case.  For example, an API definition could declare the following string: As being equivalent to the following fully-defined object: The exact mechanisms for relating reference strings is up to the API designer.  These are enforced by the AS, and the details are out of scope for this specification. </ins> This functionality is similar in practice to OAuth 2.0's "scope" parameter RFC6749, where a single string represents the set of access rights requested by the client instance.  As such, the reference


The authorization and consent gathering process in GNAP is left deliberately flexible to allow for a wide variety of different deployments, interactions, and methodologies.  In this process, the <del> AS can gather consent from the RO as necessitated by the access that has been requested.  The AS can sometimes determine which RO needs to consent based on what has been requested by the client instance, such as a specific RS record, an identified user, or a request requiring specific access such as approval by an administrator.  If the AS has a means of contacting the RO directly, it could do so without involving the client instance in its consent gathering process.  For example, the AS could push a notification to a known RO and have the RO approve the pending request asynchronously.  These interactions can be through an interface of the AS itself (such as a hosted web page), through another application (such as something installed on the RO's device), through a messaging fabric, or any other means. When interacting with an RO, the AS can do anything it needs to determine the authorization of the requested grant, including: </del>  authenticate the RO, through a local account or some other means such as federated login Alternatively, the AS could require N of M possible RO's to approve a given request in order.  The AS could also determine that the end user is not the appropriate RO for a given request and reach out to <del> the appropriate RO asynchronously.  The details of determining which RO's are required for a given request are out of scope for this specification. </del>  The client instance can also indicate that it is capable of facilitating interaction with the end user, another party, or another

to update section 4 to provide an additional use case (RO's policy). I don't think we need to update the definitions or URL
To edit notification comments on pull requests, go to your .
NAME please run on this PR to clean up the line end spaces, otherwise looks good to me. Thanks!
will do ! (btw, I added that to the wiki)
Following the discussion on the mailing list, will plan a rewording to clarify URL Thanks for the feedback. There was a rewrite of section 4 (gathering consent and authorization) that sought to update this, so if that’s still not entirely clear that definitely needs another pass. — Justin >

The authorization and consent gathering process in GNAP is left deliberately flexible to allow for a wide variety of different deployments, interactions, and methodologies.  In this process, the  <ins> AS can gather consent from the RO or apply the RO's policy as necessitated by the access that has been requested.  The AS can sometimes determine which RO needs to consent based on what has been requested by the client instance, such as a specific RS record, an identified user, or a request requiring specific access such as approval by an administrator.  If the AS has a means of contacting the RO directly, it could do so without involving the client instance in its consent gathering process.  For example, the AS could push a notification to a known RO and have the RO approve the pending request asynchronously.  These interactions can be through an interface of the AS itself (such as a hosted web page), through another application (such as something installed on the RO's device), through a messaging fabric, or any other means.  When interacting with an RO, the AS can do anything it needs to determine the authorization of the requested grant, including: </ins> authenticate the RO, through a local account or some other means such as federated login Alternatively, the AS could require N of M possible RO's to approve a given request in order.  The AS could also determine that the end user is not the appropriate RO for a given request and reach out to  <ins> the appropriate RO asynchronously. The RO is also allowed to define a policy at the AS to determine which kind of end user can get access to the resource, and under which condition.  For instance, such a condition might require the end user login and the acceptance of the RO's legal provisions. Alternatively, client software could be acting without an end user, and the RO's policy allows issuance of access tokens to instances of that client software without human interaction. The details of determining which RO's or related policies are required for a given request are out of scope for this specification. </ins> The client instance can also indicate that it is capable of facilitating interaction with the end user, another party, or another


error since the client instance will be unable to complete the request without authorization. <del> The AS SHOULD handle any interact request as a one-time-use mechanism and SHOULD apply suitable timeouts to any interaction mechanisms provided, including user codes and redirection URIs.  The client instance SHOULD apply suitable timeouts to any callback URIs. </del> 2.5.1. This specification defines the following interaction start modes as state, the client instance can repeat the interaction process by sending a continue-modify with new request-interact methods.  4.1. When a grant request is in the be used to facilitate interaction with the end user.  To initiate an interaction start method indicated by the response-interact from the AS, the client instance follows the steps defined by that interaction <del> method.  The actions of the client instance required for the </del>  interaction start modes defined in this specification are described <del> in the following sections. </del>  4.1.1.

Allows interaction responses from the AS to have an explicit timeout, with instructions on how the client instance can recover (do a modification).
To edit notification comments on pull requests, go to your .
When an AS creates a set of of interaction artifacts, like a user code or interaction URI, these artifacts aren't likely to be available perpetually. The AS will likely want to purge these after some time. It might be useful for the AS to indicate to the client a timeout for the "interact" return block so that the client has some idea of how much time it has to use the interaction methods.

error since the client instance will be unable to complete the request without authorization.  2.5.1. This specification defines the following interaction start modes as state, the client instance can repeat the interaction process by sending a continue-modify with new request-interact methods. <ins> The AS SHOULD handle any interact request as a one-time-use mechanism and SHOULD apply suitable timeouts to any interaction start methods provided, including user codes and redirection URIs.  The client instance SHOULD apply suitable timeouts to any interaction finish method. </ins> 4.1. When a grant request is in the be used to facilitate interaction with the end user.  To initiate an interaction start method indicated by the response-interact from the AS, the client instance follows the steps defined by that interaction  <ins> start mode.  The actions of the client instance required for the </ins> interaction start modes defined in this specification are described  <ins> in the following sections.  Interaction start modes defined in extensions to this specification MUST define the expected actions of the client software. If the client instance does not start an interaction start mode within an AS-determined amount of time, the AS SHOULD reject attempts to use the interaction start modes.  If the client instance has already begun one interaction start mode, the AS SHOULD reject attempts to use other interaction start modes. </ins> 4.1.1.


and no trailing newline character. The party then hashes this string with the appropriate algorithm <del> based on the "hash_method" parameter under the "finish" key.  If the "hash_method" value is not present in the client instance's request, the algorithm defaults to "sha3". [[ See issue #56 [11] ]] </del>  <del> 4.2.3.1. </del>  <del> The "sha3" hash method consists of hashing the input string with the 512-bit SHA3 algorithm.  The byte array is then encoded using URL Safe Base64 with no padding RFC4648.  The resulting string is the hash value. </del>  <del> 4.2.3.2. </del>  <del> The "sha2" hash method consists of hashing the input string with the 512-bit SHA2 algorithm.  The byte array is then encoded using URL Safe Base64 with no padding RFC4648.  The resulting string is the </del>  hash value. 5. [10] https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/78 <del> [11] https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/56 </del>  [12] https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/85

To edit notification comments on pull requests, go to your ._
Receive a Callback After Interaction: Editor's note: This should be expandable via a registry of cryptographic options, and it would be good if we didn't define our own identifiers here. Calculating the interaction hash: Editor's note: These hash algorithms should be pluggable, and ideally we shouldn't redefine yet another crypto registry for this purpose, but I'm not convinced an appropriate one already exists. Furthermore, we should be following best practices here whether it's a plain hash, a keyed MAC, an HMAC, or some other form of cryptographic function. I'm not sure what the defaults and options ought to be, but SHA512 and SHA3 were picked based on what was available to early developers.
This is probably the right registry to reference: URL
Please add a changelog, but this looks good to me!

and no trailing newline character. The party then hashes this string with the appropriate algorithm  <ins> based on the "hash_method" parameter under the "finish" key.  The resulting byte array from the hash function is then encoded using URL-Safe Base64 with no padding RFC4648.  The resulting string is the hash value. </ins>  <ins> The "hash_method" value MUST be one of the hash name strings defined in the IANA Named Information Hash Algorithm Registry [11]. </ins>  <ins> If the "hash_method" value is not present in the client instance's request, the algorithm defaults to "sha3-512". </ins>  <ins> For example, the "sha3-512" hash method consists of hashing the input string with the 512-bit SHA3 algorithm.  The byte array is then encoded using URL-Safe Base64 with no padding RFC4648.  The resulting string is the hash value. </ins>  <ins> The "sha2-512" hash method consists of hashing the input string with the 512-bit SHA2 algorithm.  The byte array is then encoded using URL-Safe Base64 with no padding RFC4648.  The resulting string is the </ins> hash value. 5. [10] https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/78  <ins> [11] https://www.iana.org/assignments/named-information/named- information.xhtml#hash-alg </ins> [12] https://github.com/ietf-wg-gnap/gnap-core-protocol/issues/85


body, the verifier MUST calculate the hash of body just as the signer does, with no normalization or transformation of the request.  7.3.4. This method is indicated by the method value "jws".  This method body, the verifier MUST decode the payload of the JWS object and treat this as the HTTP message body.  8. GNAP provides a rich structure for describing the protected resources

To edit notification comments on pull requests, go to your ._
There have been several questions about the parameter currently used to convey the hash of an access token in requests to the RS. Right now we use the definition from OpenID Connect: URL In speaking with the DPoP editors I've proposed a simplified claim there: URL It's functionally similar but doesn't require the array truncation step, and it also fixes to a single hash algorithm (SHA-256) instead of having to figure out which hash to use based on the external signing envelope. I think this change makes it both simpler to implement and to understand.
Also, for cryptographic agility here we would rely on defining a new claim name and updating the requirements about inclusion. So would always be SHA-256 and once that hash is sufficiently broken and discarded we would define a new claim like for whatever new target there is.
+1 for that, much more intuitive than truncating (and the comment from DPoP editors seem to go in that direction too). In relation to what would happen if SHA-256 gets deprecated: the current method is already based on SHA-256, so it's not a new downside an idea would be to name it for instance, to give a minimal versioning (would currently relate to SHA2) and would simplify changes later on (like avoiding ;-))
I personally think that naming the next version of the field should be left to the next version. Someone might want to specify or even , but the important thing is that we aren't defining plus parameters, we're just defining and anything else comes along as its own unique string. That kind of guidance can be written around the registry for the claim and how it'd get used.
works too
Reopening this issue: we are not providing cryto-agility, because: We do not indicate how the algorithm could change. Renaming the field to would remedy that. An implementation that did not include would formally be non-compliant, because the field is REQUIRED. We should say something about that. See URL
NAME crypto agility would be provided by defining a new field entirely. The algorithm will not change for . This was discussed in the OAuth WG with DPoP's field which has the same semantics as this. I do not recommend we re-open this.
I'm not asking to reopen it. Just to add a note in the text. The IESG reviewers are bound to comment on this.

body, the verifier MUST calculate the hash of body just as the signer does, with no normalization or transformation of the request. <ins> Note that this proof method depends on a specific cryptographic algorithm, SHA-256, in two ways: the "ath" hash algorithm is hardcoded, and computing the payload of the detached/attached signature also uses a hardcoded hash.  A future version of this document may address crypto-agility for both these uses by replacing ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method. </ins> 7.3.4. This method is indicated by the method value "jws".  This method body, the verifier MUST decode the payload of the JWS object and treat this as the HTTP message body. <ins> Note that this proof method depends on a specific cryptographic algorithm, SHA-256, in two ways: the "ath" hash algorithm is hardcoded, and computing the payload of the detached/attached signature also uses a hardcoded hash.  A future version of this document may address crypto-agility for both these uses by replacing ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method. </ins> 8. GNAP provides a rich structure for describing the protected resources


[[ See issue #103 [13] ]]  6.2. If the client instance wishes to revoke the access token proactively, supported format.  If a key is sent in multiple formats, all the key format values MUST be equivalent.  Note that while most formats present the full value of the public key, some formats present a <del> value cryptographically derived from the public key. </del>  Additional key formats are defined in IANA. required message components.  The verifier MUST validate the signature against the expected key of the signer.  7.3.2. This method is indicated by the method value "mtls".  This method first-use.  See security-mtls and security-mtls-patterns for some additional considerations for this key proofing method.  7.3.3. This method is indicated by the method value "jwsd".  This method ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method.  7.3.4. This method is indicated by the method value "jws".  This method ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method.  8. GNAP provides a rich structure for describing the protected resources

Adds a provision for rotating keys on access token requests. If a client needs to dynamically rotate its request key, this would happen through a client instance management API that is not defined in the core protocol.
To edit notification comments on pull requests, go to your .
Changing the parameters of the proof method really is the same level of function as changing the proof method entirely. Would you claim the parameters apply to the new key or the old key? And what if the proofing method makes it impossible to apply two signatures (for example) with different parameters? It opens up a can of worms to allow it to vary, and I think we need to cut all of that off.
I'm wondering if there are legit cases in the wild when as AS prohibits its clients to perform key rotation on their own. If so, how it will notify the clients?
NAME am I right that becomes immediately invalid? If it's true, wouldn't be nice to have here some way to rotate them more or less gracefully? It could be useful when there are multiple running instances of the client and it's tough, or even impossible, to update the keys on all these instances immediately (just as an example, the client instance could be deployed as a service in K8S). Thank you.
The "previous_key" element added in is not necessary in practice because the AS should always be able to look up the current key value based on the access token, and the signature using the previous key proves possession of that key separate from any presentation of the key value or reference.
Rotating the Access Token: Editor's note: If the client is using its own key as the proof, like with a bearer access token, the AS is going to need to know if the client's key has been rotated. We don't have a mechanism for rotating the token's key or the client's key yet either - so that could occur through this management function as well.
See discussion at
Token key rotation is covered by , and a non-bound token would use whatever's currently tied to the client at the AS, whatever that is.
Continuing a Grant Request: Editor's note: We need to have a secure way to rotate the key used for the continuation here. In most cases this will be a rotation for the client instance, since a client without an instance record would likely just present a new key for a new request. In that case it could go with the client management, above - but it doesn't necessarily have to be.
See my comment on pull request URL I think we need to find a single rotation recovery method. I collected my ideas here: URL
This is close to what I was thinking about. I would also add as a reference what is doing on key rotation, for discussion purposes.
Key rotation is now handled on the continuation access token, not as part of the grant update. See
Could you answer on URL and other comments in this PR? Thank you.
what do you mean by "more or less gracefully" ?
NAME you can omit "more or less gracefully", I wanted to know if GNAP allows to address the use case I provided and
Indeed the idea currently is that previous-key is replaced by the new key, for all what's coming afterwards. I know of some systems that allow a delay during which both versions coexist, is that what you're after ?
There are plenty of systems where both, or even more versions coexist until an administrator or a client itself decides to remove/invalidate previous keys. That's correct. The same approach arguably is even way more valuable for . BTW, are you planning to allow them to rotate their own keys? You are writing these specs, and IMO, you still have time to add & embed these features into the core of GNAP.

[[ See issue #103 [13] ]] <ins> 6.1.1. If the client instance wishes to bind a new presentation key to an access token, the client instance MUST present both the new key and previous key in the access token rotation request.  The client instance makes an HTTP POST as a JSON object with the following fields: The "proof" method and parameters for the new key MUST be the same as those established for the previous key. The client instance MUST prove possession of both keys simultaneously in the rotation request.  The means of doing so varies depending on the proofing method in use.  For example, the HTTP Message Signatures proofing method uses multiple signatures in the request as described in httpsig-rotate, as shown in this example. An attempt to change the "proof" method or parameters, including an attempt to rotate the key of a bearer token (which has no key), MUST result in an error returned from the AS. </ins> 6.2. If the client instance wishes to revoke the access token proactively, supported format.  If a key is sent in multiple formats, all the key format values MUST be equivalent.  Note that while most formats present the full value of the public key, some formats present a  <ins> value cryptographically derived from the public key.  See additional discussion of public keys in security-symmetric. </ins> Additional key formats are defined in IANA. required message components.  The verifier MUST validate the signature against the expected key of the signer. <ins> 7.3.1.1. When rotating a key using HTTP Message Signatures, the message, which includes the new public key value or reference, is first signed with the old key.  The message is then signed again with the new key, including the signature from the old key under the signature of the new key. For example, the following request to the token management endpoint for rotating a token value contains both the old and new keys in the request.  The message is first signed using the old key and the resulting signature is placed in "sig1": The signer then creates a new signature using the new key using the signature value as its input to the signature base.  Since the existing signature covers the required parts of the message, they do not need to be repeated. This signature is then added to the message: The verifier MUST validate both signatures before processing the request for key rotation. </ins> 7.3.2. This method is indicated by the method value "mtls".  This method first-use.  See security-mtls and security-mtls-patterns for some additional considerations for this key proofing method. <ins> 7.3.2.1. Since it is not possible to present two client authenticated certificates to a mutual TLS connection simultaneously, dynamic key rotation for this proofing method is not defined.  Instead, key rotation for MTLS-based client instances is expected to be managed through deployment practices, as discussed in security-mtls-patterns. </ins> 7.3.3. This method is indicated by the method value "jwsd".  This method ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method. <ins> 7.3.3.1. When rotating a key using Detached JWS, the message, which includes the new public key value or reference, is first signed with the old key using a JWS object with "typ" header value "gnap-binding- rotation+jwsd".  The value of the JWS object is then taken as the payload of a new JWS object, to be signed by the new key. </ins> 7.3.4. This method is indicated by the method value "jws".  This method ath with a new header that upgrades the algorithm, and possibly defining a new header that indicates the HTTP content's hash method. <ins> 7.3.4.1. When rotating a key using Attached JWS, the message, which includes the new public key value or reference, is first signed with the old key using a JWS object with "typ" header value "gnap-binding- rotation+jwsd".  The value of the JWS object is then taken as the payload of a new JWS object, to be signed by the new key. </ins> 8. GNAP provides a rich structure for describing the protected resources


As this interaction mode is designed to facilitate interaction via a secondary device, it is not expected that the client instance <del> redirect the end user to the URL given here at runtime.  If the </del>  client instance is capable of communicating an short arbitrary URI to the end user for use with the user code, the client instance can instead use the request-interact-usercodeuri method instead.  If the

Requires all URIs to be absolute throughout the protocol.
To edit notification comments on pull requests, go to your ._
While it doesn't say so in the spec and the example suggest otherwise, are relative URLs allowed for properties such as the response. Scenario, an implementation is deployed at a URL: URL The root of the server handles grant requests: to The application code that builds the response must be able to construct the full URL and therefor have knowledge of the host at which the application is deployed including any path prefix. This is not impossible, but in complex cloud deployments with load balancers and ingress services etc between the application code and the public endpoint this can get ugly. The current example from Section 3.1 of the spec. Implementations would be significantly easier to build if they could simply return:
To be clear, the base URL for any relative URL response would be the request URL.
Things get really tricky if you start to allow for things like directory ascension (../../continue) and other such things. Lots of attacks in the past stem from exploitation of devices like this. Application deployments that deal with external urls already have techniques for managing such urls, from proxy rewrites to internal configuration. With these together I don't see a good argument for this being anything but an absolute uri.
Is it necessary to state somewhere that all URIs are absolute?
Yes, we should say exactly that, that's why I am keeping this issue open. Thanks for pointing this out!
Makes sense

As this interaction mode is designed to facilitate interaction via a secondary device, it is not expected that the client instance  <ins> redirect the end user to the URI given here at runtime.  If the </ins> client instance is capable of communicating an short arbitrary URI to the end user for use with the user code, the client instance can instead use the request-interact-usercodeuri method instead.  If the


negotiating the parameters of the request through modification of the request.  To enable this ongoing negotiation, the AS provides a continuation API to the client software.  The AS returns a "continue" field response-continue that contains information the client instance needs determine a single active grant request to map the continuation request to, the AS MUST return an error. <del> The ability to continue an already-started request allows the client instance to perform several important functions, including presenting additional information from interaction, modifying the initial request, and getting the current state of the request. </del> All requests to the continuation API are protected by this bound continuation access token.  For example, here the client instance makes a POST request to a stable continuation endpoint URI with the

To edit notification comments on pull requests, go to your .
It's a continuation of the discussion started in URL which I would like to track as a separate issue. If we want to have that then the client should be able to wait and handle a delayed response say after 60 - 120 seconds, and the client should be able to gracefully handle various timeous (client and from the network infrastructure) and make a subsequent call, and the client should know what to do with the "wait" field when a timeout occurs in the previous step. I think it could be a great addition to this specification. Furthermore, take a look at and how they leverage the HTTP long polling mechanism.
The specification allows using the HTTP long polling mechanism against the OAuth2 token endpoint in somewhat similar circumstances. I had some spare time to research this topic a bit deeper and don't have a good answer on how it was possible for me to have the abovementioned specification out of sight. Again, it would be such a great thing to have a bit more instant notification mechanism in the specification core, I mean, not in its extensions or in one or another out of band/vendor-specific solution.
I wonder if we can do better than just telling the RC to poll the AS. There are a few options: http long polling, this should "just work", so long as is defined to allow it (we had quite extensive discussion over this for CIBA) webhook, this could be something quite interesting to add in to the spec as it has many other uses.
Interesting. We should probably map those technical possibilities to detailed use cases.
I believe both of these options are already available. As you say, long polling should just work, and we'd do well to pull in the lessons learned in CIBA. The "callback" method allows for a "push" notification for post-interaction, which is functionally equivalent to a webhook. The asynchronous authentication example is meant to be just that -- an example of how to accomplish this, not a required combination for that use case.
If long polling "just works", please mention it in the draft as an option.
There are still details to check out, like in CIBA long polling, if I remember well, there is a question of delay (like 30s). In practice there might be questions related to how to avoid DDoS. The difference I imagined in webhooks were more related to callbacks not specifically tied to a UI interact, but I'm not exactly sure which use cases that would cover. Maybe notifications through partner apps, like slack etc.
Thanks NAME I'd missed that.
Yep, there are many other uses for webhooks, however I think they may be outside the scope of the core spec. I think the core spec needs to be simplified where possible. Re long polling, I do think it needs to be called out.
The example is very useful here

negotiating the parameters of the request through modification of the request. <ins> The ability to continue an already-started request allows the client instance to perform several important functions, including presenting additional information from interaction, modifying the initial request, and revoking a grant request in progress. The AS MAY make use of long polling mechanisms such as discussed in RFC6202.  Instead of returning the current status immediately, the long polling technique allows the AS additional time to process and fulfill the request before returning the HTTP response to the client instance.  For example, when the AS receives a continuation request but the grant request is in the state, the AS could wait until the grant request has moved to the or state before returning the response message. </ins> To enable this ongoing negotiation, the AS provides a continuation API to the client software.  The AS returns a "continue" field response-continue that contains information the client instance needs determine a single active grant request to map the continuation request to, the AS MUST return an error.  All requests to the continuation API are protected by this bound continuation access token.  For example, here the client instance makes a POST request to a stable continuation endpoint URI with the


9.1. If the client instance calls an RS without an access token, or with <del> 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 </del>  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

To edit notification comments on pull requests, go to your .
Yaron: "Speculative" access ("Requesting a Resources With Insufficient Access") is not useful if the response is only a MAY. Why would the RC try it if it is unlikely to provide useful information? Justin: I think the MAY is not quite the right normative application here. It’s a MUST if you’re doing it to do it in this way, but it’s not a MUST for all RS’s everywhere to respond in this fashion. If the RC tries calling an RS that doesn’t respond with this, the RC simply doesn’t know, from any programmatic or automated way, what to do to make the request actually work. Yaron: Sounds like a SHOULD to me - then an RC can assume with reasonable confidence that a random RS will implement it.

9.1. If the client instance calls an RS without an access token, or with  <ins> an invalid access token, the RS SHOULD respond to the client instance with a WWW-Authenticate header field 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 SHOULD use in its access </ins> 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


tokens are an option in GNAP, these types of tokens have their own tradeoffs discussed elsewhere in this section. <del> TLS functions at the socket layer, ensuring that only the parties on either end of that socket connection can read the information passed along that connection.  Each time a new socket connection is made, such as for a new HTTP request, a new trust is re-established that is unrelated to previous connections.  As such, it is not possible with TLS alone to know that the same party is making a set of calls, and therefore TLS alone cannot provide the continuity of security needed for GNAP.  However, mutual TLS (MTLS) does provide such security characteristics through the use of the TLS client certificate, and thus MTLS is acceptable as a key-presentation mechanism when applied as described in mtls. </del>  12.3.

Built To edit notification comments on pull requests, go to your .
The last paragraph of Sec. 12.2 is a bit off. From an IETF perspective, we should be using "transport layer" (TCP, or OSI layer 4) instead of "socket layer". More importantly, modern TLS uses session resumption heavily, meaning that the trust relationship does not end when the L4 connection ends. Granted that we often need to re-authenticate, but the explanation should be more precise.
If you can, please provide more precise text to help this section out. Thanks!
NAME I cannot agree more on that. The specification may also suggest setting the Connection HTTP header to "close" when it isn't desirable to reuse the same connection.
I tried rewriting the text but then realized that the text is incorrect in a deeper way than I commented on. The current text is: The word "continuity" is misused here. MTLS does provide mutual authentication of the TLS session (a TLS session consists of multiple connections). But it doesn't provide continuity, in the sense that each TLS session is authenticated separately, and there is no session identifier bound to all requests. So we need to figure out if "continuity" is a requirement, if it is, address it, otherwise we shouldn't claim to have it but settle on mere mutual auth.
It seems the initial intent is indeed to go beyond mutual authentication, although the related "discontinuity" risks are not called out. For my understanding, by TLS continuity, do we mean a way to resume sessions ? Like session ID or session tickets or PSK ? Or something else ? In my view (perhaps incorrect, because I'm just a basic user of such systems, not a TLS/mTLS designer) : a big part of the difference between TLS + PSK and mTLS seems related to key management. with PSK a secret key is shared between client and server, so we get back to the discussion on out of band key distribution with PKI, we only need one private key per entity, and possibly the setup is simplified by a trusted certificate chain
I would suggest to drop the "continuity" word, and instead, have a normative statement saying that both client and server (server only when using MTLS) MUST validate the other party's identity (RFC 6125-bis, possibly with our own twist) on each new L4 connection.
Yes, we'll do that.

tokens are an option in GNAP, these types of tokens have their own tradeoffs discussed elsewhere in this section.  <ins> TLS functions at the transport layer, ensuring that only the parties on either end of that connection can read the information passed along that connection.  Each time a new connection is made, such as for a new HTTP request, a new trust is re-established that is mostly unrelated to previous connections.  While modern TLS does make use of session resumption, this still needs to be augmented with authentication methods to determine the identity of parties on the connections.  In other words, it is not possible with TLS alone to know that the same party is making a set of calls over time, since each time a new TLS connection is established, both the client and the server (or the server only when using mtls) have to validate the other party's identity.  Such a verification can be achieved via methods described in I-D.ietf-uta-6125bis), but these are not enough to establish the identity of the client instance in many cases. To counter this, GNAP defines a set of key binding methods in binding-keys that allow authentication and proof of possession by the caller, which is usually the client instance.  These methods are intended to be used in addition to TLS on all connections. </ins> 12.3.


The cryptographic methods used by GNAP for key-proofing can support both asymmetric and symmetric cryptography, and can be extended to <del> use a wide variety of mechanisms.  While symmetric cryptographic systems have some benefits in speed and simplicity, they have a distinct drawback that both parties need access to the same key in order to do both signing and verification of the message.  This means that when the client instance calls the AS to request a token, the AS needs to know the exact value of the client instance's key (or be able to derive it) in order to validate the key proof signature. With asymmetric keys, the client needs only to send its public key to the AS to allow for verification that the client holds the associated private key, regardless of whether that key was pre-registered or not with the AS. </del>  When used to bind to an access token, a key value must be known by the RS in order to validate the proof signature on the request.

Built To edit notification comments on pull requests, go to your .
Please take a look a BCP 107 (a.k.a. RFC 4107). You may need a reference here. Originally posted by NAME in URL
Ok but should this text be updated ? In 2005, potential quantum threats were not even anticipated (with impacts on key size for instance)
I think the overall message remains accurate, but you are right that quantum computing was not a concern when RFC 4107 was written. Any updates to RFC 4107 are not part of your task in the GNAP WG.
Sure, thanks for the feedback.

The cryptographic methods used by GNAP for key-proofing can support both asymmetric and symmetric cryptography, and can be extended to  <ins> use a wide variety of mechanisms.  Implementers will find useful the available guidelines on cryptographic key management provided in RFC4107.  While symmetric cryptographic systems have some benefits in speed and simplicity, they have a distinct drawback that both parties need access to the same key in order to do both signing and verification of the message.  This means that when the client instance calls the AS to request a token, the AS needs to know the exact value of the client instance's key (or be able to derive it) in order to validate the key proof signature.  With asymmetric keys, the client needs only to send its public key to the AS to allow for verification that the client holds the associated private key, regardless of whether that key was pre-registered or not with the AS. </ins> When used to bind to an access token, a key value must be known by the RS in order to validate the proof signature on the request.


Additional fields are defined in the IANA-client-instance.  The client instance MUST prove possession of any presented key by the "proof" mechanism associated with the key in the request.  Key proofing methods are defined in the IANA-key-proof-methods and an

Built To edit notification comments on pull requests, go to your .
In Sec. 2.3 we say, "The contents and format of this field are up to the AS." Assuming no pre-registration, this doesn't make sense, because the Client has not interacted with the AS yet. And in fact if pre-reg has taken place, we say this field should be ignored! Maybe say instead: The content of this field is typically statically configured, and MAY be used as a hint to the AS.
The question here is really "pre-registration of what". When we talk about pre-registration in GNAP, we're really referring to pre-registration of specific individual instance keys, and associating those keys with specific attributes. However, things like the class identifier can be used alongside of other fields to make sense of the client's registration request and verify it. Here's a strawman example: you've got a mobile banking ecosystem. All keys for clients are issued as certificates signed by the CA at the time of installation on the devices. The AS doesn't get told about every single key, however, it just has the root CA cert, like usual PKI stuff. There's several kinds of banking apps in this ecosystem. When a client shows up, it presents its individual key along with the class identifier for the kind of app that it is. The AS sees that the cert is issued by the CA and that the class identifier maps the app to one specific set of attributes, including rights it's allowed to ask for. Now before you ask -- yes you could bake all of that into the certificate itself with its own special fields, and I'm sure some will do exactly that. But there's no reason to couple GNAP to that specific kind of PKI solution, though we can use it. There are other ways to remix these functions, and I don't believe that GNAP should take a hard stance on that.
Another consideration: while the client instance may not have contacted the AS yet, the client software can be written with a specific AS in mind. Like a set top box with a class ID claiming to be "FooBarTV version 4", which tells the AS what kind of thing is claiming to connect. This isn't a trustworthy secret value but it can be used by the AS as part of its policy. The editors will add more text for describing use cases like these to help explain what the field is for.

Additional fields are defined in the IANA-client-instance. <ins> Both the "display" and "class_id" are self-declarative and thus the AS SHOULD exercise caution in their interpretation, taking them as a hint but not as absolute truth.  The "class_id" field can be used in a variety of ways to help the a variety of ways to help the AS make sense of the particular context in which the client instance is operating.  In corporate environments, for example, different levels of trust might apply depending on security policies.  This field aims to help the AS adjust its own access decisions for different classes of client software.  It is possible to configure a set of values and rules during a pre-registration, and then have the client instances provide them later in runtime as a hint to the AS.  In other cases, the client runs with a specific AS in mind, so a single hardcoded value would acceptable (for instance, a set top box with a "class_id" claiming to be "FooBarTV version 4").  While the client instance may not have contacted the AS yet, the value of this "class_id" field can be evaluated by the AS according to a broader context of dynamic use, alongside other related information available elsewhere (for instance, corresponding fields in a certificate).  If the AS is not able to interpret the class_id field, it SHOULD return an "invalid_client" error or choose to return lesser levels of privileges.  See additional discussion of client instance impersonation in security-impersonation. </ins> The client instance MUST prove possession of any presented key by the "proof" mechanism associated with the key in the request.  Key proofing methods are defined in the IANA-key-proof-methods and an


9.1. If the client instance calls an RS without an access token, or with <del> an invalid access token, the RS SHOULD respond to the client instance with a WWW-Authenticate header field 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 SHOULD 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.ietf-gnap-resource-servers.  The content of the resource reference is opaque to the client instance. </del>  The client instance then makes a request to the "as_uri" as described <del> in request, with the value of "access" as one of the members of the </del>  "access" array in the "access_token" portion of the request.  The client instance MAY request additional resources and other <del> information.  The client instance MAY request multiple access tokens. </del>  In this non-normative example, the client instance is requesting a <del> 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 </del>  band.  If issued, the resulting access token would contain sufficient access to be used at both referenced resources.  9.2. Additional methods of discovering the appropriate grant endpoint for generous in supporting many different key formats to allow different types of client software and client instance deployments.  13. The privacy considerations in this section are modeled after the list

fix typos
Built To edit notification comments on pull requests, go to your .
Removing the editorial label after the last change (which is normative)
This discovery method is great for usability but worrying from a security POV. The RS is telling the Client to create a request to an arbitrary AS using an arbitrary access specification and the Client's credentials. The Client doesn't have any way to understand, validate or filter anything in the RS's response, so it cannot protect itself. By the way, shouldn't we use a semicolon before the parameter? A possible workaround is to add something analogous to a parameter to the AS access request containing the RS address, require the Client to include it, and require that the AS validate that the request is indeed to that RS.
In this scenario the client is explicitly looking to the RS to provide a pointer to which AS to talk to. In most cases this is pre-configured (the client knows which AS protects which RS). In some cases this will be communicated at runtime, using this mechanism. There are both security and privacy ramifications for this choice, which we've covered at least some of in the current text. I'm sure this can be expanded.
GNAP is a delegation protocol that enables separation of control from processing with obvious advantages to all three parties (subject, controller, processor). The RS is typically a processor. The choice of AS as delegated controller SHOUlD lie with the subject in order to better represent their interest. This perspective is, of course, not absolute but it the should makes it the preferred path.
NAME I don't see anything explicit about this call. The client just makes a normal-but-unauthenticated call to the RS, with no special indication that it's doing discovery. In fact a malicious RS can redirect the client anyway, even if the client is in fact authenticated. And I don't see anything in the text about the threat vector of a malicious RS. Please also respond to my syntactic comment above.
I've got a few comments on wording. Mostly though: I'm not sure about changing the field to , since it's not just ANY opaque value but specifically an opaque value for use in the access section of the request. As such, I think is too generic in this use. If we change the parameter name back I think this is OK.

9.1. If the client instance calls an RS without an access token, or with  <ins> an invalid access token, the RS SHOULD be explicit about the fact that GNAP needs to be used to access the resource, by responding with the WWW-Authenticate header field and a GNAP challenge. In some situations, the client instance might want to know with which specific AS it needs to negotiate for access to that RS.  The RS MAY additionally return the address of the GNAP endpoint in the "as_uri" parameter, a "referrer" parameter to indicate which RS initiated the discovery process, and an opaque "access" reference.  The client instance SHOULD then use both the "referrer" and "access" parameters in its access token request.  The "referrer" parameter MUST be the URI of the RS, and the client instance MUST check its value to protect itself.  The opaque "access" 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 value for the "access" reference are out of scope of this specification, but some dynamic methods are discussed in I-D.ietf-gnap-resource-servers. When receiving the following response from the RS: </ins> The client instance then makes a request to the "as_uri" as described  <ins> in request, with the value of "referrer" passed as an HTTP Referer header field and the "access" reference passed unchanged into the </ins> "access" array in the "access_token" portion of the request.  The client instance MAY request additional resources and other  <ins> information. </ins> In this non-normative example, the client instance is requesting a  <ins> single access token using the opaque access reference "FWWIKYBQ6U56NL1" received from the RS in addition to the "dolphin- metadata" that the client instance has been configured with out of </ins> band. <ins> The client instance includes the Referer header field as a way for the AS to know that the process is initiated through a discovery process at the RS. </ins> If issued, the resulting access token would contain sufficient access to be used at both referenced resources. <ins> Security considerations, especially related to the potential of a [compromised RS]{#security-compromised-rs} redirecting the requests of an otherwise properly authenticated client, need to be carefully considered when allowing such a discovery process.  This risk can be mitigated by an alternative pre-registration process so that the client knows which AS protects which RS. </ins> 9.2. Additional methods of discovering the appropriate grant endpoint for generous in supporting many different key formats to allow different types of client software and client instance deployments. <ins> 12.34. An attacker may aim to gain access to confidential or sensitive resources.  The measures for hardening and monitoring resource server systems (beyond protection with access tokens) is out of the scope of this document, but the use of GNAP to protect a system does not absolve the resource server of following best practices.  GNAP generally considers a breach can occur, and therefore advises to prefer key-bound tokens whenever possible, which at least limits the impact of access token leakage by a compromised or malicious RS. </ins> 13. The privacy considerations in this section are modeled after the list


If issued, the resulting access token would contain sufficient access to be used at both referenced resources.  10. The editors would like to thank the feedback of the following

Built To edit notification comments on pull requests, go to your ._
The discovery process defined in GNAP details how to get information about the AS once you know the grant endpoint and can talk directly to it. We do not cover how to get the grant endpoint, except in the one case of it being provided by the RS at runtime in a response. The core document should at least discuss this gap as intentional, and an extension specification (or several) could be written to fill this gap in different circumstances.

If issued, the resulting access token would contain sufficient access to be used at both referenced resources. <ins> 9.2. Additional methods of discovering the appropriate grant endpoint for a given application are outside the scope of this specification. This limitation is intentional, as many applications rely on static configuration between the client instance and AS, as is common in OAuth 2.0.  However, the dynamic nature of GNAP makes it a prime candidate for other extensions defining methods for discovery of the appropriate AS grant endpoint at runtime.  Advanced use cases could define contextual methods for contextually providing this endpoint to the client instance securely.  Furthermore, GNAP's design intentionally requires the client instance to only know the grant endpoint and not additional parameters, since other functions and values can be disclosed and negotiated during the grant process. </ins> 10. The editors would like to thank the feedback of the following