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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions