Skip to content

Wire SEP-990 enterprise-managed-authorization conformance fixture#3007

Open
maxisbey wants to merge 1 commit into
mainfrom
auth-conformance-ema
Open

Wire SEP-990 enterprise-managed-authorization conformance fixture#3007
maxisbey wants to merge 1 commit into
mainfrom
auth-conformance-ema

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

Adds the conformance client handler for auth/enterprise-managed-authorization and drops the last client-side waiver from expected-failures.yml.

Motivation and Context

#2988 shipped IdentityAssertionOAuthProvider and #3004 shipped docs/examples for it, but the conformance fixture was still falling through to the authorization-code default for this scenario. This was the only remaining client: entry in the baseline.

How Has This Been Tested?

Against the pinned harness (@b18aa918):

  • single scenario: 9/9 (complete-flow-token-exchange, complete-flow-jwt-bearer, valid-bearer-token, prm-pathbased-requested, authorization-server-metadata all SUCCESS)
  • full client --suite all: 421/421, 0 failed, 0 warnings, baseline check clean

Breaking Changes

None. Fixture-only change under .github/actions/conformance/; no src/ touched.

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The handler does the two pieces IdentityAssertionOAuthProvider deliberately leaves to the caller:

  1. AS issuer: the provider treats the issuer as configuration (per the SEP-990 trust model — the resource server is never asked which AS to use). The harness only exposes it via the PRM document, so the fixture fetches PRM via build_protected_resource_metadata_discovery_urls and hands authorization_servers[0] to the provider. A production deployment would supply the issuer as static configuration instead.
  2. Leg 1 (RFC 8693 token-exchange at the IdP): implemented inline as the assertion_provider callback — sends subject_token=idp_id_token, audience=<AS issuer>, resource=<MCP url> to the harness IdP token endpoint, receives the ID-JAG.

The provider then runs leg 2 (RFC 7523 jwt-bearer at the AS) with token_endpoint_auth_method="client_secret_basic" — required, the harness AS rejects on missing Authorization: Basic.

_run_auth_session's oauth_auth annotation is widened from OAuthClientProvider to httpx.Auth (the new provider is not an OAuthClientProvider subclass; all existing callers already satisfy httpx.Auth).

Part of #2891.

AI Disclaimer

Adds an auth/enterprise-managed-authorization handler to the conformance
client fixture using the IdentityAssertionOAuthProvider shipped in #2988:
performs the RFC 8693 token-exchange at the harness IdP for an ID-JAG,
then the RFC 7523 jwt-bearer grant at the harness AS via the provider.

Drops the last client-side waiver from expected-failures.yml.

Widens the _run_auth_session annotation to httpx.Auth (the new provider
is not an OAuthClientProvider subclass; all existing callers already
satisfy httpx.Auth).
@maxisbey maxisbey marked this pull request as ready for review June 26, 2026 21:46

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 3 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread .github/actions/conformance/client.py

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — CI-only conformance fixture wiring that follows the existing auth scenario handler pattern; the conformance run itself validates the change.

Extended reasoning...

Overview

This PR adds a conformance handler for the auth/enterprise-managed-authorization scenario in .github/actions/conformance/client.py and removes the now-passing waiver from both expected-failures baselines. It is entirely contained under .github/actions/conformance/ — no library (src/) code is touched.

Correctness

The new handler mirrors the existing auth/client-credentials-* handlers: read context, validate required keys, construct a provider, call _run_auth_session. I verified the IdentityAssertionOAuthProvider constructor signature (server_url, storage, client_id, client_secret, issuer, assertion_provider, token_endpoint_auth_method) and build_protected_resource_metadata_discovery_urls(None, server_url) against the code shipped in #2988 — the call sites match. Widening _run_auth_session's annotation from OAuthClientProvider to httpx.Auth is safe since all existing callers pass httpx.Auth instances and the function only hands the value to httpx.AsyncClient(auth=...).

Security risks

None for the SDK or its users: this is test-harness glue executed only in CI against the conformance mock harness. The credentials involved come from MCP_CONFORMANCE_CONTEXT set by the harness. Trusting authorization_servers[0] from the PRM document would be a questionable pattern in production, but the code comment explicitly calls this out as conformance-only behavior and the production provider requires the issuer as static configuration.

Level of scrutiny

Low. CI fixture changes are self-validating — if the handler were wrong, the conformance workflow would fail (the runner also fails on stale expected-failure entries, so the baseline removals are checked both ways). The bug-hunting pass found no issues, and there are no outstanding reviewer comments.

@maxisbey maxisbey enabled auto-merge (squash) June 26, 2026 22:32
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.

1 participant