JWT, JWE, and JWKS Explained: A Developerβs Guide to Token-Based Security


π§ What is JWT?
JWT (JSON Web Token) is a compact, URL-safe token format used to transmit claims securely between parties. Itβs the backbone of stateless authentication and is often signed using JWS (JSON Web Signature) or encrypted using JWE (JSON Web Encryption).
π JWT = Header + Payload + Signature
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOiIxMjM0Iiwicm9sZSI6InVzZXIifQ.
ZHVtbXktc2lnbmF0dXJl
Section | Purpose |
Header | Metadata (algorithm, type) |
Payload | Claims (e.g., userId , role ) |
Signature | Verifies token integrity |
β JWT (JWS) β Signed Token
JWS = JSON Web Signature
Itβs the most common JWT. The payload is not encrypted β just signed to ensure authenticity.
π Use Case:
User login tokens
API access tokens
OAuth2 flows
π JWE β Encrypted JWT
JWE = JSON Web Encryption
Unlike JWS, JWE encrypts the payload so itβs not visible to intermediaries. It includes more sections than JWS.
<Header>.<EncryptedKey>.<IV>.<Ciphertext>.<AuthTag>
Component | Description |
Header | Algorithm & encryption method |
Encrypted Key | Encrypted symmetric key using RSA |
IV | Initialization Vector |
Ciphertext | Encrypted payload |
AuthTag | Auth tag for integrity/authentication |
π Use Case:
Financial data
Healthcare apps
B2B confidential communication
π JWT vs JWE
Feature | JWS (Signed) π | JWE (Encrypted) π |
Payload Visible | β Yes | β No |
Integrity | β Ensured via signature | β Ensured via encryption |
Confidentiality | β Not secure | β Encrypted |
Use Case | Auth tokens | Sensitive data transfer |
π§© What is JWKS?
JWKS = JSON Web Key Set
Itβs a public endpoint that exposes public keys in a JSON format. It's how services like Auth0, Google, and Okta let you verify JWTs without sharing the private key.
π§ JWKS provides a way to rotate keys without breaking consumers.
π URL Example:
https://your-auth-server.com/.well-known/jwks.json
π Example Response:
{
"keys": [
{
"kty": "RSA",
"kid": "abc123",
"use": "sig",
"n": "...base64url...",
"e": "AQAB"
}
]
}
ποΈ How it All Works Together
sequenceDiagram
participant AuthServer as π Auth Server
participant JWKS as π JWKS Endpoint
participant ClientApp as π§ Client App
participant API as π’ API Server
ClientApp ->> AuthServer: π Authenticate (Login)
AuthServer -->> ClientApp: β JWT (Signed or Encrypted)
ClientApp ->> API: π¨ Send JWT in Authorization Header
API ->> JWKS: π Fetch Public Keys
JWKS -->> API: π₯ Return Key Set
API ->> API: β
Verify Signature using Public Key
API -->> ClientApp: π Return Protected Data
π οΈ Verifying JWTs with JWKS in Node.js
β Install Dependencies
npm install jwks-rsa jsonwebtoken express
π§ Verify JWT with JWKS
const jwt = require("jsonwebtoken");
const jwksClient = require("jwks-rsa");
const client = jwksClient({
jwksUri: "https://your-auth-server.com/.well-known/jwks.json"
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}
function verifyToken(token) {
jwt.verify(token, getKey, {
algorithms: ["RS256"]
}, (err, decoded) => {
if (err) return console.error("β Invalid Token");
console.log("β
Verified Token Payload:", decoded);
});
}
β Best Practices
Practice | Why It Matters |
Use RS256 (asymmetric) for signing | Safer than HMAC in distributed systems |
Always verify iss , aud , exp | Protect against spoofed/expired tokens |
Enable key rotation using JWKS | Improves security without breaking apps |
Use JWE only when confidentiality is required | Saves performance otherwise |
π Final Thoughts
JWTs are everywhere β but understanding the difference between JWS, JWE, and JWKS is key to building secure, scalable, and standards-compliant systems.
β
Use JWS for API authentication
β
Use JWE for encrypting sensitive data
β
Use JWKS for secure key distribution and rotation
Let me know if you'd like a follow-up tutorial to implement JWKS-based auth with Auth0, Google Identity, or AWS Cognito! π
About Me π¨βπ»
I'm Faiz A. Farooqui. Software Engineer from Bengaluru, India.
Find out more about me @ faizahmed.in
Subscribe to my newsletter
Read articles from Faiz Ahmed Farooqui directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Faiz Ahmed Farooqui
Faiz Ahmed Farooqui
Principal Technical Consultant at GeekyAnts. Bootstrapping our own Data Centre services. I lead the development and management of innovative software products and frameworks at GeekyAnts, leveraging a wide range of technologies including OpenStack, Postgres, MySQL, GraphQL, Docker, Redis, API Gateway, Dapr, NodeJS, NextJS, and Laravel (PHP). With over 9 years of hands-on experience, I specialize in agile software development, CI/CD implementation, security, scaling, design, architecture, and cloud infrastructure. My expertise extends to Metal as a Service (MaaS), Unattended OS Installation, OpenStack Cloud, Data Centre Automation & Management, and proficiency in utilizing tools like OpenNebula, Firecracker, FirecrackerContainerD, Qemu, and OpenVSwitch. I guide and mentor a team of engineers, ensuring we meet our goals while fostering strong relationships with internal and external stakeholders. I contribute to various open-source projects on GitHub and share industry and technology insights on my blog at blog.faizahmed.in. I hold an Engineer's Degree in Computer Science and Engineering from Raj Kumar Goel Engineering College and have multiple relevant certifications showcased on my LinkedIn skill badges.