Skip to content

feat: Role mapping support in pac4j extension#18778

Open
nozjkoitop wants to merge 9 commits into
apache:masterfrom
deep-bi:feature-role-mapping-in-pac4j
Open

feat: Role mapping support in pac4j extension#18778
nozjkoitop wants to merge 9 commits into
apache:masterfrom
deep-bi:feature-role-mapping-in-pac4j

Conversation

@nozjkoitop
Copy link
Copy Markdown
Contributor

Description

This PR is aimed to enable flexible mapping of OIDC/JWT roles to Druid roles.
By default, the pac4j OIDC authentication only maps the sub claim to a single Druid role, which is extremely inconvenient.
This PR adds support for extracting roles from any nested claim path in the JWT.

Configuration

New property introduced in runtime.properties:

# Dot-separated path to the claim containing user roles
druid.auth.pac4j.oidc.roleClaimPath=resource_access.client.roles

When set, all values found at roleClaimPath are mapped 1:1 to Druid roles.

  • Path format: a.b.c for nested JSON fields
  • Claim may contain a single value or be multivalued
  • If not set, behavior remains unchanged (maps sub to a single Druid role)

Example JWT payload

{
  "iss": "https://idp.example.com/",
  "sub": "user123",
  "...": "...",
  "resource_access": {
    "client": {
      "roles": ["role1", "role2"]
    }
  },
  "...": "..."
}

With the configuration:

druid.auth.pac4j.oidc.roleClaimPath=resource_access.client.roles

The authenticated user will be assigned Druid roles role1 and role2, if those roles exist in the Druid security configuration.

Release note

Added support for extracting OIDC/JWT roles from a configurable nested claim path and mapping them directly to Druid roles.


Key changed/added classes in this PR
  • RoleBasedAuthGen
  • Pac4jFilter
  • RoleProviderUtil
  • LDAPRoleProvider
  • MetadataStoreRoleProvider

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added or updated version, license, or notice information in licenses.yaml
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • added integration tests.
  • been tested in a test Druid cluster.

@nozjkoitop nozjkoitop changed the title Feature role mapping in pac4j Role mapping in pac4j Nov 25, 2025
@nozjkoitop nozjkoitop changed the title Role mapping in pac4j Role mapping support in pac4j extension Nov 25, 2025
@AdheipSingh
Copy link
Copy Markdown
Member

AdheipSingh commented Dec 1, 2025

cc @pjain1 @capistrant can you help in reviewing this.

@AdheipSingh
Copy link
Copy Markdown
Member

As per our discussion on druid slack , i'm tagging @kfaraz for review.
Thanks for the coordination.

@kfaraz kfaraz self-requested a review December 18, 2025 15:39
@kfaraz
Copy link
Copy Markdown
Contributor

kfaraz commented Dec 18, 2025

Thanks, @AdheipSingh ! I will try to prioritize the review of this PR soon.

@nozjkoitop
Copy link
Copy Markdown
Contributor Author

Hey, @kfaraz! Quick ping on this PR is it still on your radar?

protected static Set<String> claimValuesFromCtx(Map<String, Object> ctx)
{
Object value = (ctx == null) ? null : ctx.get(RoleProviderUtil.ROLE_CLAIM_CONTEXT_KEY);
if (!(value instanceof Set)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a role claim set i.e. values is not null but we don't find expected type here then instead of returning null and thus not enforcing any role should we throw error?

Copy link
Copy Markdown
Contributor Author

@nozjkoitop nozjkoitop Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Id not throw here, cuz it's more of a misconfiguration than an exceptional case, however i can add warnings on such cases to pinpoint the issue

@nozjkoitop
Copy link
Copy Markdown
Contributor Author

Hi @kfaraz, following up on this PR, wanted to check whether you’ve had a chance to look at it

Copy link
Copy Markdown
Member

@FrankChen021 FrankChen021 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings that could not be attached inline:

  • extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/JwtAuthFilter.java:90 - [P2] roleClaimPath is ignored by the JWT authenticator. The new OIDCConfig property is documented in the shared pac4j extension configuration, which also documents the jwt authenticator mode, but JwtAuthFilter still creates AuthenticationResult with a null context after validating the ID token. For deployments using druid.auth.authenticator.jwt.type=jwt, configuring roleClaimPath has no effect and authorization falls back to identity-based roles. Extract the configured claim from the validated IDTokenClaimsSet and pass it under the same role context key, or document that the JWT authenticator is unsupported.

return Optional.of(profile);
}

final AccessToken accessToken = ((OidcProfile) profile).getAccessToken();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] OIDC role extraction ignores validated ID-token claims

RoleBasedAuthGen reads only OidcProfile.getAccessToken() and parses that token for the configured role claim. If the role claim is in the validated ID token/profile claims, or the provider issues opaque access tokens, this silently extracts no roles and Druid falls back to identity-based roles. Use the already validated OIDC profile or ID-token claims, or support both token sources with tests for ID-token-only roles.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed. Docs updated, ID token claim retrieval added

@nozjkoitop nozjkoitop changed the title Role mapping support in pac4j extension feat: Role mapping support in pac4j extension May 20, 2026
@nozjkoitop
Copy link
Copy Markdown
Contributor Author

nozjkoitop commented May 20, 2026

faulty test passes locally and feels completely unrelated to changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants