Skip to content

OIDC auth rejects Entra ID (Azure AD) tokens: username claims and top-level app roles unsupported #6630

Description

@larrysingleton007

Expected Behavior

Feature-server OIDC auth (auth: type: oidc) authenticates tokens issued by Microsoft Entra ID (Azure AD), including client-credentials (app-only) tokens, and RoleBasedPolicy matches Entra app roles.

Current Behavior

Two independent Keycloak-shape assumptions in sdk/python/feast/permissions/auth/oidc_token_parser.py (unchanged 0.64.0 -> 0.65.0):

  1. _extract_username_or_raise_error requires preferred_username or upn. Entra client-credentials tokens carry neither, so every machine-to-machine caller fails with AuthenticationError("Missing preferred_username or upn field in access token.").
  2. Roles are extracted only from Keycloak's nested resource_access.<client_id>.roles. Entra emits app roles in the top-level roles claim, so roles are always [] and RoleBasedPolicy can never match.

#4934 previously requested the roles half and was closed stale without a fix.

Steps to reproduce

  1. Configure the feature server with auth: type: oidc against an Entra ID tenant.
  2. Acquire a client-credentials token for an app registration granted an app role.
  3. Call any authenticated endpoint: the token is rejected at username extraction. With a user (auth-code) token, authentication passes but extracted roles are [].

Specifications

  • Version: 0.64.0 (parser identical in 0.65.0)
  • Platform: Python feature server, Microsoft Entra ID (Azure AD)
  • Subsystem: permissions/auth

Possible Solution

  • Username: when the human claims are absent, fall back to the calling application's identity: azp (v2 tokens), then appid (v1), then sub.
  • Roles: merge the top-level roles claim with the existing resource_access extraction so both issuer shapes authorize.

I'm taking this one: we already run 0.64 behind Entra with exactly this change applied as a build-time patch, and I'll submit it as a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions