Skip to content

feat: Extended OIDC support to extract groups & namespaces and token injection with multiple methods#6089

Open
aniketpalu wants to merge 24 commits intofeast-dev:masterfrom
aniketpalu:oidc-support
Open

feat: Extended OIDC support to extract groups & namespaces and token injection with multiple methods#6089
aniketpalu wants to merge 24 commits intofeast-dev:masterfrom
aniketpalu:oidc-support

Conversation

@aniketpalu
Copy link
Contributor

@aniketpalu aniketpalu commented Mar 10, 2026

What this PR does / why we need it:

Extracts groups and namespaces claims from the decoded JWT in OidcTokenParser.user_details_from_access_token() and passes them to the User object.

Previously, the OIDC token parser only read preferred_username and resource_access roles from the JWT, always returning User(username, roles) with empty groups and namespaces. This meant that GroupBasedPolicy, NamespaceBasedPolicy, and CombinedGroupNamespacePolicy could never grant access for OIDC-authenticated users — even when the JWT contained valid claims.


Server-Side Changes

Files: oidc_token_parser.py, utils.py
When auth.type: oidc, the Feast server now handles two types of incoming tokens:

  • Keycloak JWTs (from human users via UI/Swagger) — validated against Keycloak JWKS, extracts preferred_username, groups, and roles. Used by GroupBasedPolicy.
  • Kubernetes SA tokens (from workbench pods) — detected via kubernetes.io claim, delegated to existing KubernetesTokenParser which validates via TokenAccessReview and extracts namespace. Used by NamespaceBasedPolicy.
    Token type detection happens before any cryptographic validation — a lightweight unverified decode checks for the kubernetes.io claim. If the K8s API is unavailable (non-K8s deployment), the server falls back to Keycloak-only mode.

Client-Side Changes

Files: oidc_authentication_client_manager.py, auth_model.py, repo_config.py
OidcAuthClientManager.get_token() now supports multiple token sources with clear priority:

  • Explicit config (exclusive — only one is used): token, token_env_var, or client_secret + IDP network call
  • Bare config fallbacks (when nothing explicit is set): FEAST_OIDC_TOKEN env var, then mounted SA token file
    This means a workbench pod with just auth: {type: oidc} automatically picks up its SA token. Human users can set FEAST_OIDC_TOKEN. Existing client_credentials/ROPG flows are unchanged.

Which issue(s) this PR fixes:

#6088

Misc


Open with Devin

@aniketpalu aniketpalu requested a review from a team as a code owner March 10, 2026 12:50
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

…t, reject stray auth_discovery_url/client_id without client_secret

Signed-off-by: Aniket Paluskar <[email protected]>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

… _is_oidc_client_config helper

Signed-off-by: Aniket Paluskar <[email protected]>
Signed-off-by: Aniket Paluskar <[email protected]>
Signed-off-by: Aniket Paluskar <[email protected]>
devin-ai-integration[bot]

This comment was marked as resolved.

Signed-off-by: Aniket Paluskar <[email protected]>
@aniketpalu aniketpalu marked this pull request as draft March 11, 2026 10:54
devin-ai-integration[bot]

This comment was marked as resolved.

aniketpalu and others added 4 commits March 12, 2026 01:03
@aniketpalu aniketpalu marked this pull request as ready for review March 20, 2026 13:07
@aniketpalu aniketpalu changed the title feat: Extract groups and namespaces claims from JWT in OidcTokenParser feat: Extended OIDC support to extract groups & namespaces and token injection with multiple methods Mar 20, 2026
@khmelevskiy
Copy link

Thanks a lot for this 🙌

We’re currently using a bit of a temporary hack by overriding oidc_token_parser, so really looking forward to this landing in a release and finally getting rid of it 🙂

Really appreciate the work here! 💜

@botriki
Copy link

botriki commented Mar 21, 2026

Thank you for this work.

Could you add an override for the "current_user" parameter? Our OIDC server uses the UPN instead of preferred_username and I'm currently working on a monkey patch solution for this. But it would be much more convenient to have this in the official release.

      if "upn" in data:
          current_user = data["upn"]
      elif "preferred_username" in data:
          current_user = data["preferred_username"]
      else:
          raise AuthenticationError(
              "Missing upn or preferred_username field in access token."
          )

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

Successfully merging this pull request may close these issues.

3 participants