Repository navigation
Conversation
Quote resource_metadata, send the challenge on every 401, add the 403 insufficient_scope challenge, and add clerkMcpAuth, which checks the token audience. Fix the Express hang on a bare Bearer header and derive the Next.js metadata resource from the route path.
Fold clerkMcpAuth into mcpAuthClerk so Express and Hono expose a single
Clerk auth middleware. mcpAuthClerk now requires { resourceUrl }; code
that still passes it to a route uncalled gets a Clerk error instead of
a hung request.
Raise the @clerk/express and @clerk/hono peer ranges to 2.1.70 and 0.1.80, the first releases where authenticateRequest rejects a token without a matching aud claim, and test against those minimums.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Express and Hono adapters now send the same
WWW-Authenticatechallenges as the Clerk MCP server guide.mcpAuthClerk({ resourceUrl, requiredScopes })also checks the token's audience, so the guide's inline auth code can be replaced with it.Why
The guide writes its own
/mcpauth middleware because the adapters can't do the job. Theirresource_metadatavalue is unquoted, which RFC 9110 doesn't allow. A rejected token gets a 401 with no challenge at all, and a token missing scopes can't get a 403.mcpAuthClerknever checks the audience, so an OAuth access token issued to any other app on the same Clerk instance is accepted. In Express, a bareAuthorization: Bearerheader hangs the request.How
Express and Hono share one response rule in an internal
bearer-auth.tsmodule, so the two can't drift apart again:Bearer resource_metadata="…"error="invalid_token"(RFC 6750 §3)requiredScopeserror="insufficient_scope", scope="…"(RFC 6750 §3.1)Values in the challenge are quoted strings (RFC 9110 Appendix A), and
resource_metadatafollows RFC 9728 §5.1.The 403
scopelists the token's granted scopes followed by the missing ones, asrequireAdditionalScopesdoes, so re-authorizing doesn't drop access the token already had. The guide lists only the required scopes; this is a deliberate superset.Breaking:
mcpAuthClerkis now a factory that requiresresourceUrland passes it toauthenticateRequestas theaudience. Code that still passes the baremcpAuthClerkto a route gets aClerk error:explaining the new call form instead of hanging.Breaking: the peer ranges now start at
@clerk/express2.1.70 and@clerk/hono0.1.80. Before those versions, a JWT without anaudclaim and an opaque token both pass the audience check. The dev dependencies are pinned to these minimums, so the tests run against the oldest versions we support.mcpAuthtakes optionalresourceUrlandrequiredScopes.resourceUrlsetsresource_metadatainstead of building it from the request, which can be wrong behind a proxy.Express
mcpAuthis now synchronous, rejects schemes other thanBearer, and leaves the query string out ofresource_metadata.In the Next.js adapter, the protected resource metadata
resourcenow includes the route path, as it already does in Express and Hono. Its challenge still comes frommcp-handler'swithMcpAuth.Follow-ups
mcpAuthClerk, test the audience check against a real Clerk instance: a token issued for another resource or OAuth application must get a 401. The tests here use a mocked Clerk client.mcpAuthClerkonce this is released.