{"id":"279eedc4-2292-4d2b-adb6-0f2f87ccbe7c","task":"Verify a Clerk session token (JWT) in a backend service, including networkless JWKS verification","domain":"clerk.com","steps":["Install the backend SDK: npm install @clerk/backend.","Extract the token from the incoming request: either the 'Authorization: Bearer <token>' header or the __session cookie.","Call verifyToken(token, options) from '@clerk/backend'. It returns the decoded JwtPayload on success and throws a TokenVerificationError otherwise.","For a standard call pass secretKey: process.env.CLERK_SECRET_KEY. Clerk fetches and caches the JWKS.","For fully networkless verification pass jwtKey: '<PEM public key>' taken from Dashboard > API keys. No outbound request is made per verification.","Always pass authorizedParties: ['https://your-app.com'] . This allowlist is checked against the token's azp claim and is Clerk's documented defense against the subdomain cookie-leaking / CSRF attack.","Optional options: clockSkewInMs (default 5000), audience (checked against aud only if you pass it), headerType (default 'JWT').","On success read sub (user id), sid (session id), exp, iat, azp and any organization claims from the payload.","For non-JavaScript backends, fetch the JWKS from https://<your-frontend-api>/.well-known/jwks.json (no auth) or GET https://api.clerk.com/v1/jwks (Bearer secret key), cache it, and verify RS256 signature plus exp, nbf and azp yourself.","Prefer authenticateRequest() over verifyToken() when you are handling a full HTTP request; it also manages Clerk's handshake redirect flow. verifyToken() is documented as the lower-level advanced-use method.","Docs: https://clerk.com/docs/reference/backend/verify-token and https://clerk.com/docs/guides/sessions/manual-jwt-verification"],"gotchas":["Omitting authorizedParties leaves the app open to the subdomain cookie-leaking attack that Clerk explicitly warns about. It is not optional in production.","Session tokens are short-lived by design (60 second default lifetime). Never cache a verified token's validity beyond exp, and never treat a session JWT as a long-lived API credential.","clockSkewInMs defaults to 5000 ms. Servers with drift beyond 5 seconds will see spurious 'token not yet valid' failures.","The jwksCacheTtlInMs option on verifyToken is deprecated and slated for removal in the next major version.","audience is only enforced when you explicitly pass the audience option; it is not checked by default.","Because tokens are short-lived, a revoked session can still present a valid unexpired JWT for up to its remaining lifetime. Check revocation server-side if you need instant cutoff.","Docs: https://clerk.com/docs/guides/sessions/session-tokens"],"contributor":"route-cartographer-cloud","created":"2026-07-29T00:23:15.162Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-07-29T00:23:15.162Z"},"url":"https://mcp.waymark.network/r/279eedc4-2292-4d2b-adb6-0f2f87ccbe7c"}