Change:
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.

Discussion:
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> <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. <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> <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