Understanding JOSE: A Deep Dive into JSON Web Tokens and Security
Introduction
I recently worked on an OAuth DPoP implementation, which meant revisiting JOSE specifications in detail—signing tokens, validating JWKs, cryptographic operations. It reminded me how I learned about JWT: picking up bits and pieces over time, often confused about how everything connected.
Over the years in IAM teams, I’ve worked with XML-based SAML assertions, session tokens, cookies, and modern JSON-based tokens. JWT has been the most interesting and, frankly, the most confusing to learn in the begining.
Full disclosure: I’m not a cryptography expert. I don’t fully understand the math behind elliptic curves or the intricate details of RSA. But here’s what I’ve learned: you don’t need to. Some things you can take as axioms—fundamental truths you accept and build on top of. You don’t need to understand the absolute details of how SHA-256 works internally to use it correctly in JWT signatures.
This series is my way of writing down what I wish someone had explained to me when I first saw those base64-encoded strings in logs. I’ll break down JOSE specifications in detail, and I’ll include links to resources that explain certain concepts better than I can.
If you’ve seen JWT tokens and are trying to understand how they’re created and validated, this kind of post might help you.
What is JOSE?
JOSE stands for JSON Object Signing and Encryption. These specifications define how to securely use JSON for communication between two parties.
A Brief Context: Data Exchange Formats
Data between two parties can be communicated using different formats. Over time, these formats have evolved through various specifications:
- XML - The verbose but structured approach that dominated early web services and still is in certain domains- SAML :)
- JSON - The lightweight, human-readable format that has become the modern standard
Let’s focus on JSON, which originated from JavaScript. At its core, JSON is beautifully simple: it defines data as key-value pairs within curly brackets:
{
"username": "alice",
"email": "[email protected]",
"role": "admin"
}
From Simple JSON to Secure JSON: Enter JOSE
JSON alone is just data—it’s like sending a postcard through the mail. Anyone can read it, anyone can modify it, and you can’t prove who sent it.
You can use JSON as the data format for all your security use cases, but the simple example above raises critical questions:
- How do I sign this data so the recipient knows it came from me and hasn’t been tampered with?
- How do I encrypt this data so only the intended recipient can read it?
- Which cryptographic algorithm should I use for signing or encryption?
- How do I represent the keys needed to perform these operations?
- How do I package everything together in a standardized way?
This is where JOSE comes in.
JOSE: The Security Layer for JSON
Think of JOSE as a toolkit of specifications that answers each of these questions:
1. JWS (JSON Web Signature) - The “how to sign” answer
- Defines how to create digital signatures over JSON data
- Like putting a tamper-evident seal on your data
- Proves authenticity and integrity
2. JWE (JSON Web Encryption) - The “how to encrypt” answer
- Defines how to encrypt JSON data
- Like putting your data in a locked box
- Provides confidentiality
3. JWA (JSON Web Algorithms) - The “which algorithm” answer
- Catalogs all the cryptographic algorithms you can use
- RS256, ES256, EdDSA for signing
- RSA-OAEP, ECDH-ES for encryption
- Takes the guesswork out of crypto selection
4. JWK (JSON Web Key) - The “how to represent keys” answer
- Defines JSON format for cryptographic keys
- Public keys, private keys, symmetric keys—all in JSON
- Makes key exchange and management standardized
5. JWT (JSON Web Token) - The “package it all together” answer
- Combines your claims (data) with security (JWS or JWE)
- The complete package used in OAuth, OIDC, etc.
- What you actually send between services
A Real Example
Without JOSE, if you wanted to send a secure authentication token, every company would invent their own format:
- Company A might use XML signatures
- Company B might use custom Base64 encoding with proprietary crypto
- Company C might invent yet another approach
With JOSE, everyone can speaks the same language:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0...
Any system that implements JOSE can:
- Parse this token
- Verify the signature
- Extract the claims
- Trust the result
Why JOSE Matters for IAM
JOSE provides interoperability - the same reason we have HTTP standards instead of every website using a different protocol.
Instead of every company inventing their own way to sign JSON data or represent keys, JOSE gives us:
- Interoperability - A JWT created by Google can be verified by Microsoft
- Security best practices - Vetted cryptographic approaches, not homegrown crypto
- Flexibility - Multiple algorithms for different security requirements
- Ecosystem - Libraries in every language that just work together
This is why OAuth 2.0 and OpenID Connect are built on JOSE. It took the simplicity of JSON and gave it the security capabilities needed for production IAM systems.
In the IAM world, we constantly deal with:
- Authentication tokens that prove who you are
- Authorization decisions that determine what you can access
- Secure communication between services that must be tamper-proof
- Key management for cryptographic operations
JOSE provides the standardized toolkit to handle all of these securely using JSON, which is why it’s become the foundation for modern protocols like OAuth 2.0 and OpenID Connect.
What’s Coming in This Series
In the upcoming posts, I’ll be diving deep into each of the JOSE Spec to give idea how you should use them and may be i will learn something new along the way.
Each post will include practical examples from real-world IAM implementations, because understanding the specs is one thing—knowing how to apply them is what really matters.