DEV Community

Cover image for You've Never Actually Sent a JWT (JOSE, JWS, JWE, JWA and JWK Explained)
RuntimeStack
RuntimeStack

Posted on

You've Never Actually Sent a JWT (JOSE, JWS, JWE, JWA and JWK Explained)

You've used JWTs a hundred times. But here's the thing: you've probably never actually sent one.

That token in your Authorization header? Technically, it's a JWS.

JOSE, JWS, JWE, JWA, JWK, JWT. It's alphabet soup. Here's one analogy that makes all of it click.

JOSE: the shipping company

Start with JOSE: JSON Object Signing and Encryption. It's not a token. It's a family of IETF standards.

Think of it as a shipping company, with rules for how packages get sealed, locked and delivered.

JWT: the letter

A JWT isn't a container at all. It's the letter inside: a set of claims.

{
  "iss": "auth.example.com",
  "sub": "user_42",
  "aud": "orders-api",
  "exp": 1767225600
}
Enter fullscreen mode Exit fullscreen mode

Who issued it. Who it's about. Who it's for. And when it expires.

But a letter on its own isn't secure. It needs packaging.

JWS: the sealed envelope

Option one: JWS, JSON Web Signature. Picture a clear envelope with a tamper-proof wax seal.

It has three parts, separated by dots: a header that names the algorithm, the payload, and the signature.

eyJhbGciOiJ...  .  eyJzdWIiOiI...  .  SflKxwRJSMe...
    header            payload           signature
Enter fullscreen mode Exit fullscreen mode

The seal proves who sent it, and that nobody changed a single byte.

The gotcha: the envelope is clear

The payload is just Base64URL encoded. Anyone can decode it:

echo 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ==' | base64 -d   # Base64URL drops the = padding; add it back for base64
# {"sub":"1234567890","name":"John Doe","iat":1516239022}
Enter fullscreen mode Exit fullscreen mode

So never put secrets inside a signed JWT.

JWE: the locked box

Need privacy? Option two: JWE, JSON Web Encryption. This is a locked metal box, with five parts:

  1. A header
  2. An encrypted key
  3. An initialization vector
  4. The ciphertext
  5. An authentication tag

Only the recipient, holding the right key, can open it.

JWA: the toolbox

So how do you seal or lock it? That's JWA, JSON Web Algorithms. The toolbox.

  • Signing: HS256, RS256 and ES256
  • Encryption: RSA-OAEP and A256GCM

The alg field in the header tells the receiver which tool was used.

JWK and JWKS: the keys

And the keys themselves? That's JWK, JSON Web Key. Instead of PEM files, a key is just JSON: a key type (kty), what it's used for (use), a key ID called kid, and the key material.

Put several keys in an array, and you get a JWKS. Auth servers publish it at /.well-known/jwks.json.

Your API reads the kid from the token header, fetches the matching public key, and verifies the signature. That's how keys rotate without redeploying anything.

Nested JWT: both at once

And yes, you can combine them. Sign a JWT, then encrypt the result. That's a nested JWT: a sealed envelope, inside a locked box.

Recap

Analogy
JOSE the shipping company the family of standards
JWT the letter the claims
JWS the sealed envelope signed, readable by anyone
JWE the locked box encrypted, private
JWA the toolbox the algorithms
JWK the keys keys as JSON

Next time someone says JWT, you can say: well, actually... it's a JWS.

Which of these acronyms confused you the most? Tell me in the comments.


This is the written version of a 3-minute animated explainer on RuntimeStack. Sources: RFC 7519 (JWT), RFC 7515 (JWS), RFC 7516 (JWE).

Top comments (0)