The Architecture of JSON Web Tokens (JWT RFC 7519) & Modern API Security
JSON Web Tokens (JWT) are an open, industry-standard RFC 7519 method for securely transmitting information between parties as a compact, self-contained JSON object. Because JWTs are digitally signed using cryptographic algorithms (such as HMAC with SHA-256 or RSA/ECDSA public-private keypairs), the claims they contain can be trusted and verified by downstream microservices without querying a centralized session database.
1. The Three Building Blocks of a JWT
In its compact serialized form, a JWT consists of three separate Base64URL-encoded strings separated by periods (header.payload.signature):
- Header: Typically consists of two fields: the cryptographic signing algorithm being used (e.g., "alg": "HS256" or "RS256") and the token type ("typ": "JWT").
- Payload: Contains the claims. Claims are statements about an entity (typically the authenticated user or tenant) along with additional metadata such as token issue time and expiration limits.
- Signature: Generated by hashing the encoded header, a dot delimiter, the encoded payload, and your private cryptographic secret key using the specified algorithm. The signature guarantees that the token has not been tampered with in transit.
2. Standard Registered Claims Dictionary (RFC 7519)
The IETF defines seven reserved, non-mandatory claims designed to provide interoperability across microservices and identity providers:
- iss (Issuer): The identity provider or authorization server that minted the token (e.g. https://accounts.google.com or https://auth.company.com/).
- sub (Subject): The unique identifier of the user or resource principal (e.g. UUID usr_98b4f1).
- aud (Audience): The recipient or backend API service for which the token is intended. Backend services must verify their own client ID matches the audience claim before accepting incoming requests.
- exp (Expiration Time): UNIX epoch timestamp after which the token is strictly invalid. Critical for mitigating token replay attacks.
- nbf (Not Before): The earliest timestamp at which the token becomes valid.
- iat (Issued At): The timestamp when the identity provider minted the token.
- jti (JWT ID): A unique cryptographic nonce used to prevent token replay across distributed systems.
3. Symmetric (HS256) vs Asymmetric (RS256 / ES256) Architectures
Selecting the correct signing algorithm is a foundational design choice:
- HS256 (HMAC-SHA256): Uses a single shared symmetric secret key for both generating the signature and validating it. HS256 is computationally fast, but requires that every microservice that validates the token has access to the exact secret key. If a single reporting microservice is compromised, the attacker can forge administrative tokens for the entire company.
- RS256 (RSA-SHA256) & ES256 (ECDSA): Uses an asymmetric keypair. The identity provider signs tokens using a tightly guarded private key. All downstream microservices download the provider's public key (often published via a JSON Web Key Set / JWKS endpoint) to verify incoming tokens. Even if a downstream microservice is completely compromised, the attacker cannot forge new tokens.
4. Critical JWT Security Vulnerabilities & Prevention
When implementing token-based authentication in Node.js, Go, Python, or Java, avoid these common security flaws:
- The "alg: none" Exploit: Early vulnerable JWT libraries allowed attackers to modify the header to "alg": "none", strip the signature, and submit forged admin claims. Modern authorization servers must explicitly whitelist allowed algorithms and reject "none" tokens.
- Weak Shared Secrets: In HS256, short passwords (like secret123) can be cracked offline in seconds using tools like Hashcat or John the Ripper. Always use high-entropy secrets of at least 256 bits (32 random bytes).
- Storing Sensitive Secrets in Payloads: Base64URL encoding is not encryption! Anyone holding the token can decode and view all claims in plaintext. Never store unencrypted passwords, API keys, or credit card numbers inside JWT payloads.