Optional additional MCP signing algorithms (ES256 now-capable; EdDSA on demand)
Stage 4 (#94 / PR #126) ships MCP access-token signing as RS256 only — the universally-interoperable default. This tracks adding algorithm choice if a deployment ever needs it. Low priority: no spec or known MCP client requires anything beyond RS256.
ES256 — cheap, no new dependency
jsonwebtoken@9 already supports ES256/384/512 (confirmed: it's in the @types/jsonwebtoken Algorithm union and the jwa README). Adding it is a small, dependency-free change:
- Generate an EC P-256 keypair (
generateKeyPair('ec', { namedCurve: 'P-256' })) when mcp.signingAlgorithm === 'ES256'.
- Pass
algorithm: 'ES256' to jwt.sign (the issuer is otherwise unchanged).
- JWK serialization already works —
node:crypto createPublicKey(pem).export({ format: 'jwk' }) emits EC JWKs (kty: "EC", crv, x, y); generalize publicKeyToJwk beyond the current RSA-only n/e.
- Re-advertise
ES256 in id_token_signing_alg_values_supported (wellKnown.ts) conditioned on what's configured.
ES256 is the conventional "modern" upgrade (smaller keys/signatures than RSA, broad client support) and is the one to add first if asked.
EdDSA — on demand only
jsonwebtoken cannot emit EdDSA. Two options, neither blocking:
node:crypto directly — sign(null, data, ed25519PrivateKey) works (verified, 64-byte sig); the JWT (base64url(header).base64url(payload).base64url(sig)) would be assembled by hand. Zero new deps but more code.
jose — clean JOSE implementation that handles EdDSA (and everything else) without hand-rolling. A new dependency; only worth it if EdDSA is actually required (or if we choose to standardize the whole issuer on jose).
EdDSA has the weakest client/library ecosystem support of the three; implement only when a specific client needs it.
Non-breaking
Tokens carry kid and clients verify via JWKS, so a new algorithm is additive: publish a second JWK, sign new tokens with the new alg, old RS256 tokens keep verifying. No migration.
Related
🤖 Generated with Claude Code
Optional additional MCP signing algorithms (ES256 now-capable; EdDSA on demand)
Stage 4 (#94 / PR #126) ships MCP access-token signing as RS256 only — the universally-interoperable default. This tracks adding algorithm choice if a deployment ever needs it. Low priority: no spec or known MCP client requires anything beyond RS256.
ES256 — cheap, no new dependency
jsonwebtoken@9already supportsES256/384/512(confirmed: it's in the@types/jsonwebtokenAlgorithmunion and thejwaREADME). Adding it is a small, dependency-free change:generateKeyPair('ec', { namedCurve: 'P-256' })) whenmcp.signingAlgorithm === 'ES256'.algorithm: 'ES256'tojwt.sign(the issuer is otherwise unchanged).node:cryptocreatePublicKey(pem).export({ format: 'jwk' })emits EC JWKs (kty: "EC",crv,x,y); generalizepublicKeyToJwkbeyond the current RSA-onlyn/e.ES256inid_token_signing_alg_values_supported(wellKnown.ts) conditioned on what's configured.ES256 is the conventional "modern" upgrade (smaller keys/signatures than RSA, broad client support) and is the one to add first if asked.
EdDSA — on demand only
jsonwebtokencannot emit EdDSA. Two options, neither blocking:node:cryptodirectly —sign(null, data, ed25519PrivateKey)works (verified, 64-byte sig); the JWT (base64url(header).base64url(payload).base64url(sig)) would be assembled by hand. Zero new deps but more code.jose— clean JOSE implementation that handles EdDSA (and everything else) without hand-rolling. A new dependency; only worth it if EdDSA is actually required (or if we choose to standardize the whole issuer onjose).EdDSA has the weakest client/library ecosystem support of the three; implement only when a specific client needs it.
Non-breaking
Tokens carry
kidand clients verify via JWKS, so a new algorithm is additive: publish a second JWK, sign new tokens with the new alg, old RS256 tokens keep verifying. No migration.Related
🤖 Generated with Claude Code