Articles

What Is a JWKS? JSON Web Key Sets Explained

A JWKS is a JSON document of public keys that lets any service verify JWT signatures. How JSON Web Key Sets work, the kid header, caching, and key rotation.

Chisato Chisato · · 5 min read
A set of keys on a ring against a plain background

A JSON Web Key Set (JWKS) is a JSON document that publishes a list of public keys an issuer uses to sign tokens. When an identity provider signs a JWT with its private key, any service that needs to verify that token fetches the issuer’s JWKS, picks the matching public key, and checks the signature — no shared secret required. The JWKS is how asymmetric token signing works at scale: one private key stays locked away, and the public half is handed out to everyone over a well-known URL.

Why JWKS exists

With a symmetric algorithm like HS256, the issuer and every verifier share the same secret. That works for a single application, but in a system with many services it means distributing a secret that can also mint tokens. Leak it from any one service and an attacker can forge credentials for all of them.

Asymmetric algorithms such as RS256 and ES256 fix this. The issuer signs with a private key; verifiers only need the public key, which can’t be used to create signatures. (If the distinction is fuzzy, see how digital signatures work.)

That raises a distribution question: how do dozens of services, including third-party ones, get the right public key — and learn about new keys when the old one is replaced? A JWKS endpoint is the standard answer.

What a JWKS looks like

A JWKS is a JSON object with a single keys array. Each element is a JSON Web Key (JWK) — one public key expressed as JSON fields:

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "2024-signing-key-a",
      "use": "sig",
      "alg": "RS256",
      "n": "0vx7agoebGcQSuu...",
      "e": "AQAB"
    },
    {
      "kty": "EC",
      "kid": "2024-signing-key-b",
      "use": "sig",
      "alg": "ES256",
      "crv": "P-256",
      "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
      "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
    }
  ]
}

The common fields:

  • kty — key type, such as RSA or EC (elliptic curve).
  • kid — key ID, an arbitrary string the issuer uses to label the key.
  • use — intended use; sig for signature verification, enc for encryption.
  • alg — the algorithm the key is meant for.
  • Key material — for RSA, the modulus n and exponent e; for EC, the curve crv and coordinates x and y. All values are base64url-encoded.

A JWKS for verification should only ever contain public keys. If you see fields like d, p, or q in a published set, private key material has leaked.

How verification works step by step

When a service receives a JWT, the flow looks like this:

  1. Read the header. Decode the token’s header (paste one into the JWT decoder to see it) and note the alg and kid values.
  2. Find the JWKS URL. In OpenID Connect, this comes from the issuer’s discovery document at /.well-known/openid-configuration, which includes a jwks_uri field. Many providers also serve the set at /.well-known/jwks.json.
  3. Fetch and cache the set. Download the JWKS and keep it in memory.
  4. Select the key by kid. Find the entry whose kid matches the token header.
  5. Verify. Check the signature with that key, using an algorithm your service expects — not whatever the header claims.
  6. Validate claims. Confirm iss, aud, exp, and anything else your application relies on.

Steps 5 and 6 matter as much as the key lookup. A valid signature only proves who issued the token, not that it was meant for your service or that it’s still current.

Key rotation: the main reason for the kid

Signing keys shouldn’t live forever. Rotating them limits the damage if one is compromised and is a routine requirement in most security policies. JWKS makes rotation painless because a set can hold several keys at once:

  1. Publish the new key first. Add it to the JWKS while still signing with the old key. Verifiers pick it up on their next refresh.
  2. Switch signing. After verifiers have had time to refresh, start signing new tokens with the new key and its new kid.
  3. Retire the old key. Once every token signed with the old key has expired, remove it from the set.

Because each token names its kid, verifiers always know which key to use during the overlap. Without key IDs, a verifier would have to try every key in the set.

Caching and refresh behavior

Fetching the JWKS on every request would add latency and hammer the issuer. Verifiers should cache it, typically respecting the endpoint’s HTTP caching headers or a sensible fixed lifetime.

The standard pattern pairs a cache with a refresh-on-miss rule: if a token arrives with a kid that isn’t in the cached set, refetch the JWKS once and look again. That handles rotation instantly. Rate-limit those refetches, though — otherwise an attacker can send tokens with random kid values and turn your service into a traffic amplifier against the issuer.

Common JWKS security mistakes

  • Trusting the jku or x5u header. These JWT header fields let a token point at its own key URL. If a verifier follows them, an attacker can host a JWKS containing their own key and sign anything. Configure the JWKS URL on the server side and ignore token-supplied URLs. Fetching attacker-chosen URLs can also open the door to SSRF.
  • Trusting the alg header. Pin the allowed algorithms per key. Accepting none, or letting an RSA public key be used as an HMAC secret, are classic algorithm-confusion bugs.
  • Skipping issuer checks in multi-tenant setups. If you accept tokens from several issuers, make sure each token is verified against its own issuer’s JWKS, not any key you happen to have cached.
  • Never rotating. A JWKS that has held the same key for years defeats the purpose of the format.

Where JWKS fits

JWKS is part of the JOSE family of standards alongside JWT, JWS, and JWE, and it’s central to OAuth, OIDC, and SAML-style federated login — specifically the OAuth and OIDC side. Identity providers publish a JWKS so that APIs, gateways, and client libraries can validate tokens independently. It plays a role similar to certificates in PKI, but in a lighter-weight, JSON-native form without certificate chains.

The takeaway

A JWKS is a published list of public keys, each tagged with a kid, that lets any service verify tokens signed by an issuer’s private key. Fetch it from a configured URL, cache it, refresh it when you see an unknown kid, and pin the algorithms you accept. Done that way, it gives you stateless token verification across many services and lets issuers rotate keys without breaking anyone.

Chisato Chisato · · 5 min read

What Is TOTP? How Time-Based One-Time Passwords Work

TOTP generates a new six-digit code every 30 seconds from a shared secret and the current time. How authenticator apps use it, and where it falls short.

#Security #Authentication #Cryptography
Chisato Chisato · · 4 min read

What Is a Rainbow Table? Password Attacks Explained

A rainbow table is a precomputed lookup of hash chains that speeds up cracking unsalted password hashes. How it works and why salting defeats it.

#Security #Cryptography #Authentication
The Lycoris Team The Lycoris Team · · 5 min read

How Digital Signatures Work

A digital signature uses a private key to prove a message's origin and integrity, and a public key lets anyone verify it — no shared secret required.

#Security #Cryptography #Authentication