kid (Key ID) Header Parameter in a JWT
kid is a hint naming which key was used to sign the token. It makes key rotation possible without downtime, and it is the header parameter most often used unsafely as an index into something.
At a glance
- Parameter
- kid (Key ID)
- Defined in
- RFC 7515 section 4.1.4
- Value type
- String, case sensitive, opaque to everyone but the issuer
- Required
- Optional, but effectively required once an issuer publishes more than one key.
- Sample value
- 2024-06-key
- In the decoder
- Shown in the header JSON. The tool does not resolve it against any key set: you paste the secret or the PEM public key yourself.
In detail
Rotation is why it exists. An issuer publishes the new public key alongside the old one, starts signing with the new key, and keeps the old one published until every token signed with it has expired. Verifiers pick the right entry by matching kid against the key set they fetched, so nothing breaks in the window where both keys are live. Without kid the verifier has to try each key in turn, which works but tells you nothing when it fails.
The value is opaque and issuers choose their own convention: a date, a random string, a thumbprint of the key. What matters is that it identifies an entry in a set the verifier already has, and that a kid the verifier does not recognize means fetch the key set again, once, with a rate limit. Refetching on every unknown kid turns a stream of forged tokens into a stream of requests to the issuer.
The unsafe pattern is treating kid as anything other than a lookup key. It has been used as a filename to read, as a fragment of a SQL query, and as a command argument, and each of those turns an attacker controlled string into path traversal, injection or worse. It arrives from outside, before verification, so it deserves the same handling as any other untrusted input: match it against known values and never let it name a resource.
The decoder shows kid in the decoded header and stops there. It does not fetch a key set, resolve the identifier or use it to select anything, because verification here is done with material you paste in. That makes it a safe place to read a header from an unfamiliar token: nothing in that header causes a request to anywhere, and nothing is uploaded.
Examples
// Header of a token signed with the new key
{ "alg": "RS256", "typ": "JWT", "kid": "2024-06-key" }
// Published key set, abbreviated
{ "keys": [
{ "kty": "RSA", "kid": "2023-11-key", "use": "sig", "alg": "RS256", "n": "...", "e": "AQAB" },
{ "kty": "RSA", "kid": "2024-06-key", "use": "sig", "alg": "RS256", "n": "...", "e": "AQAB" }
] }Things that catch people out
- Using kid to build a file path or a query. It is attacker controlled text read before verification, so it belongs in a lookup and nowhere else.
- Refetching the key set every time an unknown kid appears. That is a denial of service lever pointed at your own issuer; cache and rate limit.
- Retiring the old key the moment signing switches over. Tokens signed with it are still valid until they expire, so keep it published until then.
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.
jwk (JSON Web Key) Header Parameter in a JWT
The jwk header embeds the public key in the token itself. Why trusting it verifies nothing, where it is legitimate, and how the decoder treats it.
alg (Algorithm) Header Parameter in a JWT
The alg header names the algorithm used to sign a JWT. Why the accepted algorithms belong in configuration, and what the decoder does with the value.
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