Custom OIDC provider (ES256) rejected with "Could not verify OIDC token claim"
🪲Bug Report
Setup: Custom OIDC provider (not Clerk/Auth0). JWTs are signed with ECDSA P-256 / ES256 using an AWS KMS key. The OIDC discovery doc and JWKS are served from our domain. auth.config.ts: ts{ domain: "https://XYZ", applicationID: "XYZ" } JWT claims (decoded): json{ "alg": "ES256", "kid": "a8e9b72e-e469-42e6-882a-ed0968e6727e" } { "sub": "<uuid>", "iss": "https://XYZ", "aud": "XYZ", "iat": 1745..., "exp": 1745...+900 } OIDC discovery (https://XYZ/.well-known/openid-configuration) — HTTP 200, correct JSON, id_token_signing_alg_values_supported: ["ES256"] JWKS (https://XYZ/.well-known/jwks.json) — HTTP 200, contains correct EC P-256 public key with matching kid
Diagnostics I ran inside a Convex action to isolate the failure: ts// verifyBridgeToken action — runs inside Convex's V8 isolate const cryptoKey = await crypto.subtle.importKey( 'jwk', jwk, // key fetched from our JWKS { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'], ) const valid = await crypto.subtle.verify( { name: 'ECDSA', hash: 'SHA-256' }, cryptoKey, sigBytes, signingInput, ) Result: { importKey: "ok", signatureValid: true, isExpired: false } The signature verifies correctly using the same crypto.subtle that Convex's own auth middleware would use, in the same V8 runtime. The token is not expired. The iss, aud, and kid all match. Yet Convex's auth still returns "Could not verify OIDC token claim". Both OIDC endpoints are reachable from within a Convex action — confirmed with fetch() calls returning HTTP 200.
Question: Is there a known issue with ES256/EC key verification in Convex's auth middleware? All documented examples of custom OIDC providers I've found use RSA (RS256). Is ES256 actually supported end-to-end, or only in theory? Any internal logs that would show which claim check is failing would be hugely helpful — the client-side error message doesn't distinguish between signature failure, claim mismatch, or key-fetch failure.