feat(oauth2): populate groups claim in client_credentials tokens#4691
Open
carlesarnal wants to merge 2 commits intodexidp:masterfrom
Open
feat(oauth2): populate groups claim in client_credentials tokens#4691carlesarnal wants to merge 2 commits intodexidp:masterfrom
carlesarnal wants to merge 2 commits intodexidp:masterfrom
Conversation
01d6288 to
ac08ebb
Compare
carlesarnal
added a commit
to carlesarnal/apicurio.github.io
that referenced
this pull request
Mar 26, 2026
- Groups scope verified working on live cluster (v2.45.1) - client_credentials: works on dex:master, not in v2.45.1 - groups claim missing from client_credentials tokens (accepted but not populated) - Link to fix: dexidp/dex#4691 (adds groups field to static clients) - Verified fix on cluster: writes succeed with patched Dex - Added unsupported_grant_type troubleshooting entry
ac08ebb to
44f15e7
Compare
nabokihms
requested changes
Mar 30, 2026
Member
nabokihms
left a comment
There was a problem hiding this comment.
Overall, looks good. The only thing required is the storage code.
Add a ClientCredentialsClaims sub-struct to the Client definition,
allowing static clients to declare identity claims (starting with
groups) that are included in tokens issued via client_credentials.
This keeps the Client struct focused on application-level concerns
(ID, secret, redirect URIs) while providing a dedicated home for
identity attributes needed by RBAC-aware consumers.
Configuration example:
staticClients:
- id: my-service
secret: "..."
clientCredentialsClaims:
groups:
- admin-group
When the groups scope is requested in a client_credentials grant,
the groups from clientCredentialsClaims are included in the token.
If clientCredentialsClaims is not set, behavior is unchanged.
Fixes dexidp#4690
Signed-off-by: Carles Arnal <carlesarnal92@gmail.com>
Add the client_credentials_claims field to the ent ORM schema and update the storage client to persist and retrieve it. Also fix gci import formatting in handlers_test.go. Signed-off-by: Carles Arnal <carnalca@redhat.com> Signed-off-by: Carles Arnal <carlesarnal92@gmail.com>
5ffd90c to
83b7b4a
Compare
carlesarnal
added a commit
to Apicurio/apicurio.github.io
that referenced
this pull request
Apr 9, 2026
* Add blog post: Universal OAuth integration via Dex Covers evolving the Apicurio Registry authentication story from the OpenShift-specific direct integration to a universal approach using Dex as an OIDC bridge, enabling any OAuth provider (OpenShift, LDAP, GitHub, Azure AD, SAML) with full feature support including UI login, principal identity, and owner-based authorization. * Fix blog post: correct Dex/Registry client architecture and config Fixes 10 issues including: two-client architecture (public UI + confidential backend), CORS allowedOrigins, correct appClientId/uiClientId, UI auth scope for groups, redirectUri, ingress.host with edge TLS annotations, REGISTRY_API_URL override, /dashboard redirect URI, and expanded troubleshooting section. * Refine blog post: improve inline explanations and comments Moves key explanations (two-client architecture, UI scope, redirectUri) into inline YAML comments and a dedicated callout section after the CR, removes Group-based access row from comparison table, adds --port flag to oc route command, and cleans up redundant prose. * Add M2M access section to Dex blog post Covers machine-to-machine authentication patterns: authorization code flow with the confidential client for scripts, Dex's lack of client_credentials grant, refresh token approach for CI/CD pipelines, and the option to bypass Dex for native M2M providers. * Remove DEX-OAUTH-INTEGRATION.md from branch, update comparison table The guide file should not be part of this PR. Also adds M2M row to the feature comparison table noting Dex does not support client credentials. * Update blog: add Dex client_credentials test results and fix PR - Groups scope verified working on live cluster (v2.45.1) - client_credentials: works on dex:master, not in v2.45.1 - groups claim missing from client_credentials tokens (accepted but not populated) - Link to fix: dexidp/dex#4691 (adds groups field to static clients) - Verified fix on cluster: writes succeed with patched Dex - Added unsupported_grant_type troubleshooting entry * Update blog: use clientCredentialsClaims sub-struct per reviewer feedback
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Add a
ClientCredentialsClaimssub-struct to theClientdefinition, allowing static clients to declare identity claims (starting withgroups) that are included in tokens issued viaclient_credentials.What this PR does / why we need it
PR #4583 added
client_credentialsgrant support and listsgroupsas a supported scope. However, the scope is only accepted (not rejected) — theGroupsfield in the claims struct is never populated, so tokens never contain agroupsclaim regardless of the scope requested.This is because
client_credentialshas no upstream connector or user involved, so there is no source for group membership. This PR adds aclientCredentialsClaimssub-struct to static client definitions, keeping identity attributes separate from core Client fields (ID, secret, redirect URIs).Design decision: Per reviewer feedback, identity attributes are scoped to a dedicated
ClientCredentialsClaimsstruct rather than added as top-level fields onClient. This avoids mixing application identity with user-like identity attributes and provides a clean extension point for future claims (email, custom attributes) without each addition leaking into the client definition.Changes:
storage/storage.go— AddedClientCredentialsClaimsstruct withGroupsfield, and an optionalClientCredentialsClaimspointer onClientserver/handlers.go— InhandleClientCredentialsGrant, populateclaims.Groupsfromclient.ClientCredentialsClaims.Groupswhen thegroupsscope is requestedserver/handlers_test.go— Added two test cases:clientCredentialsClaims.groups+groupsscope → groups appear in tokenclientCredentialsClaims+groupsscope → no groups in token (no regression)Configuration example:
Why this matters:
Applications that use the
groupsclaim for RBAC — such as Apicurio Registry — cannot authorizeclient_credentialstokens for write operations without groups. The Apicurio Kafka SerDes libraries only supportclient_credentials(they hardcodegrant_type=client_credentials), so this is a blocking issue for Kafka schema registry use cases.Testing:
go test ./server/... -run TestHandleClientCredentials— all 10 cases pass (8 existing + 2 new)client_credentialstokens now includegroupsand Apicurio Registry successfully resolves RBAC roles — write operations return 200 instead of 403Fixes #4690