Skip to content
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

Open
paulbastian opened this issue Nov 10, 2023 · 18 comments

Comments

@paulbastian
Copy link
Collaborator

paulbastian commented Nov 10, 2023

In particiuar:

  • this mechanism should work for other endpoints
  • client attestation should not "take up" the client authentication slot, but be separate
  • How does the AS get the key of the client backend/attestation service? What's the trust mechanism?

Related to #62

@tlodderstedt
Copy link
Contributor

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.

@jogu
Copy link

jogu commented Nov 15, 2023

"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).

@tlodderstedt

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.

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.)

@jogu
Copy link

jogu commented Nov 15, 2023

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

@ju-cu
Copy link

ju-cu commented Nov 15, 2023

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?

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.
+1 for separating client attestation and client authentication via PoP mechanisms
+1 for supporting client attestation with DCR.

@paulbastian
Copy link
Collaborator Author

Let me lay out how I understand the ideas of combining DCR with Client Attestation:

  • before a Wallet/Client interacts with an Issuer/AS, he once sends a request to DCR Endpoint containing:
    • client attestation as authorization
    • some additional data according to RFC 7591
    • some mechanism for client authentication, e.g. client credentials or private_key_jwt
  • Issuer/AS checks the client attestation and registers the Wallet/Client in his Client database under a newly generated client_id,e.g. (client_id, private_key_jwt) and sends response to DCR request
  • Wallet/Client Token Request containing:
    • client authentication, e.g. private_key_jwt
    • DPoP key
  • Issuer/AS responds with Token Response containing the DPoP-bound access token

My observations to this:

  • the biggest difference to the status quo of this specification is that in DCR the AS chooses the client_id, while in our model the Wallet Provider has a client_id that is the same for all client instances and chosen by the Wallet Provider
  • as I understand DCR is usually only called once during registration, in the use cases we have in mind it is very typical to send fresh client attestations to the Issuer/AS
  • as of now, we cannot use client attestations with DCR, because the cleint attestation already contains client_id as the sub value
  • in my opinion it seems a little strange and inefficient that every AS manages client_ids for every wallet instance and all wallets manage separate client_ids for every Issuer
  • We want to have attested public keys in the client attestation that an Issuer may use to bind VCs or other credentials to, that doesn't work very well with DCR

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.

@vdzhuvinov
Copy link

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.

@tlodderstedt
Copy link
Contributor

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

Is this handling any different from private_key_jwt?

@tlodderstedt
Copy link
Contributor

"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).

@tlodderstedt

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.

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.)

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.

@jogu
Copy link

jogu commented Nov 15, 2023

Is this handling any different from private_key_jwt?

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.

@tlodderstedt
Copy link
Contributor

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.

@jogu
Copy link

jogu commented Nov 16, 2023

I think a client id previously already could have multiple instances (think of open banking apps), however the AS did not need to know

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.

@bc-pi
Copy link
Contributor

bc-pi commented Nov 16, 2023

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 (client_key_attestation or something) and decoupled from client authentication is appealing. It'd keep public clients public. But give binding of RT to the DPoP key (the key that's been attested to) without the special handling that's there now but is a really important security property. And could provide this simple attestation (mostly about a key) independent of client authentication. And also stay orthogonal to DCR.

@tplooker
Copy link
Collaborator

tplooker commented Nov 17, 2023

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.

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.

Doing that change in conjunction with changing the Client Attestation JWT to be sent via some other parameter (client_key_attestation or something) and decoupled from client authentication is appealing. It'd keep public clients public. But give binding of RT to the DPoP key (the key that's been attested to) without the special handling that's there now but is a really important security property.

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.

@jogu
Copy link

jogu commented Nov 17, 2023

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.

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.

@tlodderstedt
Copy link
Contributor

tlodderstedt commented Nov 22, 2023

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.

@embesozzi
Copy link

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.
In the context of mobile apps that use public clients, the Authorization Server MUST verify the "first-partyness" of the client. Therefore, I'm implementing client attestation at the token endpoint.

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.

@jogu
Copy link

jogu commented Aug 25, 2024

@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.)

@embesozzi
Copy link

@jogu, I appreciate the feedback and I'll review the discussion.
I've found others proposed standards to address this issue, but as usual, I'll try follow the KISS principle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants