-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IETF 118 : Should this mechanism be used in parallel with Client Authentication /with Dynamic Client Registration #61
Comments
The way this mechanism is designed allows it to be used with other endpoints then the token endpoint (like any other client authentication method). Using client authentication as a way to also do client attestation is not just convenient it also means any client with attestation capabilities can be treated as a confidential client. I would like to understand how people proposing to split client authentication and attestation envision this to work. Would that mean deployments would use public clients + attestations? What would be the benefit? How would dynamic client registration work with attestation? I personally have doubts about the utility of dynamic client registration. It requires the client to dynamically keep track of AS specific credentials including its expiration. Attestation based authentication on the other hand allows a client to just use a single attestation with any compatible AS. |
"Should this mechanism be used in parallel with Client Authentication /with Dynamic Client Registration" feels like two different questions that we may want to discuss separately (albeit if the answer to both is "yes" the solution may be the same for both cases).
DCR requires neither of those things when used with private_key_jwt or MTLS client authentication. (I'd agree that it does probably require the client to keep track of a client_id per AS.) DCR with attestations is fairly commonly used by mobile apps, to establish per-install client credentials. It's certainly not the only solution, but many people find it a useful solution today. The advantage of using attestation at DCR is you only do the attestation process once at registration time, which in the lower risks cases makes things easier to implement on the AS side and simpler for client developers. (For clarify I also agree that there are use cases where presenting attestations every time a client authenticates could make sense.) |
I am not convinced this is completely true; it's actually creating something that sits somewhere between a confidential client and a public client. See for example the special handling needing for refresh tokens as per https://vcstuff.github.io/draft-ietf-oauth-attestation-based-client-auth/draft-ietf-oauth-attestation-based-client-auth.html#section-5.2 but I think it has further implications for AS implementations, for example existing authorised consents would need to be tracked on a per "client instance" basis instead of a per client basis. |
Attestation is just a statement by some entity ("Attester") about certain properties of a client (including its public key, in this case). I don't think attestation implies neither a public nor confidential client. Attestation could be used with both types I believe, because it serves a different purpose than authentication. I see attestation as a method to for the authorization server to get greater confidence in the credentials of a client. I picture, like @jogu, a setup where you can use client attestation (e.g. in an HTTP header or additional query parameter?!) together with existing (or future) client authentication methods such as private_key_jwt or mutual TLS. |
Let me lay out how I understand the ideas of combining DCR with Client Attestation:
My observations to this:
The initial motivation of this draft is to provide identification and authentication of the client instance towards the AS. I'm new to DCR so I might miss a few things here, right now it seems like an extra steps with no benefit to our usecases. |
Maybe I don't know the entire story behind this ticket, but switching to a DCR seems kind of heavy and inefficient to me, as seen from an AS, but also generally, when I try to think how this is going to mesh in a greater system / deployment / federation. I liked the original concept that relied on the attestation. It is efficient and easier to scale. |
Is this handling any different from private_key_jwt? |
Can you please describe how that works? As far as I understand RFC 7591, the AS creates a client id with every registration. There is no special treatment of neither private_key_jwt nor mTLS. I also noticed there is no proof of possession for the key material and there is no key binding for the software statement. That's all built into the client attestation mechanism. |
Yes. The entire concept that one client_id can now have multiple instances and that the AS needs to treat the different instances of that client_id as distinct entities is a brand new concept created in this draft. |
You are right. Since different client instances may use different attestations, the refresh token is no longer just bound to the client id. I think a client id previously already could have multiple instances (think of open banking apps), however the AS did not need to know. Why? Because authentication was done through the respective backend so instance management was application internal. Now, the instances themselves can authenticate, which raises privacy as the backend cannot observer this interaction. The way I see it this draft allows implementation of confidential clients with native apps in a more privacy friendly manner. The attestation part helps the AS to determine whether the instance is really an instance of the respective client id. I guess that's why I believe both concepts belong together. |
I'm not sure that's really counts multiple instances. Or at least it's not just that authentication was in the backend, it's also that the refresh tokens never left the backend so there was no risk of one instance using a difference instances refresh token. I agree with the privacy benefits, but it is a significant change to the security posture. It is clear that the new thing defined in this draft is neither a traditional confidential client nor a traditional public client. I'm struggling to figure out which it is closest too. I think in a lot of ways it feels closest to a public client that's using dpop (particularly when you think of how refresh tokens are bound to the dpop key in that case), but essentially with the addition of attestation for the dpop key. |
I'd concur with that. And there's some discussion over here and above about maybe using the DPoP proof as the PoP mechanism rather than the Client Attestation PoP JWT. Doing that change in conjunction with changing the Client Attestation JWT to be sent via some other parameter ( |
It might not be a broadly enough socialised concept yet but I dont think this draft has invented the notion of a client instance. OAuth 2.1, RFC8705 and the latest OAuth browser BCP all speak informally about client instances. I also dont think the draft is aiming for an AS to treat different instances of a particular client differently beyond that if they fail to authenticate in a way that is required for that client, then of course their request could be rejected. The exception is perhaps the RT language that @bc-pi raised which I agree is very important to prevent one client instance from being able to use another client instances RT.
I like this solution personally, it is much cleaner to explain and feels like it gets the best of both worlds including re-using DPoP more meaning this specification has to invent less. |
This is true, albeit they only speak about instances of public clients. (My original sentence wasn't great; it was the "that the AS needs to treat the different instances of that same confidential client_id as distinct entities is a brand new concept" part that I really wanted to emphasise. And we agree that it's this refresh token related behaviour that's the important and necessary difference.) I strongly agree this latest direction as per your / Brian's comments. |
client instances: the draft allows to authenticate the caller as being an instance of a certain client (id). The client id should then be used by the AS for other logic (such as storing user consent and so on). There is no need to identify the client instance, I would go as far as to state the instance should not be identifiable simply because a client instance identifier would be kind of a user identifier (in case of a native app). I know the key is a co-relation handle, that's why deployments should use short lived or even emphemeral client attestation to foster privacy. attestation vs authentication: In traditional OAuth deployments requiring client authentication (e.g. open banking or commercial/paid schemes), a native app would send requests through its backend, which acts as a confidential client towards the AS. That's the way to ensure the AS talks to a legit client. In emerging use cases (esp. wallets), the way through the backend is seen as not as privacy preserving as it should be. Using the apps backend instead to issue an assertion to its app(s) and use that assertion to authenticate to the AS is the alternative being proposed. The backend uses platform attestation to ensure the caller is a instance of the backend's app. That's the origin of the name attestation based client authentication. Binding the attestation to a key ensures it cannot be replayed by other parties. With such an attestation, the app can directly call the AS (while establishing confidence the AS talks to the legit client). Conclusion: the attestation is used to establish confidence the AS is talking to an instance of a certain client. This is inline with the purpose of client authentication. That's why the idea to use the existing client authentication mechanics here makes sense to me. re public client: I would like to understand how the suggested differentiation between attestation and public client shall work. Can someone please share an example flow with request examples? I would especially like to know what client_id such a public client would use. I'm asking since in the proposed flow, the client_id is determined by the trusted 3rd party issuing the client attestation assertion. |
Just a minor comment: I'm trying to use this standard in the context of the proposed OAuth 2.0 for First-Party Applications standard to prevent client impersonation (I'm on the implementation side). To provide more context, OAuth 2.0 for First-Party Applications is an API-based "authentication" approach, serving as an alternative to the traditional method, which required redirecting or opening a browser. After reviewing the standard, it's not clear to me how the AS can trust the attestation issuer and verify the signature of a client attestation. |
@embesozzi you're not missing anything, that currently isn't stated as far as I know. Like base OAuth as defined in RFC6749 doesn't say much about how you get a client_secret or client_id, it's assumed there's some kind of out of band configuration of what attestation issuers an authorization server trusts and where it gets the keys for those issuers from. (See also openid/oid4vc-haip-sd-jwt-vc#101 which has more discussion.) |
@jogu, I appreciate the feedback and I'll review the discussion. |
In particiuar:
Related to #62
The text was updated successfully, but these errors were encountered: