Skip to content

fix(sdk,mcp,fastmcp): preserve issuer identity, serve PRM verbatim, raise mcp floor past PYSEC-2026-3483 - #23

Open
RobertoIskandarani wants to merge 1 commit into
mainfrom
fix/issuer-identity-prm-verbatim
Open

fix(sdk,mcp,fastmcp): preserve issuer identity, serve PRM verbatim, raise mcp floor past PYSEC-2026-3483#23
RobertoIskandarani wants to merge 1 commit into
mainfrom
fix/issuer-identity-prm-verbatim

Conversation

@RobertoIskandarani

Copy link
Copy Markdown
Contributor

What

Three related identifier-handling and dependency fixes, plus CI hardening:

  1. Issuer identity is preserved byte-for-byte (RFC 9068 iss, RFC 8414 §3.3). The configured issuer is no longer trailing-slash-stripped before storage, and the AS-metadata issuer comparison no longer strips either side. An issuer carrying a query or fragment component (RFC 8414 §2 forbids both) is rejected at AuthplaneClient.create() with a clear ValueError instead of being silently stripped. .well-known URL derivation still drops the terminating slash — that is derivation (RFC 8414/9728 §3.1), not identity. build_prm_url now preserves the resource's query component and rejects fragment-bearing resources (RFC 8707 §2).
  2. The served PRM advertises identifiers verbatim (RFC 9728 §3.3). The adapters serve PRM through upstream MCP's pydantic.AnyHttpUrl fields, which normalise an empty-path authority to a trailing-slash form; clients following the advertised value literally were then rejected by the strict §3.3 comparison. The served document is rewritten so authorization_servers and resource match the configured strings exactly.
  3. Security — mcp floor raised to >=1.28.1,<2 (from >=1.23.0,<1.28.0), clearing PYSEC-2026-3483 (affects mcp <=1.28.0). authplane-fastmcp declares the same direct floor since it imports mcp directly. The adapter resolves the URL-elicitation id field from the model's own schema instead of hard-coding the camelCase spelling.
  4. CI: the conformance catalog is pinned to a fixed revision, single-sourced in .conformance-catalog-ref (40-hex guarded), with a scheduled drift workflow against the catalog tip; ruff is pinned to >=0.16,<0.17.

Breaking (pre-1.0 → next minor)

  • authplane-mcp: supported mcp range is now >=1.28.1,<2. Migration: upgrade mcp to at least 1.28.1; mcp 2.0 is not yet supported.
  • Issuers/resources that relied on silent trailing-slash reconciliation or carried query/fragment components must correct their configuration — see the CHANGELOG Migration notes.

Verification

  • ruff check + format clean (pinned and latest resolve identically today).
  • pyright strict: 0 errors.
  • Full suites: 647 passed +1 xfail (root), 67 (mcp), 66 (fastmcp), Python 3.11–3.13.
  • Conformance vs the pinned catalog: 104 passed, 1 intentional xfail.
  • Manual E2E against a live authserver (develop): PRM served verbatim, RFC 9728 challenge, authenticated MCP initialize + tools/call, 401 on garbage tokens.

@RobertoIskandarani
RobertoIskandarani requested a review from a team as a code owner August 5, 2026 11:43
Comment thread authplane-fastmcp/tests/test_url_elicitation.py Fixed
Comment thread authplane-mcp/tests/test_url_elicitation.py Fixed
Comment thread authplane-mcp/authplane_mcp/url_elicitation.py Fixed
Comment thread authplane-fastmcp/authplane_fastmcp/url_elicitation.py Fixed
…aise mcp floor past PYSEC-2026-3483

- authplane-sdk: issuer identifiers are stored and compared byte-for-byte
  (RFC 9068 iss, RFC 8414 §3.3) — no trailing-slash stripping on storage
  or comparison; query- or fragment-bearing issuers are rejected at
  AuthplaneClient.create() (RFC 8414 §2). Well-known derivation still
  strips the terminating slash (RFC 8414/9728 §3.1); build_prm_url keeps
  the resource query and rejects fragment-bearing resources (RFC 8707 §2).
- authplane-mcp, authplane-fastmcp: the served Protected Resource
  Metadata advertises the configured issuer and resource byte-for-byte
  instead of the AnyHttpUrl-normalised form (RFC 8414/9728 §3.3).
- authplane-mcp: mcp floor raised to >=1.28.1,<2 (PYSEC-2026-3483);
  the elicitation-id field name is resolved from the model schema instead
  of being hard-coded. authplane-fastmcp declares the same direct floor.
- ci: single-source the conformance catalog pin in
  .conformance-catalog-ref (40-hex guarded) and add a scheduled drift
  check; pin ruff to >=0.16,<0.17 so formatting stays stable.
@RobertoIskandarani
RobertoIskandarani force-pushed the fix/issuer-identity-prm-verbatim branch from dc419e7 to 74c48e9 Compare August 5, 2026 11:49

@muralx muralx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewing

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.

2 participants