PR #50342: oid4vci-feat: Add provider ID detail to refresh token events and impl…#50705
Conversation
There was a problem hiding this comment.
Pull request overview
This PR standardizes emitting the refresh token provider identifier (refresh_token_provider_id) into Keycloak events, enabling downstream consumers to distinguish refresh-token ownership (e.g., OID4VCI vs default) without introducing new refresh token types.
Changes:
- Adds
Details.REFRESH_TOKEN_PROVIDER_IDand emits it during initial issuance (code-to-token), refresh, and revocation flows. - Extends the refresh token provider SPI with a default
getProviderId()and overrides it for OID4VCI. - Adds an integration test validating the emitted provider ID for both OID4VCI and default refresh tokens.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/base/src/test/java/org/keycloak/tests/oid4vc/OID4VCRefreshTokenProviderEventTest.java | Adds integration coverage for refresh_token_provider_id on REFRESH_TOKEN, REVOKE_GRANT, and CODE_TO_TOKEN events. |
| services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java | Emits refresh_token_provider_id detail during initial refresh token issuance. |
| services/src/main/java/org/keycloak/protocol/oidc/refresh/RefreshTokenProvider.java | Adds SPI default method getProviderId() for consistent provider identification. |
| services/src/main/java/org/keycloak/protocol/oidc/refresh/AbstractRefreshTokenProvider.java | Emits refresh_token_provider_id detail during refresh-token grant processing. |
| services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java | Emits refresh_token_provider_id detail during refresh token revocation. |
| services/src/main/java/org/keycloak/protocol/oid4vc/refresh/OID4VCIRefreshTokenProvider.java | Overrides getProviderId() to return the OID4VCI provider ID. |
| server-spi-private/src/main/java/org/keycloak/events/Details.java | Introduces the REFRESH_TOKEN_PROVIDER_ID event detail constant. |
4662cf0 to
aa54459
Compare
2ea1f29 to
55629a9
Compare
55629a9 to
859ee49
Compare
859ee49 to
9136905
Compare
9136905 to
5dc9474
Compare
5dc9474 to
9eab14d
Compare
| String providerIdDetail = oldRefreshToken.getProvider() != null ? oldRefreshToken.getProvider() : getProviderId(); | ||
| event.detail(Details.REFRESH_TOKEN_PROVIDER_ID, providerIdDetail); |
| String providerId = refreshToken.getProvider() != null ? refreshToken.getProvider() : refreshTokenProvider.getProviderId(); | ||
| event.detail(Details.REFRESH_TOKEN_PROVIDER_ID, providerId); |
| String refreshToken = tokenResponse.getRefreshToken(); | ||
| oauth.doTokenRevoke(refreshToken); | ||
|
|
||
| EventAssertion.assertSuccess(events.poll()) | ||
| .type(EventType.REVOKE_GRANT) | ||
| .details(Details.REFRESH_TOKEN_PROVIDER_ID, | ||
| OID4VCIRefreshTokenProviderFactory.PROVIDER_ID); |
graziang
left a comment
There was a problem hiding this comment.
@jimmychakkalakal thanks! The decision to keep the prov claim rather than a custom token type seems seems reasonable.
lhanusov
left a comment
There was a problem hiding this comment.
@jimmychakkalakal Hi Jimmy, please, take a look and let me know what you think about my comments. If it makes sense, please address.
3aa5ef1 to
438dd63
Compare
| String providerId = refreshToken.getProvider() != null ? refreshToken.getProvider() : refreshTokenProvider.getProviderId(); | ||
| event.detail(Details.REFRESH_TOKEN_PROVIDER_ID, providerId); |
|
@lhanusov Thanks for the comments. I have changed the implementation. Please review, when you have time |
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.cluster.RealmInvalidationClusterTest#crudWithoutFailoverorg.keycloak.testsuite.cluster.RealmInvalidationClusterTest#crudWithFailover |
…ement provider ID retrieval Closes keycloak#50342 Signed-off-by: Jimmy Chakkalakal <jimmy.chakkalakal@ibm.com>
…ement provider ID retrieval Closes keycloak#50342 Signed-off-by: Jimmy Chakkalakal <jimmy.chakkalakal@ibm.com>
Closes keycloak#50342 Signed-off-by: Jimmy Chakkalakal <jimmy.chakkalakal@ibm.com>
438dd63 to
bad26c9
Compare
Decision: Use prov field instead of custom token type
After analysis, I've retained the prov field on RefreshToken rather than introducing a new type like "Refresh-oid4vci".
Rationale:
Implementation:
Closes #50342