[OID4VCI] keep credential-offer state reusable and align offer-flow tests - #48586
[OID4VCI] keep credential-offer state reusable and align offer-flow tests#48586forkimenjeckayang wants to merge 2 commits into
Conversation
ea92da7 to
8a0058d
Compare
|
@forkimenjeckayang thank you for your PR. Unfortunately, there are some new conflicts that need to be resolved. Could you please take a look when you get a chance? |
5363941 to
f6d8c26
Compare
|
@mposolda, @graziang, @pskopek, @jimmychakkalakal: Could you please help review this community contribution PR when you have a chance? |
|
AFAIK, the VCI tests don't deal with offers at all because there is no standard way to make the Issuer create an offer. and the Issuer returns The credential request then uses the The Perhaps there is another use case that requires the offer state to survive the credential request, could you describe that and explain why the |
Signed-off-by: forkimenjeckayang <forkimenjeckayang@gmail.com>
02b45af to
b5f7b1d
Compare
Thanks for the review and the feedback! I understand the concern, but there's an important distinction here based on the specific test variant being executed. 1. The Conformance Suite DOES use Offers for Pre-Authorized Code
For this specific grant type, the OID4VCI spec (Section 4.1.1) mandates that the 2. Clarification: The
3. Why the Offer State must survive the Credential Request
Before this PR, Keycloak was aggressively deleting the offer state as soon as the first credential was issued ( By allowing the offer state to persist for its normal TTL rather than eagerly deleting it, we strictly comply with Section 14.3. This allows the Wallet to make multiple accesses to the Credential Endpoint without the server falsely failing the request due to premature state cleanup. |
|
This is interesting - thanks. How does the conformance suite tell the Issuer to create a credential offer (i.e. how does This spec requirement ...
makes me wonder whether we should remove the offer state not later but earlier ;-) If the client has an access token derived from a |
Great question about how 1. How the Conformance Suite receives the offer
2. Regarding removing the offer state at the Token Request In Keycloak's current implementation for the pre-authorized code flow, the Token Endpoint injects a custom If we deleted the offer state at the Token Endpoint today, the Credential Endpoint would immediately fail with a By simply keeping the Does this pragmatic approach sound reasonable for the current implementation? |
|
Well, I'd say the lifecycle of a pre-auth offer state should end when it is exchanged for a auth token. It is actually the As far as this PR is concerned, it fine with me that it gets merged as is. In a follow up, I could try to get of references to the offer state from the credential endpoint if all the information ever needed is in the access/refresh token already. Anyway, this "optimization" does not strictly need to be part of this PR |
Perfect, thank you for the thorough review. Insightful observation. |
|
LGTM |
mposolda
left a comment
There was a problem hiding this comment.
@forkimenjeckayang It seems that your PR has lots of irrelevant changes and looks that it was somehow messed with your other PR for credential signing #48528 . If I understand correctly, only relevant change is in the class OID4VCIssuerEndpoint (besides changes in the testsuite). Am I correct?
Moreover, I think that not removing credential offer does not solve the issue entirely. Maybe it works for the scenario from the conformance testsuite, but may fail for some other cases like:
- Credential offer timeout is shorter than access token timeout. For example when credential offer timeout is 1 minute, access token timeout is 5 minutes and credential-request would be sent with the access token after 2 minutes from authentication (when credential offer is expired), request would fail
- Request would also fail for the cases of refresh tokens used (see specs 14.5) . As the refresh-token (and subsequent credential-request) can happen very long time after initial authentication (possibly even weeks/months).
Right now, it looks to me that to support refresh tokens together with credential offers, we may rather refactor credential offers to not be needed at credential-request at all, but being verified (and removed) in the token-endpoint after initial issuance . The related GH issue is #50340 . This would apply for authorization_code as well as pre-authorized code and hence should solve this issue as well. FYI. The issue is planned for our current sprint of core team and hence we can hopefully address this relatively soon.
@mposolda Yes, the PR is currently polluted by changes from #48528 because this branch was based on On the actual credential-offer behavior, I agree with your point. Not removing the offer state after credential issuance only fixes the immediate repeated credential-request case while the offer state is still present. It does not fully solve cases where the offer expires before the access token, or refresh-token flows where the credential request happens much later. Your suggested direction sounds better: validate/consume the credential offer during the token endpoint flow, for both authorization_code and pre-authorized_code, and make the credential endpoint rely on the authorization details already carried by the access token rather than requiring the original credential offer state to still exist. Given that #50340 is planned for the core team, I’m fine with not pushing this partial workaround further. I can either close this PR or reduce it to a clean, minimal test/behavior discussion, depending on what you prefer. |
|
@forkimenjeckayang FYI. The issue #50340 is resolved now. There is still follow-up issue #51050 to possibly not check credential offers in credential-endpoint at all, but instead check it properly during token-endpoint. However it seems to me that your reported issue should be fine now with latest main (even without #51050 being addressed) and the mentioned conformance test might be already working with the changes from #50340 ? If it is the case, feel free to either close this PR or update it for minimal test/behaviour as you suggested (possibly behavior which mimics the conformance test). |
I can confirm this error on the conformance test doesn't still occur @mposolda. |
Summary
Problem
Conformance flow
oid4vci-1_0-issuer-happy-flow(pre-authorized code variant) failed with:No credential offer state for: <credentials_offer_id>This happened because offer state could be unavailable when follow-up accesses occurred.
Why
OID4VCI flows may require follow-up accesses after initial interactions. Persisting offer state for normal lifetime (TTL) and keeping offer fetch reusable prevents false
invalid_credential_requestfailures and aligns implementation + tests with expected behavior.see: adorsys#245 (comment)
Depends on : #48528