In a modern microservices system, services need a reliable way to establish trust without querying a central database for every single incoming request. This need is precisely why JSON Web Tokens (JWTs) have become the industry standard for transmitting verifiable information between clients and servers—or directly between services.
However, while thousands of developers use JWTs daily, very few actually understand the underlying specification. This knowledge gap leaves many applications vulnerable to simple security flaws. To build bulletproof authorization systems, we must look under the hood and explore the entire JOSE (JSON Object Signing and Encryption) framework.
1. The Problem with Traditional Sessions
To appreciate the design of JWTs, it helps to understand why traditional session-based authentication breaks down at scale:
Traditional Sessions: When a user logs in, the server creates a session entry in memory or a database and returns a Session ID to the client. On every subsequent request, the server must query the database to validate that Session ID.
The Microservices Bottleneck: In an architecture split into specialized services (e.g., Billing Service, Inventory Service, User Service), every service would need to make remote calls to the User Service or a central database just to verify the user's identity. This introduces major latency bottlenecks and hinders scaling.
The Stateless Solution: JWTs solve this problem by remaining completely stateless. The issuing server embeds user identity data (such as User IDs and roles) directly into the token and signs it using a cryptographic key.
Because the token itself carries verifiable proof, any downstream service can independently validate the signature and trust the claims without querying a database. The JOSE working group began standardizing this JSON-based security approach in 2011 to provide uniform authentication across languages and systems.
2. Practical Applications of JWTs
In production systems, JWTs typically serve two primary roles, along with a distinct workflow for token lifecycle management:
Stateless Sessions
Instead of maintaining server-side state, user roles and permissions (e.g., "role": "admin") are embedded directly into the token payload. The server evaluates these claims instantly on each request.
Security Note: Storage mechanics matter. Storing tokens in browser cookies requires protection against Cross-Site Request Forgery (CSRF), while local storage requires rigorous protection against Cross-Site Scripting (XSS).
Federated Identity (OpenID Connect)
Federated authentication (such as "Log in with Google") relies on OpenID Connect (OIDC), an identity layer built on top of OAuth2. In this architecture:
The App redirects the user to an Identity Provider (IdP) like Google.
Google authenticates the user and issues an ID Token (a signed JWT) back to the App.
The App reads the embedded assertions (called Claims, such as
email) and trusts them because they bear Google's signature. This mechanism powers Single Sign-On (SSO) across systems.
Access Tokens vs. Refresh Tokens
Most authentication systems utilize two distinct token types:
Access Tokens: Short-lived (typically ~15 minutes) and formatted as JWTs, these are presented with API requests to access protected resources.
Refresh Tokens: Long-lived and usually not formatted as JWTs. Servers intentionally look up refresh tokens in a database to confirm that the user account has not been revoked, suspended, or deleted before issuing a new access token.
3. Anatomy of a JWT
A standard compact JWT appears as a single string composed of three distinct parts separated by dots (.). While it looks like random gibberish, it is simply Base64-URL encoded JSON data.
[Header].[Payload].[Signature]
The Header
The header is a JSON object defining how the token should be parsed.
typ: The token type, almost always"JWT".alg: The cryptographic algorithm used to sign the token.cty: The Content Type, used primarily when nesting tokens inside one another.
The Payload
The payload contains the actual Claims (assertions about the user or token). The specification defines standard Registered Claims using compact three-letter keys:
iss(Issuer): Who created and issued the token.sub(Subject): Whom the token identifies (typically the User ID).aud(Audience): The intended recipient service.exp(Expiration Time): Unix timestamp indicating when the token expires.nbf(Not Before): Timestamp before which the token must be rejected.iat(Issued At): Timestamp when the token was created.jti(JWT ID): A unique identifier used to prevent replay attacks.…
Developers can also include Public Claims intended for common standard use, or Private Claims specific to custom application logic.
The Signature
The signature protects the integrity of the token. It is created by taking the Base64-URL encoded header and payload, joining them with a dot, and passing them through the specified alg mathematical function alongside a secret or private key.
Step | Operation |
1. Issuance | The server constructs the header and payload, signs them, Base64-URL encodes the segments, joins them with dots, and sends the string to the client. |
2. Storage & Transmission | The client stores the token and attaches it to authorization headers in subsequent requests. |
3. Verification | The recipient server extracts the token, recalculates the signature using its own secret key, and compares it with the token's signature segment. |
If an attacker modifies even a single character in the payload, signature recalculation will fail, causing the server to reject the token immediately.
Warning on Unsecured JWTs: Tokens using "alg": "none" carry no signature segment at all. These "Unsecured JWTs" allow anyone to tamper with payload claims and should almost never be accepted in secure environments.
4. JSON Web Signatures (JWS)
If a JWT is a container for data, JSON Web Signature (JWS) is the specific specification that defines how to lock that container mathematically.
JWS ensures two critical properties:
Integrity: Proves the data has not been modified in transit.
Authenticity: Confirms the identity of the issuer.
Crucially, JWS does not encrypt or hide data—anyone who intercepts the token can decode Base64-URL and read the raw claims.
Signature Algorithms
Algorithm | Type | Description |
HS256 | Symmetric | Uses a single shared secret key for both signing and verification. Simple and fast, but requires sharing the secret with every verifying service. |
RS256 | Asymmetric | Uses RSA public/private key pairs. The auth server signs with a private key, while downstream microservices verify using a public key. |
ES256 | Asymmetric | Uses Elliptic Curve cryptography. Delivers equal security to RSA but uses significantly smaller keys, maximizing speed and efficiency. |
To assist servers in locating the correct verification key, JWS headers can include key references such as kid (Key ID), jwk (JSON Web Key), or jku (JWK Set URL).
Critical Security Rule: Enforce Algorithm Verification
A widespread security vulnerability occurs when code relies on the token's header to determine which algorithm to execute during verification. Attackers can exploit this by changing the header alg to "none" or switching an asymmetric algorithm like RS256 to symmetric HS256 using a public key as the secret.
Always explicitly configure your application library to accept only expected algorithms (e.g., forcing RS256) regardless of what the token header claims.
5. JSON Web Encryption (JWE)
While JWS provides integrity, JSON Web Encryption (JWE) provides confidentiality. If a payload contains sensitive data that must remain hidden from unauthorized viewers, JWE transforms the payload into an opaque string that cannot be read without the private key.
Key Mechanics & Structure
The key usage direction in JWE is reversed compared to JWS:
JWS: Signed with a private key; verified using a public key.
JWE: Encrypted using a recipient's public key; decrypted using their private key.
To achieve both sender authenticity and data secrecy, developers use Nested JWTs—signing the payload with JWS first, then wrapping that signed token inside a JWE envelope. This also prevents signature removal attacks.
Because encryption requires additional parameters, a JWE compact token consists of five dot-separated parts:
Protected Header: Declares encryption algorithms used.
Encrypted Key: The encrypted Content Encryption Key (CEK) used to scramble the payload.
Initialization Vector (IV): Random data ensuring identical plaintext yields unique ciphertext every time.
Ciphertext: The encrypted payload data.
Authentication Tag: Proves the ciphertext has not been tampered with.
JWE supports both Compact Serialization (the standard 5-part string) and JSON Serialization, which allows a single payload to be encrypted for multiple distinct recipients simultaneously.
6. JSON Web Keys (JWK & JWKS)
For asymmetric cryptography to work seamlessly across heterogeneous microservice fleets, systems need a standardized way to represent and publish cryptographic keys. JSON Web Keys (JWK) standardizes key formats into clean JSON structures.
A standard JWK includes fields such as:
kty(Key Type): Identifies the key family, such as"RSA","EC"(Elliptic Curve), or"oct"(Symmetric).use: Specifies intended usage, such as"sig"(signature) or"enc"(encryption).alg: The target algorithm (e.g.,"RS256").kid(Key ID): The unique identifier matching thekidheader in incoming JWTs.
Depending on the algorithm, the JSON object exposes exact parameters—such as n (modulus) and e (exponent) for RSA, or x and y coordinates for Elliptic Curve keys.
Key Rotation with JWKS
To handle key rotation cleanly without downtime, Identity Providers (like Auth0 or Google) host a JSON Web Key Set (JWKS) endpoint. A JWKS is simply a JSON object holding an array of all active public keys. Downstream microservices fetch this public URL (referenced in the jku header claim) to dynamically update their verification keys whenever key rotation occurs.
7. JSON Web Algorithms (JWA)
At the foundation of the JOSE framework is JSON Web Algorithms (JWA), which dictates the mathematical implementations underlying all encoding, hashing, signing, and encryption tasks.
Key Concepts
Base64-URL Encoding: Not an encryption algorithm, but a character swapping method designed to render raw binary data or JSON safe for transport within URLs.
Hash Functions (SHA-256): One-way functions that condense arbitrary inputs into fixed-length "fingerprints" (digests). Changing a single character in the input completely alters the output hash.
HMAC (HS256): Merges hash functions with a shared secret password to confirm integrity and authenticity across two parties.
RSA (RS256): Relies on the mathematical difficulty of factoring products of large prime numbers, enabling public/private key pairs.
ECDSA (ES256): Uses scalar multiplication on elliptic curve geometry to deliver equivalent cryptographic strength to RSA with dramatically smaller key sizes.
Summary Cheat Sheet
Standard | Full Name | Main Purpose | Key Feature |
JWT | JSON Web Token | Data Container | Compact, stateless format for claims |
JWS | JSON Web Signature | Integrity & Authenticity | 3-part string using digital signatures |
JWE | JSON Web Encryption | Confidentiality | 5-part encrypted string for sensitive data |
JWK / JWKS | JSON Web Key (Set) | Key Distribution | JSON representations of public keys |
JWA | JSON Web Algorithms | Cryptographic Math | Governs SHA-256, RSA, ECDSA, AES math |
By leveraging the complete JOSE specification—structuring claims properly with JWT, securing integrity with JWS, protecting confidential data with JWE, and managing keys via JWKS—you can build resilient, stateless authorization layers across any microservice architecture.
Thanks for Reading ❤
Stay tuned for the next parts 💡
Arian
