Skip to content

fix(fastmcp): accept zone_url as valid audience in AuthProvider#123

Merged
Larry-Osakwe merged 2 commits into
mainfrom
fix/fastmcp-audience-zone-url
May 20, 2026
Merged

fix(fastmcp): accept zone_url as valid audience in AuthProvider#123
Larry-Osakwe merged 2 commits into
mainfrom
fix/fastmcp-audience-zone-url

Conversation

@Larry-Osakwe
Copy link
Copy Markdown
Contributor

Problem

keycardai-fastmcp's AuthProvider sets self.audience to the MCP resource URL (e.g. https://my-server.fly.dev/mcp). But Keycard PKCE access tokens have aud = zone_url (e.g. https://abc123.keycard.cloud) — the actual MCP resource is in a separate resource claim, not in aud.

This causes token validation to always fail with invalid_token / "audience mismatch" for any MCP server using keycardai-fastmcp's AuthProvider with PKCE-issued tokens.

The older keycardai-mcp-fastmcp package works correctly because it uses AuthSettings.issuer_url for validation, which doesn't check aud against the resource URL.

Fix

Accept both aud forms by setting audience to a list:

self.audience = [f"{self.mcp_base_url}mcp", self.zone_url]

The JWTVerifier already handles list audiences by checking aud in self.audience, so a token with either aud = resource_url or aud = zone_url will pass validation.

Repro

Deploy any MCP server using keycardai-fastmcp's AuthProvider + WebIdentity, connect via Keycard PKCE, observe Bearer token rejected: audience mismatch in server logs.

🤖 Generated with Claude Code

Keycard PKCE access tokens carry aud=zone_url rather than aud=resource_url
(the MCP resource is indicated by a separate `resource` claim). The
previous implementation set audience to only the MCP resource URL, causing
token validation to fail with invalid_token for all Keycard-issued PKCE
tokens.

Fix: set audience to a list containing both the resource URL and zone_url,
so the JWTVerifier accepts either form.
The grant() decorator built auth_info with resource_client_id set to
self.client.config.client_id, which for WebIdentity is the DCR-registered
ua:<hash> identifier. This changes on every restart and cannot be
pre-registered as a Keycard application credential.

Fix: when application_credential has an identity_manager (WebIdentity),
use its stable key_id instead. This matches the identifier registered via
keycard agent api application-credentials --type public-key.
@Larry-Osakwe Larry-Osakwe merged commit dc6f77a into main May 20, 2026
5 checks passed
@Larry-Osakwe Larry-Osakwe deleted the fix/fastmcp-audience-zone-url branch May 20, 2026 13:36
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