jwk (JSON Web Key) Header Parameter in a JWT
jwk carries the public key inside the token's own header. A verifier that uses it is checking the token against a key the sender supplied, which proves the sender signed it and nothing else at all.
At a glance
- Parameter
- jwk (JSON Web Key)
- Defined in
- RFC 7515 section 4.1.3
- Value type
- JSON Web Key object, as defined in RFC 7517, holding a public key
- Required
- Optional. Legitimate only where the key is separately bound or thumbprinted.
- Legitimate use
- DPoP proofs in RFC 9449, where the key is bound to an access token through its cnf claim
- In the decoder
- Displayed as JSON in the header. The tool never adopts it as the verification key.
In detail
The failure is a circular one. If the verifier takes the key from the token and uses it to check the token's signature, then anyone can generate a key pair, sign whatever claims they like, embed the matching public key, and pass. The signature is genuine and completely meaningless, because it proves only that whoever wrote the claims also owns a key they made a moment earlier.
Real libraries have shipped this behaviour, honouring an embedded key by default because RFC 7515 defines the parameter and the code path looked like completeness. The lesson is not that jwk is broken but that a key has to come from somewhere the verifier already trusts, and a field inside the document being verified is by definition not such a place.
There is a correct use, and it looks different. In DPoP the client sends a proof token carrying its public key in jwk, and the resource server checks that the thumbprint of that key matches the jkt value inside the cnf claim of the access token, which was signed by the authorization server. The embedded key is accepted because a trusted party committed to it in advance, not because it was present.
The decoder shows a jwk header as decoded JSON so you can read the key type, curve or modulus and the key identifier. It will not use it: verification here takes a secret or a PEM public key that you supply. That mirrors what a service should do, and it means inspecting a suspicious token cannot cause the tool to trust anything the token brought with it.
Examples
{
"alg": "ES256",
"typ": "JWT",
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
}
}Sample key material. Nothing here says who the signer is, only that they hold the matching private key.
Things that catch people out
- Leaving a library's default in place without checking whether it honours embedded keys. Some have, and it is a complete authentication bypass.
- Assuming a valid signature means a trusted signer. With jwk it means the sender owns a key pair, which anyone does.
- Copying the DPoP pattern without the binding. The embedded key is only meaningful because cnf in a separately signed token commits to its thumbprint.
Try it: JWT Decoder
Paste a token to decode the header and payload, read the claims and expiry, and verify the signature in your browser. Nothing is uploaded.
JWT Decoder
LOCAL · Browser-OnlyDecode and inspect JSON Web Tokens without sending them to a server
Related JWT claims and algorithms
All jwt claims and algorithms →jku (JWK Set URL) Header Parameter in a JWT
The jku header points at a JWK Set URL for the signing key. Why following it blindly gives an attacker both forgery and SSRF, and safe handling.
cnf (Confirmation) Claim in a JWT
The cnf claim binds a token to a key its holder must prove. How mTLS and DPoP use it, why it stops replay of a stolen token, and decoder limits.
kid (Key ID) Header Parameter in a JWT
The kid header says which key signed a token. How rotation depends on it, why the value must be a lookup and never a path, and decoder behaviour.
x5u (X.509 URL) Header Parameter in a JWT
The x5u header points at an X.509 certificate chain for the signing key. The SSRF and trust risks, and what a verifier has to validate.
x5c (X.509 Certificate Chain) Header Parameter
The x5c header embeds the X.509 certificate chain in the token. Why it uses standard Base64 rather than Base64URL, and how a verifier must treat it.
x5t (X.509 Certificate SHA-1 Thumbprint) Header
The x5t header holds a SHA-1 thumbprint of the signing certificate. How it selects a certificate, why SHA-1 here is not the usual problem, and what to prefer.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server