Skip to content

fix(auth): handle Azure AD v1 tokens in OAuth claim validation#4159

Open
ecthelion77 wants to merge 1 commit intoIBM:mainfrom
forterro:fix/oauth-token-validation-entra-v1-upstream
Open

fix(auth): handle Azure AD v1 tokens in OAuth claim validation#4159
ecthelion77 wants to merge 1 commit intoIBM:mainfrom
forterro:fix/oauth-token-validation-entra-v1-upstream

Conversation

@ecthelion77
Copy link
Copy Markdown
Contributor

🐛 Bug-fix PR

🔗 Issue

Closes #4158

📌 Summary

The token claim validation introduced in #3941 produces false-positive blocking errors for Azure AD tokens, preventing valid OAuth gateways from fetching tools. Three issues are fixed:

  1. Audience: Azure AD v1 tokens use client_id (GUID) as audience when scopes use {client_id}/.default. The validator now accepts client_id and api://{client_id} as valid audiences alongside the configured resource.

  2. Issuer: Azure AD v1 tokens use iss=https://sts.windows.net/{tenant}/ while v2 uses https://login.microsoftonline.com/{tenant}/v2.0. Same tenant, different URL. The validator now detects Entra v1/v2 duality and accepts both when the tenant ID matches.

  3. Scopes: OIDC meta-scopes (openid, offline_access, profile, email) and Azure AD /.default scopes are request-time directives that never appear in the access token scp claim. The validator now skips them from the missing-scope check.

🔁 Reproduction Steps

  1. Configure a gateway with Azure AD OAuth (authorization_code grant)
  2. Set scopes to ["{client_id}/.default", "openid", "offline_access"]
  3. Complete OAuth flow → "Fetch Tools" → blocked with audience/issuer/scope errors

🐞 Root Cause

_validate_audience() did not consider client_id as a valid audience.
_validate_issuer() did not handle Azure AD v1/v2 issuer URL duality.
_validate_scopes() treated OIDC meta-scopes and /.default as required token claims.

💡 Fix Description

  • _validate_audience(): build a set of acceptable audiences including client_id and api://{client_id}
  • _validate_issuer(): extract tenant from v1 (sts.windows.net/{tenant}) and v2 (login.microsoftonline.com/{tenant}/v2.0) URLs, accept both if tenant matches
  • _validate_scopes(): skip openid, offline_access, profile, email, and any scope ending with /.default

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 80 % make coverage
Manual regression Azure AD gateway fetch tools works

📐 MCP Compliance

  • No breaking change to MCP clients
  • No change to MCP protocol handling

✅ Checklist

  • DCO sign-off present
  • Single file changed (token_validation_service.py)
  • Backward compatible — only relaxes false-positive blocking, does not weaken legitimate validation

@ecthelion77
Copy link
Copy Markdown
Contributor Author

Suggested labels: bug, SHOULD, python, security

@ecthelion77 ecthelion77 force-pushed the fix/oauth-token-validation-entra-v1-upstream branch from 466d542 to c6137c4 Compare April 14, 2026 07:23
@ecthelion77 ecthelion77 force-pushed the fix/oauth-token-validation-entra-v1-upstream branch 4 times, most recently from db09914 to 6b22ba2 Compare April 14, 2026 15:34
…idation

Signed-off-by: Olivier Gintrand <olivier.gintrand@forterro.com>
@ecthelion77 ecthelion77 force-pushed the fix/oauth-token-validation-entra-v1-upstream branch from 6b22ba2 to de02c9e Compare April 14, 2026 15:45
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.

[BUG][AUTH]: OAuth token claim validation blocks valid Azure AD v1 tokens — audience, issuer, and scope false positives

1 participant