{"record":{"id":"ceff000d53514a4b","repo":"PrefectHQ/fastmcp","slug":"unsupported-jwk-key-type-key-type-r","errorCode":null,"errorMessage":"Unsupported JWK key type: {key_type!r}","messagePattern":"Unsupported JWK key type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/cimd.py","lineNumber":54,"sourceCode":"    SSRFFetchError,\n    ssrf_safe_fetch_response,\n    validate_url,\n)\nfrom fastmcp.utilities.logging import get_logger\n\nif TYPE_CHECKING:\n    from fastmcp.server.auth.providers.jwt import JWTVerifier\n\nlogger = get_logger(__name__)\n\n\ndef _jwk_to_pem(key_data: dict[str, Any]) -> str:\n    key_type = key_data.get(\"kty\")\n    if key_type == \"RSA\":\n        return jwk.import_key(key_data, \"RSA\").as_pem().decode(\"utf-8\")\n    if key_type == \"EC\":\n        return jwk.import_key(key_data, \"EC\").as_pem().decode(\"utf-8\")\n    raise ValueError(f\"Unsupported JWK key type: {key_type!r}\")\n\n\nclass CIMDDocument(BaseModel):\n    \"\"\"CIMD document per draft-parecki-oauth-client-id-metadata-document.\n\n    The client metadata document is a JSON document containing OAuth client\n    metadata. The client_id property MUST match the URL where this document\n    is hosted.\n\n    Key constraint: token_endpoint_auth_method MUST NOT use shared secrets\n    (client_secret_post, client_secret_basic, client_secret_jwt).\n\n    redirect_uris is required and must contain at least one entry.\n    \"\"\"\n\n    client_id: AnyHttpUrl = Field(\n        ...,\n        description=\"Must match the URL where this document is hosted\",","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/cimd.py#L36-L72","documentation":"A ValueError from _jwk_to_pem (fastmcp_slim/fastmcp/server/auth/cimd.py:48) when converting a JWK from a CIMD document's jwks into PEM for JWT signature verification and the key's 'kty' is neither 'RSA' nor 'EC'. Only RSA and EC asymmetric keys are supported; oct (symmetric) and OKP (Ed25519) keys are rejected.","triggerScenarios":"A CIMD document's jwks contains a key with kty='oct', kty='OKP', a missing kty field, or a misspelled value (e.g. lowercase 'rsa'); _extract_public_key_from_jwks selects that key while validating a private_key_jwt assertion.","commonSituations":"Clients publishing symmetric keys in their CIMD jwks (invalid for this flow); Ed25519 (OKP) signing keys not yet supported by this implementation; hand-written jwks JSON with a typo or a missing kty field.","solutions":["Publish an RSA or EC key in the CIMD document's jwks (kty exactly 'RSA' or 'EC', uppercase).","Replace OKP/Ed25519 keys with ES256 (EC P-256) or RS256 (RSA) signing keys in the client.","Check every jwks entry for a present, correctly-cased kty value.","If you control the client, generate a new supported key pair and update the hosted CIMD document."],"exampleFix":"// before\n{\"kty\": \"OKP\", \"crv\": \"Ed25519\", \"x\": \"...\"}\n// after\n{\"kty\": \"EC\", \"crv\": \"P-256\", \"x\": \"...\", \"y\": \"...\"}","handlingStrategy":"validation","validationCode":"SUPPORTED_KTY = {'RSA', 'EC'}\nkeys = cimd_doc.get('jwks', {}).get('keys', [])\nfor k in keys:\n    if k.get('kty') not in SUPPORTED_KTY:\n        raise ValueError(f\"CIMD jwks key kty={k.get('kty')!r} unsupported; publish RSA or EC\")","typeGuard":"def is_supported_jwk(key: dict) -> bool:\n    return key.get('kty') in ('RSA', 'EC')","tryCatchPattern":"try:\n    client = await cimd_manager.get_client(client_id)\nexcept ValueError as e:\n    logger.error('CIMD key issue: %s', e)\n    raise HTTPException(401, 'invalid_client') from e","preventionTips":["Publish only RSA or EC keys (uppercase 'RSA'/'EC') in CIMD jwks documents.","Avoid OKP (Ed25519) and oct keys for private_key_jwt client authentication.","Validate the jwks JSON with a script before hosting the CIMD document.","Never leave kty missing — every JWK requires it."],"tags":["jwk","cimd","jwt","unsupported-key-type"],"backgroundTag":"unsupported-key-type","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}