Skip to content

id_token iss claim doesn't match AS metadata issuer (Clerk/better-auth integration) #101

@arjunkmrm

Description

@arjunkmrm

Summary

Strict OAuth clients (anything using oauth4webapi, or following RFC 8414 §3) fail token exchange against https://mcp.onkernel.com/mcp with:

Failed to process authorization code response: unexpected JWT "iss" (issuer) claim value

DCR succeeds. The user signs in. /callback fires. /token returns 200 with a body. The client rejects on the id_token's iss claim.

Root cause: your AS metadata advertises one issuer; the id_token returned by /token is Clerk-signed with a different one.

curl -s https://mcp.onkernel.com/.well-known/oauth-authorization-server/mcp | jq '.issuer, .jwks_uri'
# "https://mcp.onkernel.com"
# "https://clerk.onkernel.com/.well-known/jwks.json"

Decode the id_token from a real token-exchange response and iss is https://clerk.onkernel.com, not https://mcp.onkernel.com. RFC 8414 §3 requires the two to match; strict clients enforce.

Context

We hit this while onboarding kernel/ onto Smithery. The flow is past DCR (after working around a separate 200-vs-201 issue at /register client-side) and dies during token exchange in oauth4webapi's processAuthorizationCodeResponse. Same family from another client: jlowin/fastmcp#2453, open, no fix.

Fix options

Option Where it lives Tradeoff
1. Clerk JWT template that mints session tokens with iss=https://mcp.onkernel.com, used when minting through your /token route Clerk dashboard + src/app/token/route.ts Self-contained, no re-signing. Doesn't change AS identity.
2. Re-sign the id_token in src/app/token/route.ts with iss=https://mcp.onkernel.com before returning src/app/token/route.ts Full control over claims. Need a signing key, JWKs endpoint you own, and to update jwks_uri in your AS metadata.
3. Change AS metadata issuer to https://clerk.onkernel.com so it matches what's in the token src/app/.well-known/oauth-authorization-server/route.ts Works. Couples your AS identity to Clerk's domain.

1 or 2.

Reproduction

  1. Hit https://mcp.onkernel.com/register and walk a real OAuth flow.
  2. Capture the token response body.
  3. echo "$id_token" | cut -d. -f2 | base64 -d | jq .iss
  4. Compare to .issuer from https://mcp.onkernel.com/.well-known/oauth-authorization-server/mcp.

They differ today. Either fix above aligns them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions