corresponding to the token labels chosen by the client instance in the request-token-multiple. <del> In this non-normative example, two bearer tokens are issued under the names "token1" and "token2", and only the first token has a management URL associated with it. </del>  Each access token corresponds to one of the objects in the "access_token" array of the client instance's request-token-multiple.

…alue should be the boolean false. Please, correct me if I wrong.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 23bd329e9c764cedfe6a8dd1e26b557aa8fda9a6 https://deploy-preview-209--gnap-core-protocol-editors-URL
Ok, I will take care of it a bit later. I also suggest omitting from other examples as it's a default value.
Done.
We'll need to add an example of in at least one location, but otherwise these changes are good.
Done in URL
The intent was to make the examples bound tokens by default, so instead of changing the examples, any text surrounding these examples referring them as bearer needs to be adjusted appropriately.

corresponding to the token labels chosen by the client instance in the request-token-multiple.  <ins> In this non-normative example, two tokens are issued under the names "token1" and "token2", and only the first token has a management URL associated with it. </ins> Each access token corresponds to one of the objects in the "access_token" array of the client instance's request-token-multiple.


[[ See issue #42 [4] ]] <del> Note: the "subject_types" and "assertions" request fields are independent of each other, and a returned assertion MAY omit a requested subject identifier. </del>  [[ See issue #43 [5] ]]

align with I think however this might be a problem when we already use in the text, in many places (token format, key format, assertion format etc.). Ex in section 2.2, we would have formats (relates to subject identifiers) and just below we discuss assertions: "assertions (array of strings) An array of requested assertion formats." Of course we could change when there's potential confusion, but it shows it's not that straightforward. Therefore I submitted this PR to see what it does, but I think we should hold that change and ask why format is the best term for the job. Types seems more adequate a priori (a type of identifier), but there's probably a reason why they chose format instead. Even if it's still a draft, we should also ask whether it's considered stable, since our syntax depends on it. Of course, if it changes later, a mapping is possible, but that's extra gruntwork for all parties (one of the value of using sub_ids is to make the mapping straighforward). Please let me know what you think. If agreed, I can reach out to the editors.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 328e5750fea6b5e8664b305133695702f6753c86 https://deploy-preview-220--gnap-core-protocol-editors-URL
This PR is also related to as we must consider when more information about a particular subject identifier format needs to be communicated.
To be seen with SECEVENT WG for sub_ids I'm also including some questions from the ML (here Tobias).
Thanks NAME to generalize this beyond DIDs and relate it to your PR , there may be a need to communicate more detail about the subject identifier formats that the client instance supports in its request to the AS.
In my opinion (as an individual), we need to walk a very careful line about the complexity we define around end user information like this. Presenting and receiving both identifiers and assertions is, to me, pretty straightforward. Both are self-contained bits of information that are meant to be taken in a presentation context. Moving beyond this, things could get hairy fast. I personally think it makes a lot of sense to enable this kind of thing, but I'm inclined to think that this kind of more advanced presentation and negotiation would be better as a DID-specific extension, and I'd like to see what that looks like. One of the things that the core protocol needs to be able to do is support more complex extensions without breaking.
Yes, the first step anyways is to see where SECEVENT lands on with regards to DIDs (just as basic identifiers).
Some text proposal is required to go forward on this issue.
A DID is a reference to a (typically) public control structure called a DID Document. Because DID Documents are presumed public and therefore easily aggregated and indexed, it's desirable to limit their content to only those structures strictly dependent on control by the DID subject. This includes authentication and encryption keys as well as service endpoints. The service endpoints are the demarcation between the public DID Document and private resources under control of the DID controller. DID Service Endpoints can be used for most anything but two particular service types stand out: communication (e.g.: an inbox) and authorization (e.g. an authorization server). A communication endpoint expects to handle a resource directly whereas an authorization server endpoint expects to return an access token to a resource. Either the communication or authorization service endpoints can optionally be proxied by a mediator in order to reduce the risk of correlation across multiple service domains. As end-users to the AS, DID subjects can be either the resource owner or a requesting party. Either way, the DID Document can be an effective way to manage authentication, present claims, and sign requests. A resource owner could use a DID to authenticate to the policy management endpoint of an AS and to provide a service endpoint for AS requests, warnings and errors. Capabilities issued to the resource owner by a resource server (RS) could be delegated to the AS as part of the policy management process. A requesting party could use a DID to present claims and sign requests to the AS with the goal of receiving an access token. When an end-user presents an access token as a capability to an RS, a DID may also be required as a matter of RS policy. The DID might be associated with the end user or with a third-party notary that is part of an audit or accountability process. Because it is typically pubic, the DID service endpoint considerations for an end-user are tied to the costs of processing unsolicited messages and requests. For example, the service endpoint could expect a refundable deposit to cover processing costs.
Interesting as an overview of possibilities. There are quite a few implications for implementers, who will need guidance on how to do that in practice. I'd suggest to also review the difference between public DIDs vs potentially more restricted DIDs (eg. peer, orb, keri).
DIDs like peer, orb, keri avoid the cost and transparency of a public ledger while preserving the self-certifying feature of DIDs. This does not change anything when DIDs are used for authorization and delegation such as the cost of processing unsolicited messages and requests. The public ledgers themselves do not typically "publish" DIDs or DID Documents either but simply provide a root of trust for the authenticity of a self-certifying DID. The use of any DID and associated assertions incurs a privacy risk to the subject and a cost to either the controller or their delegate. The costs can vary widely across . Resolution, the process of going from a DID to a DID Document, is only costly to the relying party such as an authorization server. Verifying an assertion through a zero-knowledge proofs, for example, can be designed to shift the cost to the end user or the relying party.
Yes indeed, my comment was really related to what we mean "typically", especially when there's such a large variety of methods in the wild, some of which might expose the user more than others. It is entirely possible to publish DIDs and their updates, so a bit of guidance as to what we consider good practice might help.
It might be wise to steer clear of the DID method issues. The DID document I linked above could be enhanced with some GNAP-related points if we have some. GNAP can provide guidance on how to use service endpoints based on the without any method-specific language.
I like the idea.
Closing this issue, as a consequence of secevent update to include DIDs

[[ See issue #42 [4] ]]  <ins> Note: the "formats" and "assertions" request fields are independent of each other, and a returned assertion MAY omit a requested subject identifier. </ins> [[ See issue #43 [5] ]]


To protect the request, the JOSE header MUST contain the following additional parameters.  The HTTP Method used to make this request, as an uppercase ASCII string. To protect the request, the JWS header MUST contain the following additional parameters.  The HTTP Method used to make this request, as an uppercase ASCII string.

Suggested changes for URL
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 5602b657d1be7c2b17685269030092799ccb120f https://deploy-preview-226--gnap-core-protocol-editors-URL
This PR is now pending merge, linking with a new issue for verification (to check the value based on typ).
Key proof sections do not currently detail how to verify each method, including requirements for verifying fields, this needs to be added.
The idea is to minimize ways to reuse JWS objects . These attacks are sometimes referred as Swapping JWTs and Cross-JWT Confusion). See also discussion in URL

To protect the request, the JOSE header MUST contain the following additional parameters. <ins> The type header, value "gnap-binding+jwsd". </ins> The HTTP Method used to make this request, as an uppercase ASCII string. To protect the request, the JWS header MUST contain the following additional parameters. <ins> The type header, value "gnap-binding+jws". </ins> The HTTP Method used to make this request, as an uppercase ASCII string.


response-interact.  [[ See issue #89 [34] ]] For example, if the request is successful in causing the AS to issue <del> access tokens and release subject claims, the response could look like this: </del>  With this example, the client instance can not make an additional continuation request because a "continue" field is not included.

Replaces most examples by on email, as discussed in and
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 36777fd4186ad5d5f3d9e64c1120277ab52806d2 https://deploy-preview-228--gnap-core-protocol-editors-URL
Requesting User Information: Editor's Note: What we're really saying here is that "even if the AS gives you an email address to identify the user, that isn't a claim that this is a valid email address for that current user, so don't try to email them." In order to get a workable email address, or anything that you can use to contact them, you'd need a full identity protocol and not just this. Also, subject identifiers are asserted by the AS and therefore naturally scoped to the AS. Would changing the name to "assubids" or "localsubids" help convey that point?
Perhaps the example in this section should not include asking for the email here if we want to encourage asking for the email claim from OpenID instead.
NAME that's actually the core point of this issue: there's a semantic difference between asking for "tell me who the current user is, and I know them by an email address identifier" vs. "tell me the email address of the current user so that I can email them". The subject identifiers are the former, OpenID and other identity protocols would give you the latter.
See also .
It would be better to use examples that are not related to emails, to avoid confusion. I believe an "as_uid" (unique identifier local to the AS) could be best as an example that conveys the message.
Yaron: "Subject identifiers requested by the RC serve only to identify the RO in the context of the AS and can't be used as communication channels by the RC" - this sounds a bit naive, people will do that anyway. So why is this a useful statement? (And similarly in 3.4) Justin: This inclusion is based roughly off of a similar constraint in OIDC around subject identifiers: URL I agree that people will do dumb things anyway, but that’s why we need to spell out why it’s dumb here. Yaron: I haven't looked at the OpenID text, but at least here, we do not_ explain why using the email address to send email is a bad idea, we just say that it is. I think we should give a rationale.
There are many reasons why we don't want emails ("should not use email"). No assurance it's unique (ex: EMAIL) No idea on email policy (could be transfered to someone else) Ties to a delivery method (which shouldn't be our goal here) Also not using email facilitates the distinction with what OIDC/authentication mechanisms provide (more an internal argument for the specification text itself). Might also want to push forward privacy enhancing mechanisms.

response-interact.  [[ See issue #89 [34] ]] For example, if the request is successful in causing the AS to issue  <ins> access tokens and release opaque subject claims, the response could look like this: </ins> With this example, the client instance can not make an additional continuation request because a "continue" field is not included.


person, organization or device. <del> statement asserted locally by an AS about a subject. </del>  1.4. client instance (such as the subject of an issuer and subject pair), while others forms (such as email address and phone number) are intended to allow the client instance to correlate the identifier <del> with other account information at the client instance.  The client instance MUST NOT request or use any returned subject identifiers for communication purposes (see request-subject).  That is, a subject identifier returned in the format of an email address or a phone number only identifies the RO to the AS and does not indicate that the AS has validated that the represented email address or phone number in the identifier is suitable for communication with the current user.  To get such information, the client instance MUST use an identity protocol to request and receive additional identity claims.  The details of an identity protocol and associated schema are outside the scope of this specification. </del>  [[ See issue #75 [26] ]]

Reflect the various scopes possible in sub_ids Some are local to the AS, some enable dereferencing
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit fef94aa06f805be88e9d958929ca0cafe0bd6c8f https://deploy-preview-229--gnap-core-protocol-editors-URL
I'm confused. This reflects that we want to support both locally-scoped subjects and also non-locally ("federated"?) scoped ones. So does the comment in with subject identifiers. But the move to means that we expect the AS to identify a subject using a single string. Why are we getting rid of the issuer URI?
We're not getting rid of isssub, which is also a valid subid. Opaque is just one additional possibility, local to the AS.
I don't think I agree with this change -- even in the case of an AS sending a globally-scoped identifier like iss/sub (or email, or phone, etc), the connection between the user and that identifier is still being asserted locally by the AS. After all, nothing stops a rogue AS from assering an iss/sub pair that it is not the issuer for. And in the case of a user logging in to the AS with a federated identity, that might actually be desirable to know. The intent of the previous language was to say that the AS is only its own authority and not able to make truly global trusted statements. I think that this can be said better but I don't think removing "locally" gets at that and leaves it too open for misinterpretation.
The rationale is that "asserted by the AS" already provides that information, while the scope of the identifier is defined by the choice of sub_id.
I'm always confused by the meaning of subject identifiers in authorization protocols, not just GNAP. I wonder if this URL framing would be useful?
Add some text in the spec saying that the assertion is made locally by the AS
In section 1.3, subject is defined as: Subject person, organization or device. Given the current definition of a Right (ability given to a subject to perform a given operation on a resource under the control of a RS), it does not make sense to consider that a subject may also be an organization or a device. Delete "organization or a device".
We're mostly interested in having definitions which are consistent throughout the document. In the context of a right associated to an end-user, it is usually applicable to a person. But even then the right could derive from an automatic RBAC system as well. There are other places where subject is applicable to an organization or an IT system, especially for the resource owner. Notice the OR statement, depending on the context it may vary.
A resource owner is still a person: it is neither an organization nor a device: it still does not make sense to consider that a subject may also be an organization or a device.
Not always, the resource owner can very well be your company for instance, and the consent might not require a real person (that's the all point of LDAP for instance).
Do you mean that a subject is either an end-user or a resource owner which may then be either a person or an organization ? Would you have some arguments for a "subject" being a "device" ?
An end user is only a natural person. A RO could be a natural person, an organisation or a device. In the last 2 cases, you have a rule engine instead of a person. An example of a device as a resource owner could be a system (ex a robot, a car, etc.) that controls specific resources. Not very common today tbh, but IoT scenarii make that likely in the future (at least I don't see a reason why it shouldn't be included in a generic definition).
This topic is closely related to the issue . An AS manages end-users and maintains relationships with some ROs, but does not manage organizations, nor devices. "Requesting Subject information" does not really make sense.
We never said the AS managed organisations or devices, and we didn't say either that it managed users. It manages access tokens. It's not because the definition might in some cases allow additional cases that it doesn't make sense. We just need to be very specific as to what kind of subject is concerned when it doesn't apply to all.
Humm ! An AS needs to manage end-users because an end-user needs first to authenticate to the AS before the client it is using may obtain an access token. The authentication mechanism being used is left out of the scope of the document, but an authentication exchange must exist. Once an end-user has been authenticated, it is possible for the AS to know which are his attributes and upon a request from the client they can be enumerated by the AS. "Requesting end-user information" makes sense. while "Requesting Subject information" still does not make sense.
I've reviewed in detail, and I quite definitely think the current definition is fine and fits well with all sequences in 1.4.x. More info also for IETF110.
Closing as discussed last week on the mailing list
Returning User Information: Editor's note: Subject identifiers here are naturally scoped to the AS; even though using an external identifier like an email address or phone number implies a global namespace in use, the association of that identifier to the current user is still under the view of the AS. Would changing the name to "assubids" or "localsubids" help convey that point? Would it also be desirable to have an identifier that's globally unique by design? The "iss_sub" type almost gets us there by explicitly calling out the issuer URL, but tuples are hard to deal with in practice and so tend to get ignored in practice in the OIDC space.
Having reflected on that, I believe sub_ids should be scoped to the AS (but I don't see the value of changing the label). There's no way GNAP can impose a global identifier even if that existed, and there's even value for GNAP to be able to provide portability between identity systems This is helpful, Denis. I will focus on "Then Bob asks to Alice to issue for him an authorization to access the resource." and avoid using any hammers. Let's use something in the news and say the RS is a hospital that gave Alice a J&J COVID vaccine. Alice identified herself to the hospital with a number N. N could have been randomly chosen by Alice or the hospital or N could be Alice's driver's license number right next to her face photo. GNAP should probably deal with both cases. The hospital creates a digital credential that includes the J&J vaccine name and lot number, N, a statement about how N was derived, and a date. The hospital posts this credential at some resource URL, protected by some access token requirement, and gives Alice the "resource URL" instead of or along with a paper vaccination card with the same information as the resource. When Bob asks Alice for an access token, Bob makes a request to Alice and she can either: A - Give Bob the "resource URL" and let him try his luck turning this into an access token somewhere, B - Go to the hospital portal and authenticate somehow and grab an access token that she can return to Bob, C - Give Bob an access token for the resource URL based on some signature that is trusted by the hospital. When Bob gets the resource, it will include N along with the hospital's statement about how N was derived. Bob can decide what to do next. Adrian Denis wrote: >

person, organization or device.  <ins> statement asserted by an AS about a subject. </ins> 1.4. client instance (such as the subject of an issuer and subject pair), while others forms (such as email address and phone number) are intended to allow the client instance to correlate the identifier  <ins> with other account information at the client instance.  The AS MUST ensure that the returned subject identifiers only apply to the authenticated end user.  The client instance MUST NOT request or use any returned subject identifiers for communication purposes (see request-subject).  That is, a subject identifier returned in the format of an email address or a phone number only identifies the RO to the AS and does not indicate that the AS has validated that the represented email address or phone number in the identifier is suitable for communication with the current user.  To get such information, the client instance MUST use an identity protocol to request and receive additional identity claims.  The details of an identity protocol and associated schema are outside the scope of this specification. </ins> [[ See issue #75 [26] ]]


OPTIONAL.  The key that the token is bound to, if different from the client instance's presented key.  The key MUST be an object or <del> string in a format described in key-format, describing a public key to which the client instance can use the associated private key.  The client instance MUST be able to dereference or process the key information in order to be able to sign the request. </del>  OPTIONAL.  Flag indicating a hint of AS behavior on token rotation.  If this flag is set to the value "true", then the processing requirements for each are detailed in binding-keys. The "proof" field is REQUIRED. <del> Value of the public key as a JSON Web Key RFC7517.  The object MUST contain an "alg" field which is used to validate the signature.  The object MUST contain the "kid" field to identify the key. </del>  PEM serialized value of the certificate used to sign the request, with optional internal whitespace per RFC7468.  The PEM header and

Suggested changes after the discussion in URL I believe GNAP may also require using the JWK thumbprint as a "kid" (Key ID) value as described in with the hashing algorithm agreed in advance, for example, SHA256. That will be a collision-resistant value and protection against misuse.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit cc79f5b5fef3c6ae35629a650c2f8b4115db3c83 https://deploy-preview-232--gnap-core-protocol-editors-URL
+1 for "The alg parameter MUST NOT be none", and the rest of the proposed change seems fine to me.
GNAP may also allow omitting the public key and specify "jku" (JWK set URL) and "x5u" (X.509 URL) parameters instead. That will allow rotation of the keys (only for the jwk key format) by the client at its jwks_uri endpoint. See also URL In this particular case, I'm guessing it may not allow mixing different parameters such as the public key and or both and . Although, it's debatable. If allowed, the AS MUST NOT blindly follow these parameters per recommendations at URL
Fetchable keys were under consideration in but the WG decided to table that for now and focus on keys by value and by direct reference instead, due to the complexities around security of key fetching. We'll still need to deal with rotation of keys by value even if we allow fetchable keys, and the rotation of fetched keys isn't straightforward are susceptible to cache poisoning and other attacks. In this PR, I agree with NAME that the 'must not be ' text is good, but the text might not be helpful because of what's discussed in
URL suggested replacing and with JWKs and their properties. It isn't quite the same as the changes here Yes, we can remove that allows specifying the parameter only corresponding to the provided public key if WG wants to do so. Note, JWKs remain to be very flexible and if the goal is to allow only public keys we probably should explicitly specify what is allowed. Interestingly enough, a JWK as the format can contain both public and private keys and I don't think it's desirable to allow.
The definition already states that these are public keys. Shared keys aren't allowed to be passed by value, but could instead be passed by reference through either the client instance identifier or the key reference, if either is applicable to the situation. I'd like to hear feedback from other implementors on the utility of including the language around in this definition here.
Related to public/private keys: The text in section 7 is clear I think We might want to remove the part in bold in section 3.2.1 "describing a public key to which the client instance can use the associated private key." I don't think that brings anything (of course it corresponds to a known keypair). As for fetchable keys, might be something to deal with in a separate issue, as they indeed bring their own challenges
The current version of URL allows specifying , as well as and for a DPoP proof. The PR doesn't change anything about and / . Yes... it could be a separate issue. I'm guessing that certificates are only one way to go in certain deployments.
Binding Keys: Editor's note: We are going to need a way for a client to rotate its keys securely, even while an ongoing grant is in effect.
The easiest way for a client to rotate its keys is to handle a URL in the claim to the client's JWKs endpoint on the AS side (the same also applies to the claim for certificates). "OpenID Connect Dynamic Client Registration" and "OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591)" use the parameter for that. Personally, I don't think this approach will work that well for all possible scenarios because we can't assume that all clients have a way to publish and make sure their JWKs endpoints are always reachable for the AS. Furthermore, a client may not have or simply lost control of the domain and an attacker may make use of it. I guess it's totally fine to use this approach in one security domain where you have full control over all components and trust them (clients, the AS, DNS servers) but IMO, it isn't going to be a secure enough approach if you don't have that. That also won't work for the and key formats defined in the current specification. I was never been a big fan of this approach (or I'm missing something important) but it may work even OTB if the specification doesn't forbid us to do that and a JWS library of your choice supports this. Another option would be to introduce the client key management URI (similar to Token Management URI) which accepts an object with similar properties to what and where the goal of the AS to make sure that that the client does have key material. Upsides may work for all currently defined, as well as for future key formats pretty much in the same fashion no need to advertise the client key management URI using the Discovery mechanism which is great and inlined with "the protocol minimizes the need for any pre-flight discovery" the client does not need to have any special knowledge on how to obtain and use tokens to rotate its own keys each client may have its own independent client key management URI These are my thoughts.
Another item that is a bit specific is 7.1.1 (key reference). Since "dereferencing this value are out of scope for this specification", so is rotation. I guess we assume there's some out of band KMS for that.
I may also add yet another item for section "10.1. Introspecting a Token"
I'm more in favor of a defined API that the client can use to update its keys as well as anything else it needs to, a la RFC7592. Features that rely on the AS to fetch the latest values are susceptible to a number of problems: Not all clients can host URLs (mobile clients specifically, and these are most likely to want to rotate keys dynamically) The AS fetching items opens it up to SSRF attacks, as has been documented in OAuth/OIDC against parameters like jwks_uri It's up to the AS to get the cache right on keys during a rotation event, and detect when to invalidate the data it holds; if a client pushes key information when it changes then this isn't an issue Flexibility on key formats is extremely helpful, we can't assume everyone's going to use the same kinds of keys in every environment Clients are probably going to want to update other stuff about themselves, including display names and webpages and the like over time Clients should be able to rotate keys to an ongoing grant in a secure fashion (prove possession of old and new keys together) without changing their overall "Registration": in other words, a client instance could use many different keys and handle them on different lifetimes, not just one "registered" key The last point is really important: we need to be careful we don't make the same limiting assumptions that OAuth2 does in terms of client registration. This has been one of the driving limiting factors that GNAP is trying to address at a fundamental level, and we have to be careful it doesn't creep back in.
I think it'll be important to introduce something soon -- otherwise components are likely to become brittle by treating a client instance's keys (or key thumbprints, or other derived artifacts) as persistent client instance identifiers. For example, imagine a resource server that expects access tokens conveying RARs like: Well, the RS can see this RAR and allow a client to create some folders -- but how does it track which folders were created by a given client instance, so that it can allow the correct client instances to add files to (only) their own folders? The natural/only thing today is to use the introspection API's as a (pseudo)-identifier for the client, correlating these across requests. But that'll become unreliable when client instances can rotate their own keys, and we'll need a way to reflect in the data model something like a "client instance identifier" (independent of keys) or a "client instance's original key" property or what-have-you. (Now you could argue that this style of RAR modeling is broken, but I think it's actually quite common and expressive. Compare for example with Google Drive OAuth permissions for add-ons like "Can read documents it's installed in" -- you don't say which documents at the time of approval, and the system needs to track installs relative to this client and authorization).
(RAR) requests should go to the AS because that’s where they will be processed into access tokens. If the request happens to go to the RS first, it’s a failure of data minimization. Discovery style (AS or RS-first) may not be determined by GNAP but GNAP can make sure that this privacy issue is adequately considered in the spec. Adrian
I think you've misunderstood my point NAME -- I'm not suggesting requests would be sent to the resource server. Rather, as GNAP specifies: an access token (issued by the authorization server) is sent by the client to the resource server, and the RS introspects this token to learn what Resource Access Rights the token conveys. I'm pointing out here that the RS often needs some stable identifier for the client instance to do its job -- and in a world where client instances can rotate their own keys, the client instance key cannot be that stable identifier.
NAME Sorry for the confusion. I've been tutored by capabilities gurus to be suspicious of any identity-related access controls and I consider client identity to be part of that design. That's not to say that GNAP must normatively forbid client credentials, of course. When clients need pre-registration and rotation is important, couldn't client instances be identified by DIDs just like anything else?
Client instances could be identified in all kinds of ways; my point is that currently (at least, if I'm reading the spec correctly -- and it's entirely possible I'm just missing something) GNAP doesn't model this information in an explicit RS-facing data element.
My concern is metadata the RS persists as a result of a RO and AS relationship. RS persisting client identifiers or information as part of the RO and AS relationship limits the RO's ability to delegate to agents that they choose and I would like to keep that out of the core spec as much as possible. The RS can avoid any client information issues in one of two ways: (a) it can issue capabilities to the RO that the RO can pass to any AS, or (b) the RO can register an AS they choose with the RS and then the RS can use an AS introspection endpoint to expose client information to the AS before acting on the token. Are you suggesting that GNAP is unable to do (b)?
The point I've trying to make (and it seems I'm failing to communicate clearly -- sorry!) is that GNAP can and should provide a way to do (b). It's as "simple" as deciding this is a problem worth addressing, and standardizing a solution (or else deciding it's out of scope and leaving it to extension space. (I should note that even under (b), the RS absolutely needs to persist some kind of grant-specific identifier in order to associate with certain resources, at least for certain styles of RAR modeling -- see my initial comment. If you don't like this, you can always avoid those styles of RAR modeling, but they do exist, and they're expressive and useful.)
NAME You are correct that there is not a persistent client instance identifier that's exposed throughout the system, and that's been a deliberate design decision. While there are many kinds of software for which persistent identifiers make sense, we've seen with SPAs and mobile apps in OAuth that client_id gets in the way in a lot of places and doesn't end up telling you what you might think it does. Also note that the key bound to an access token might vary over time more than the client's "registered" key. We don't want to assume this will all be the same all the time, OAuth has already shown us that not to be the case. To the scenario you presented, it sounds like a requirement of the API you're protecting that there be some kind of authorization identifier that persists over time. After all, isn't it more than just the client software -- it's also who approved the software and for what purpose. This gets close to a grant identifier (like in ) but exposing that to an RS sounds wrong. Still, I question whether the RS actually needs to know that information all the time. And if it does, then it's up to the AS to provide an RS-facing identifier for the software, user, grant, or whatever else, either in the introspection response or the token itself. The AS would be able to map this identifier across any kind of key rotation, since it would be able to trace the history of key usage and rotation for a client instance over time. Importantly, the result of this might be an identifier that the client instance itself never sees, since it's part of the internal agreement between the RS and AS. To have something like that we'd need to expand the model of what a token represents here with an AS-to-RS-identifier for the client instance.
Agreed with your assessment NAME that a grant identifier solves the problem just fine, and may be invisible to the client itself. My point here on this issue that that if we don't surface something like this in the standard protocol, RSs will (incorrectly) try to use client instance keys for this purpose, and that'll break even worse once those keys can be rotated. So I'm just calling out that is linked to in perhaps a non-obvious way.
NAME that subtle connection's a fair point, especially when the client instance is using some-other-key for the access token. GNAP is built to enable (and perhaps even encourage) diversity of keys, especially for client software that can securely generate a key locally, so we'd expect much client software to use different keys over time. Rotating would tie those together at the AS. What I'm wondering is if we should actually put some warnings in the RS document against the RS using the client's key as a a stable identifier at all, and instead rely on things returned from the AS for all of these reasons.
Yeah, I'd love to see 1) an explicit warning against using a client's key for this purpose and 2) an explicit field introduced in the introspection response (and eventually, incorporated into self-contained token formats) to allow the AS to communicate a stable grant identifier to the RS.
We've got two types of bound keys: tied to a client's identity (and therefore a registered client's record at the AS, either dynamic or static) tied to an access token (including the continuation access token, since it's not a separate item anymore) The keys for an access token could be a simple pass-through pointer to the client instance's key, and this will probably be the default style of implementation. We can to solve these problems separately, but probably using the same key-presentation mechanisms for rotating the key material itself. We could have a client-management API as an extension that allows rotation of the client instance's key itself, and a key-rotation mechanism available as part of token rotation. The token rotation will be part of core.
This should be in the same extension as discussed in
Identifying the RC Key: Editor's note: We will eventually want to have fetchable keys, I would guess. Things like DID for key identification are going to be important.
Fetchable keys can be addressed in a future feature if needed by the community.

OPTIONAL.  The key that the token is bound to, if different from the client instance's presented key.  The key MUST be an object or  <ins> string in a format described in key-format.  The client instance MUST be able to dereference or process the key information in order to be able to sign the request. </ins> OPTIONAL.  Flag indicating a hint of AS behavior on token rotation.  If this flag is set to the value "true", then the processing requirements for each are detailed in binding-keys. The "proof" field is REQUIRED.  <ins> The public key and its properties represented as a JSON Web Key RFC7517.  A JWK MUST contain the "alg" (Algorithm) and "kid" (Key ID) parameters.  The "alg" parameter MUST NOT be "none".  The "x5c" (X.509 Certificate Chain) parameter MAY be used to provide the X.509 representation of the provided public key. </ins> PEM serialized value of the certificate used to sign the request, with optional internal whitespace per RFC7468.  The PEM header and


the RO that the request has been completed. Meanwhile, the client instance loads the continuation information <del> stored at (3) and continue-request.  The AS determines which </del>  ongoing access request is referenced here and checks its state. If the access request has not yet been authorized by the RO in

Typo for section 1.4.3 Asynchronous Authorization, step 6: The continuation information was stored on step (2) not (3) as specified in the latest draft.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit befdba8ad92320248c4d011b13cca4f1dcb51f83 https://deploy-preview-245--gnap-core-protocol-editors-URL
Well spotted.

the RO that the request has been completed. Meanwhile, the client instance loads the continuation information  <ins> stored at (2) and continue-request.  The AS determines which </ins> ongoing access request is referenced here and checks its state. If the access request has not yet been authorized by the RO in


around that ecosystem.  However, GNAP is not an extension of OAuth 2.0 and is not intended to be directly compatible with OAuth 2.0. GNAP seeks to provide functionality and solve use cases that OAuth <del> 2.0 cannot easily or cleanly address.  Even so, GNAP and OAuth 2.0 will exist in parallel for many deployments, and considerations have been taken to facilitate the mapping and transition from legacy systems to GNAP.  Some examples of these can be found in example- oauth2. </del>  1.1.

Fixes issue Note : in the appendix, I used "OAuth 2", elsewhere we talk about "OAuth 2.0". Maybe needs some adjustements.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 40ad74b8eeec1229a14c83324dbcce73533365d9 https://deploy-preview-247--gnap-core-protocol-editors-URL
For the RFC to be self-contained, please add a section to the Introduction (or an appendix) summarizing the main changes from OAuth2/OIDC, and the rationale for each delta. (Originally raised by NAME
Suggest to put this area in the wiki to have a deeper explanation
I've started a wiki page with some content I had written up for another publication: URL
This information is important to the draft's readership, and people are not seeing it (e.g., Denis's mail from March 26). Can we include it as-is in an appendix to the draft?
I will submit a PR as an appendix. Note also that the editors prepared a short paper "Managing authorization grants beyond OAuth 2" that has been accepted at . It was a nice way to get some external reviews. Will be published in
Looks good, just one typo to fix before inclusion.

around that ecosystem.  However, GNAP is not an extension of OAuth 2.0 and is not intended to be directly compatible with OAuth 2.0. GNAP seeks to provide functionality and solve use cases that OAuth  <ins> 2.0 cannot easily or cleanly address. vs-oauth2 further details the protocol rationale compared to OAuth 2.0.  GNAP and OAuth 2.0 will exist in parallel for many deployments, and considerations have been taken to facilitate the mapping and transition from legacy systems to GNAP.  Some examples of these can be found in example-oauth2. </ins> 1.1.


BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.  1.2. The parties in GNAP perform actions under different roles.  Roles are All key binding methods used by this specification MUST cover all relevant portions of the request, including anything that would change the nature of the request, to allow for secure validation of <del> the request by the AS.  Relevant aspects include the URI being called, the HTTP method being used, any relevant HTTP headers and values, and the HTTP message body itself.  The recipient of the signed message MUST validate all components of the signed message to ensure that nothing has been tampered with or substituted in a way that would change the nature of the request. When a key proofing mechanism is bound to an access token, the access token MUST be covered by the signature method of the proofing mechanism. </del>  When used for delegation in GNAP, these key binding mechanisms allow the AS to ensure that the keys presented by the client instance in [[ See issue #105 [48] ]]  7.3.1. This method is indicated by "jwsd" in the "proof" field.  A JWS RFC7515 object is created as follows: <del> The JOSE (JSON Object Signing and Encryption) header MUST contain the "kid" parameter of the key bound to this client instance for this request.  The "alg" parameter MUST be set to a value appropriate for the key identified by kid and MUST NOT be "none".  The "b64" parameter MUST be set to "false" and the "crit" parameter MUST contain at least "b64" as specified in RFC7797. </del>  <del> To protect the request, the JOSE header MUST contain the following additional parameters. </del>  <del> The type header, value "gnap-binding+jwsd". </del>  The HTTP Method used to make this request, as an uppercase ASCII <del> string. </del>  The HTTP URI used for this request, including all path and query <del> components. </del>  <del> A timestamp of the request in integer seconds </del>  When a request is bound to an access token, the access token hash <del> value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash algorithm used in the "alg" header parameter of the JWS's JOSE Header.  For instance, if the "alg" is "RS256", hash the "access_token" value with SHA-256, then take the left-most 128 bits and base64url encode them. </del>  <del> The payload of the JWS object is the serialized body of the request, and the object is signed according to detached JWS RFC7797. </del>  <del> The client instance presents the signature in the Detached-JWS HTTP Header field. </del>  <del> If the request being made does not have a message body, such as an HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated over an empty payload. </del>  <del> When the server (AS or RS) receives the Detached-JWS header, it MUST parse its contents as a detached JWS object.  The HTTP Body is used as the payload for purposes of validating the JWS, with no transformations. </del>  7.3.2. string. The HTTP URI used for this request, including all path and query <del> components. </del>  <del> A timestamp of the request in integer seconds </del>  When a request is bound to an access token, the access token hash <del> value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash algorithm used in the "alg" header parameter of the JWS's JOSE Header.  For instance, if the "alg" is "RS256", hash the "access_token" value with SHA-256, then take the left-most 128 bits and base64url encode them. The payload of the JWS object is the JSON serialized body of the request, and the object is signed according to JWS and serialized into compact form RFC7515. The client instance presents the JWS as the body of the request along with a content type of "application/jose".  The AS MUST extract the payload of the JWS and treat it as the request body for further processing. This example's JWS header decodes to: And the JWS body decodes to: </del>  If the request being made does not have a message body, such as an HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated over an empty payload and passed in the "Detached-JWS" header as described in detached-jws.  [[ See issue #109 [49] ]]  7.3.3. <del> This method is indicated by "mtls" in the "proof" field.  The client instance presents its TLS client certificate during TLS negotiation with the server (either AS or RS).  The AS or RS takes the thumbprint of the TLS client certificate presented during mutual TLS negotiation and compares that thumbprint to the thumbprint presented by the client instance application as described in RFC8705 section 3. </del>  [[ See issue #110 [50] ]] 7.3.4. <del> This method is indicated by "dpop" in the "proof" field.  The client instance creates a Demonstration of Proof-of-Possession signature header as described in I-D.ietf-oauth-dpop section 2.  In addition, this specification defines the following fields to be added to the DPoP payload: </del>  Digest of the request body as the value of the Digest header defined in RFC3230.  When a request contains a message body, such as a POST or PUT request, this field is REQUIRED. <del> When a request is bound to an access token, the access token hash value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash algorithm used in the "alg" header parameter of the JWS's JOSE Header.  For instance, if the "alg" is "RS256", hash the "access_token" value with SHA-256, then take the left-most 128 bits and base64url encode them. </del>  7.3.5. This method is indicated by "httpsig" in the "proof" field.  The <del> client instance creates an HTTP Signature header as described in I- D.ietf-httpbis-message-signatures section 4.  The client instance MUST calculate and present the Digest header as defined in RFC3230 and include this header in the signature. </del>  <del> When used to present an access token as in use-access-token, the Authorization header MUST be included in the signature. </del>  7.3.6. This method is indicated by "oauthpop" in the "proof" field.  The <del> client instance creates an HTTP Authorization PoP header as described in I-D.ietf-oauth-signed-http-request section 4, with the following </del>  additional requirements: The "at" (access token) field MUST be omitted unless this method is being used in conjunction with an access token as in use- access-token.  [[ See issue #112 [51] ]] <del> The "b" (body hash) field MUST be calculated and supplied, unless there is no entity body (such as a GET, OPTIONS, or DELETE request). </del>  <del> All components of the URL MUST be calculated and supplied </del>  <del> The m (method) field MUST be supplied </del>  [[ See issue #113 [52] ]]  8. GNAP provides a rich structure for describing the protected resources

Updates a number of syntacitcal and semantic requirements for key proofing mechanisms and makes the language more generic around the use of the mechanisms in the protocol and its extensions. change "htu" claim to "uri" for JOSE-based methods, - align token hash with latest dpop 'ath' claim, - use body hash for detached JWS with body, - update HTTP message signature syntax, - include verification language,
~At this time, cryptographic and encoded content of examples has not been regenerated and recalculated.~
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 89cb898b4b5275f44b3daf4edd8a15731895469c https://deploy-preview-250--gnap-core-protocol-editors-URL
Cryptographic examples have all been updated.
The security considerations should discuss the differences between PKI-based (with a CA) and non-PKI keys. This is especially relevant to MTLS signing as it changes how the server-side of the TLS connection is deployed.
See discussion on different deployments at: URL
Addressed by security considerations: URL
Key proof sections do not currently detail how to verify each method, including requirements for verifying fields, this needs to be added.
DPoP defines as not containing path or query components, GNAP's JOSE methods use the full URL. The JOSE methods should move to a different claim name to avoid confusion with DPoP.
See comments at URL
Doesn't make sense to me: JOSE is published as an RFC and is well established, so this sounds like an error in DPoP - which should move away from ... What am I missing?
We don't have control over DPoP's claims, those are defined by the OAuth WG. If we continue to keep DPoP signing in GNAP, we will use what they define as much as we can. JOSE as a signing suite is published as an RFC, GNAP is profiling JOSE (specifically JWS) to have a simple detached HTTP message signature method.
The HTTP Message Signatures draft has changed formats, our examples need to be updated to incorporate these changes.
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.
As I was working on a client implementation, it occurred to me that it would be a lot simpler and less error prone to include a hash of the request body in the JWS rather than doing the current "compute-the-JWS-then-remove-the-body" method. This would remove the and fields from the JWS header, and would add a new sentence describing how to calculate the body hash, dropping the dependency on RFC7797: This significantly cleans up the client code, since previously the client would have to generate the JWS, the pull out the header and signature components and reassemble them with an empty body, creating a string like "XXXXX..XXXXX". Now it can use a JWS library without any additional hacks on top.
Such JWS header wouldn't qualify RFC7797 in this case then.
how so?
RFC 7797 requires you to include "b64" in the "crit" header parameter and set the "b64" header parameter to . Lots of existing JWT parsers obey the "crit" parameter. As you mention, you may remove these parameters. Although, it will result in an inability to parse such JWTs by parsers that already support RFC 7797.
Some of the existing parsers provide a convenient way to get "XXXXX..XXXXX" without any hacks on top. For example, take a look at method in URL
Not relying on the additional rules specified in RFC7797 seems like a benefit, less specs to read and less edge cases to handle. Removing a dependency on another spec is a benefit.
Right, these wouldn't be RFC7797 values anymore, they would just be plain JWS objects with a specially calculated payload. We still will have the "XXXX..XXXX" format for payload-less requests (requests without the body, such as GET and DELETE).
I think I'm in favor of this idea, personally. It still fulfills the requirement of covering the message body with the signature method, but it does so in a way that's perhaps more native to most JOSE developers. It's also more conducive to the kinds of deployment models discussed in
I hear you. I would like to add & emphasize that there are two parts to this story. The first part where we create JWTs and accordingly, there is the second part where we verify them. The beauty is that there are lots of libraries that support RFC 7797. The rest of the decently implemented libraries JWTs because they don't know how to proceed with b64 in the crit header parameter and it's really great IMO. It reduces the chances of errors. Now, let’s imagine we omitted b64 from the crit header parameter and started to put the SHA-256 hash in the payload of the JWS object. In this case, the verification process should fail by all existing libraries, right? If you decide to put something like “gnap-detached” in the crit header parameter then you will also need to change the code of a JWT library so this library will be able to process it. I am guessing that isn't always possible, rational, or just easy to do.
The body of this new method would be a base64 encoded hash value, so we actually don't :want: the header at all and we wouldn't be doing RFC7797 here. One thing that's different from what many libraries may expect is that the body doesn't decode into JSON -- but this was always a JWS, not a JWT. Just about every JWS library I've used, these days, allows for an arbitrary payload. Even URL allows for signing an arbitrary string for the payload, but it will base64 encode it first. I think this new approach benefits from not requiring any parameter, enforcement of which I've found hit-or-miss at best in the JOSE community.
NAME will you require the "typ" header parameter to be presented in such JWSs... with the values like "gnap+jwsd" and "gnap+jws"?
The Proving Possession of a Key with a Request section explicitly states that Unfortunately, I don't see how a client can make use of the jws param (Attached JWS payload) to make calls to "regular" RSs. Normally, they won't be ready to accept the "application/jose" content type and the corresponding payload for the endpoint that accepts say "application/json" and "application/xml". I also believe that this specification shouldn't require the payload (HTTP Body) to be included in the calculation of the JWS signature for RSs in case of Detached JWS payload. The reason is that the client (or any logic that validates access tokens) doesn't always have access to the payload and the bright example for this would be NGinx and . Note, this approach isn't limited in any way to NGinx and is extremely popular among various cloud providers. There are also other minor reasons say just huge payloads (like a movie upload) or even a real-time stream (WebRTC) and so on and so forth. Both these items are totally fine and definitely should be required for any calls from a client to an AS though.
URL says this about the payload and HTTP headers and
Attached JWS is highly problematic and limited for exactly the reason you describe: it requires the API the client is calling to accept a JOSE encoded payload instead of its native payload (see ). Plus, this only works for requests with a message body (POST/PUT) so you need to fall back to the detached method for other verbs, and it's really only mostly applicable for JSON payloads though technically you can serialize anything in a JWS so that's just more it feeling "weird" than being wrong. I'm personally not a fan of the method for all these reasons, but several members of the WG have stated that it fits their use cases better than other methods. Inclusion of the body (when present) in the detached JWS request allows it to be validated along with the signature in the reset of the request. A library outsourcing GNAP with something like an auth_request module would need to include the signature calculation in that module, like here: URL An AS is just as likely to be behind a security layer proxy, either externalized as you describe or internal to the app like in Java's servlet filter system. In any event, to handle body integrity you're going to have to handle this as part of the filtering system, like here: URL ... and to me, it's really not any dissimilar to TLS reverse proxies. As for DPoP, note that we're only using the signature method of DPoP here, not the whole protocol extension in its context. The restrictions and guidance you've quoted come from the fact that DPoP is targeted specifically at SPA's running OAuth 2, and so the advice does not apply here.
The changes to get the whole request body in such externalized components in the Kubernetes (and its friends) world are very slim as that somehow defeats the benefits of their use. Note, these components don't act as a proxy. They receive all or only certain headers of an HTTP request, do their own business, and then finally tells whether access is granted. If granted, the whole initial HTTP request gets a couple of new headers like X-Auth-User-* and then forwarded to the right service to be processed further. If not, a caller gets 401 or an HTTP redirect, etc. URL is another example of a component that does pretty much the same as NGinx's auth_request module. There is a bunch of other similar components. I do like that GNAP requires "body" integrity for all interactions between a client and an AS. It feels for me it should be optional for interactions between a client and an RS.
This is where things like the HTTP Message Signatures could help, since the body hash is separate from the signing. The client can calculate the body Digest header and pass that along to the signing component. It could also be that the security components get redesigned to accommodate the security protocols. We already saw that shift when API libraries started handling access tokens instead of just HTTP Basic username/password combos, which is all they used to do. Or when browsers adopted the fetch() API as opposed to the deeply limited capabilities that were there before. Now, I'm not saying that GNAP should count on the world bending to its will, or that we should ignore deployment patterns; but we also shouldn't limit the protocol based on a design choice in software that makes sense today and might not in the future. These libraries only look at a couple headers because that's all they need to do right now, much like in the past they would have just taken in a username and password.
These external components don't really have a choice to read only certain headers or the whole request. They get only what they get from ingress controllers in a cluster. It's very possible that in the future, these controllers (like NGinx or Traefic) will have to provide the SHA-256 hash of the request's payload in order to accommodate the security protocols as you said. It's hard to predict when and if it will happen at all. As of today, this is a very common and extremely popular deployment model.
The approach proposed in should address these concerns by and large, and this issue will close with
Looks fine, but tbh I must test to be sure

BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here. <ins> This document contains non-normative examples of partial and complete HTTP messages.  Some examples use a single trailing backslash '' to indicate line wrapping for long values, as per RFC8792.  The "" character and leading spaces on wrapped lines are not part of the value. </ins> 1.2. The parties in GNAP perform actions under different roles.  Roles are All key binding methods used by this specification MUST cover all relevant portions of the request, including anything that would change the nature of the request, to allow for secure validation of  <ins> the request.  Relevant aspects include the URI being called, the HTTP method being used, any relevant HTTP headers and values, and the HTTP message body itself.  The verifier of the signed message MUST validate all components of the signed message to ensure that nothing has been tampered with or substituted in a way that would change the nature of the request.  Key binding method definitions SHOULD enumerate how these requirements are fulfilled. When a key proofing mechanism is bound to an access token, the key being presented MUST be the key associated with the access token and the access token MUST be covered by the signature method of the proofing mechanism. The key binding methods in this section MAY be used by other components making calls as part of GNAP, such as the extensions allowing the RS to make calls to the AS defined in {{I-D.ietf-gnap- resource-servers}}. To facilitate this extended use, the sections below are defined in generic terms of the "sender" and "verifier" of the HTTP message.  In the core functions of GNAP, the "sender" is the client instance and the "verifier" is the AS or RS, as appropriate. </ins> When used for delegation in GNAP, these key binding mechanisms allow the AS to ensure that the keys presented by the client instance in [[ See issue #105 [48] ]] <ins> In the following sections, unless otherwise noted, the "RS256" JOSE Signature Algorithm is applied using the following RSA key (presented here in JWK format): </ins> 7.3.1. This method is indicated by "jwsd" in the "proof" field.  A JWS RFC7515 object is created as follows:  <ins> To protect the request, the JOSE header of the signature contains the following parameters: </ins>  <ins> The key identifier.  RECOMMENDED.  If the key is presented in JWK format, this MUST be the value of the "kid" field of the key. </ins>  <ins> The algorithm used to sign the request.  REQUIRED.  MUST be appropriate to the key presented.  If the key is presented as a JWK, this MUST be equal to the "alg" parameter of the key.  MUST NOT be "none". The type header, value "gnap-binding+jwsd".  REQUIRED </ins> The HTTP Method used to make this request, as an uppercase ASCII  <ins> string.  REQUIRED </ins> The HTTP URI used for this request, including all path and query  <ins> components and no fragment component.  REQUIRED </ins>  <ins> A timestamp of when the signature was created, in integer seconds since UNIX Epoch </ins> When a request is bound to an access token, the access token hash  <ins> value.  The value MUST be the result of Base64url encoding (with no padding) the SHA-256 digest of the ASCII encoding of the associated access token's value.  REQUIRED if the request protects an access token. </ins>  <ins> If the HTTP request has a message body, such as an HTTP POST or PUT method, the payload of the JWS object is the Base64url encoding (without padding) of the SHA256 digest of the bytes of the body.  If the request being made does not have a message body, such as an HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated over an empty payload. </ins>  <ins> The client instance presents the signed object in compact form RFC7515 in the Detached-JWS HTTP Header field. </ins>  <ins> In this example, the JOSE Header contains the following parameters: The request body is the following JSON object: </ins>  <ins> This is hashed to the following Base64 encoded value: This leads to the following full HTTP request message: When the verifier receives the Detached-JWS header, it MUST parse and validate the JWS object.  The signature MUST be validated against the expected key of the signer.  All required fields MUST be present and their values MUST be valid.  If the HTTP message request contains a body, the verifier MUST calculate the hash of body just as the signer does, with no normalization or transformation of the request. </ins> 7.3.2. string. The HTTP URI used for this request, including all path and query  <ins> components and no fragment component. </ins>  <ins> A timestamp of when the signature was created, in integer seconds since UNIX Epoch </ins> When a request is bound to an access token, the access token hash  <ins> value.  The value MUST be the result of Base64url encoding (with no padding) the SHA-256 digest of the ASCII encoding of the associated access token's value. If the HTTP request has a message body, such as an HTTP POST or PUT method, the payload of the JWS object is the JSON serialized body of the request, and the object is signed according to JWS and serialized into compact form RFC7515.  The client instance presents the JWS as the body of the request along with a content type of "application/ jose".  The AS MUST extract the payload of the JWS and treat it as the request body for further processing. </ins> If the request being made does not have a message body, such as an HTTP GET, OPTIONS, or DELETE method, the JWS signature is calculated over an empty payload and passed in the "Detached-JWS" header as described in detached-jws. <ins> In this example, the JOSE header contains the following parameters: The request body, used as the JWS Payload, is the following JSON object: This leads to the following full HTTP request message: </ins> [[ See issue #109 [49] ]] <ins> When the verifier receives an attached JWS request, it MUST parse and validate the JWS object.  The signature MUST be validated against the expected key of the signer.  All required fields MUST be present and their values MUST be valid.  If the HTTP message request contains a body, the verifier MUST decode the payload of the JWS object and treat this as the HTTP message body. </ins> 7.3.3.  <ins> This method is indicated by "mtls" in the "proof" field.  The signer presents its TLS client certificate during TLS negotiation with the verifier. In this example, the certificate is communicated to the application through the "Client-Cert" header from a TLS reverse proxy, leading to the following full HTTP request message: The verifier compares the TLS client certificate presented during mutual TLS negotiation to the expected key of the signer.  Since the TLS connection covers the entire message, there are no additional requirements to check. Note that in many instances, the verifier will not do a full certificate chain validation of the presented TLS client certificate, as the means of trust for this certificate could be in something other than a PKI system, such as a static registration or trust-on- first-use. </ins> [[ See issue #110 [50] ]] 7.3.4.  <ins> This method is indicated by "dpop" in the "proof" field.  The signer creates a Demonstration of Proof-of-Possession signature header as described in I-D.ietf-oauth-dpop section 2.  In addition, this specification defines the following fields to be added to the DPoP payload: </ins> Digest of the request body as the value of the Digest header defined in RFC3230.  When a request contains a message body, such as a POST or PUT request, this field is REQUIRED.  <ins> In this example, the request body is the following JSON object: ~~~ { "access_token": { "access": [ "dolphin-metadata" ] }, "interact": { "start": ["redirect"], "finish": { "method": "redirect", "uri": "https://client.foo/callback", "nonce": "VJLO6A4CAYLBXHTR0KRO" } }, "client": { "proof": "dpop", "key": { "jwk": { "kid": "gnap-rsa", "kty": "RSA", "e": "AQAB", "alg": "RS256", "n": "hYOJ- XOKISdMMShn_G4W9m20mT0VWtQBsmBBkI2cmRt4Ai8Bf YdHsFzAtYKOjpBR1RpKpJmVKxIGNy0g6Z3ad2XYsh8KowlyVy8IkZ8NMwSrcUIBZG YXjHpwjzvfGvXH_5KJlnR3_uRUp4Z4Ujk2bCaKegDn11V2vxE41hqaPUnhRZxe0jR ETddzsE3mu1SK8dTCROjwUl14mUNo8iTrTm4n0qDadz8BkPo-uv4BC0bunS0K3bA_ 3UgVp7zBlQFoFnLTO2uWp_muLEWGl67gBq9MO3brKXfGhi3kOzywzwPTuq-cVQDyE N7aL0SxCb3Hc4IdqDaMg8qHUyObpPitDQ" } } "display": { "name": "My Client Display Name", "uri": "https://client.foo/" }, } } ~~~ The JOSE header contains the following parameters, including the public key: The JWS Payload contains the following JWT claims, including a hash of the body: This results in the following full HTTP message request: The verifier MUST parse and validate the DPoP proof header as defined in I-D.ietf-oauth-dpop.  If the HTTP message request includes a message body, the verifier MUST calculate the digest of the body and compare it to the "htd" value.  The verifier MUST ensure the key presented in the DPoP proof header is the same as the expected key of the signer. </ins> 7.3.5. This method is indicated by "httpsig" in the "proof" field.  The  <ins> sender creates an HTTP Message Signature as described in I-D.ietf- httpbis-message-signatures. The covered content of the signature MUST include the following: the target of the HTTP request The Digest header as defined in RFC3230.  When the request message has a body, the signer MUST calculate this header value and the verifier MUST validate this header. When the request is bound to an access token, the covered content MUST also include: The Authorization header used to present the access token as discussed in use-access-token. Other covered content MAY also be included. </ins>  <ins> If the signer's key presented is a JWK, the "keyid" parameter of the signature MUST be set to the "kid" value of the JWK, the signing algorithm used MUST be the JWS algorithm denoted by the key's "alg" field, and the explicit "alg" signature parameter MUST NOT be included. In this example, the message body is the following JSON object: This body is hashed for the Digest header using SHA-256 into the following encoded value: The HTTP message signature input string is calculated to be the following: This leads to the following full HTTP message request: If the HTTP Message includes a message body, the verifier MUST calculate and verify the value of the "Digest" header.  The verifier MUST ensure that the signature includes all required covered content. The verifier MUST validate the signature against the expected key of the signer. </ins> 7.3.6. This method is indicated by "oauthpop" in the "proof" field.  The  <ins> signer creates an HTTP Authorization PoP header as described in I- D.ietf-oauth-signed-http-request section 4, with the following </ins> additional requirements: The "at" (access token) field MUST be omitted unless this method is being used in conjunction with an access token as in use- access-token.  [[ See issue #112 [51] ]]  <ins> The "b" (body hash) field MUST be calculated and included, if the message includes an entity body (such as a PUT or PATCH request). </ins>  <ins> All components of the URL MUST be calculated and included, including query parameters "q", path "p", and host "u". </ins>  <ins> The "m" (method) field MUST be included In this example, the request message body is the following JSON object The JOSE header for the PoP token is the following: After calculating the hashes for the body, headers, and URL components, the JWS Payload is the following: This leads to the following HTTP message request: </ins> [[ See issue #113 [52] ]] <ins> The verifier MUST parse the JWS object of the PoP header.  The verifier MUST validate the signature of the header against the expected key of the signer.  The verifier MUST ensure that all required parts of the message are covered by the signature.  The verifier MUST ensure that all components of the signature contain correct values. </ins> 8. GNAP provides a rich structure for describing the protected resources


GNAP allows for the negotiation of the grant process over time by multiple parties acting in distinct roles.  This protocol solves many of the same use cases as OAuth 2.0 RFC6749, OpenID Connect OIDC, and the family of protocols that have grown up around that ecosystem.  However, GNAP is not an extension of OAuth GNAP seeks to provide functionality and solve use cases that OAuth 2.0 cannot easily or cleanly address. vs-oauth2 further details the protocol rationale compared to OAuth 2.0.  GNAP and OAuth 2.0 will <del> exist in parallel for many deployments, and considerations have been taken to facilitate the mapping and transition from legacy systems to GNAP.  Some examples of these can be found in example-oauth2. </del>  1.1. deployed cluster, then this cluster is considered a single client instance.  For another example, an AS could likewise be built out of many constituent components in a distributed architecture.  The component that the client instance calls directly could be different from the <del> component that the the RO interacts with to drive consent, since API </del>  calls and user interaction have different security considerations in many environments.  Furthermore, the AS could need to collect identity claims about the RO from one system that deals with user attributes while generating access tokens at another system that deals with security rights.  From the perspective of GNAP, all of these are pieces of the AS and together fulfill the role of the AS as <del> defined by the protocol. </del>  1.3.

adds a paragraph to the introduction adds specific examples under roles
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit aa65f1110cdcc11a60ca4d2d284e78f7909d0817 https://deploy-preview-254--gnap-core-protocol-editors-URL

GNAP allows for the negotiation of the grant process over time by multiple parties acting in distinct roles. <ins> The focus of this protocol is to provide interopability between the different parties acting in each role, and is not to specify implementation details of each.  Where appropriate, GNAP may make recommendations about internal implementation details, but these recommendations are to ensure the security of the overall deployment rather than to be prescriptive in the implementation. </ins> This protocol solves many of the same use cases as OAuth 2.0 RFC6749, OpenID Connect OIDC, and the family of protocols that have grown up around that ecosystem.  However, GNAP is not an extension of OAuth GNAP seeks to provide functionality and solve use cases that OAuth 2.0 cannot easily or cleanly address. vs-oauth2 further details the protocol rationale compared to OAuth 2.0.  GNAP and OAuth 2.0 will  <ins> likely exist in parallel for many deployments, and considerations have been taken to facilitate the mapping and transition from legacy systems to GNAP.  Some examples of these can be found in example- oauth2. </ins> 1.1. deployed cluster, then this cluster is considered a single client instance. <ins> In these cases, the distinct components of what is considered a GNAP client instance may use any number of different communication mechanisms between them, all of which would be considered an implementation detail of the client instances and out of scope of GNAP. </ins> For another example, an AS could likewise be built out of many constituent components in a distributed architecture.  The component that the client instance calls directly could be different from the  <ins> component that the RO interacts with to drive consent, since API </ins> calls and user interaction have different security considerations in many environments.  Furthermore, the AS could need to collect identity claims about the RO from one system that deals with user attributes while generating access tokens at another system that deals with security rights.  From the perspective of GNAP, all of these are pieces of the AS and together fulfill the role of the AS as  <ins> defined by the protocol.  These pieces may have their own internal communications mechanisms which are considered out of scope of GNAP. </ins> 1.3.