Skip to main content
Category: Identity and Access Management

JSON Web Token

Also known as: JWT, jot
Simply put

A JSON Web Token (JWT, pronounced 'jot') is a compact, self-contained token used to securely transmit information between two parties, typically a client and a server. It encodes claims as JSON and is formatted to be safe for use in URLs. JWTs are commonly used in web applications and APIs to handle authentication and authorization.

Formal definition

JSON Web Token (JWT) is an open standard defined in RFC 7519 that specifies a compact, URL-safe method for representing claims to be transferred between two parties. The claims are encoded as a JSON object and may be digitally signed (using JWS) or encrypted (using JWE), enabling integrity verification and, optionally, confidentiality. The token structure supports self-contained transmission of identity and authorization context without requiring server-side session state.

Why it matters

JWTs are central to how modern web applications and APIs handle authentication and authorization. Because the token is self-contained, servers can verify a user's identity and permissions without querying a central session store, making JWTs well-suited for stateless and distributed architectures. This design has made them a dominant mechanism in single-page applications, mobile backends, and microservices.

However, the self-contained nature of JWTs also means that implementation mistakes carry significant security consequences. A forged or tampered token can grant unauthorized access to any resource that trusts it, because the token itself carries the authorization context. Vulnerabilities such as the 'alg:none' attack, where an attacker strips the signature algorithm from the header to bypass verification, and algorithm confusion attacks that exploit libraries accepting both symmetric and asymmetric key types, have been demonstrated repeatedly in real-world systems. These classes of issue arise not from the standard itself but from insecure library implementations and developer misconfiguration.

Revocation also presents a structural challenge. Unlike server-side sessions, a signed JWT remains valid until its expiration time unless the application implements additional controls such as a token blocklist or short expiry windows. This means that a compromised token cannot be easily invalidated in real time, which has operational implications for incident response and account takeover scenarios.

Who it's relevant to

Application Developers
Developers building web applications or APIs are the primary implementers of JWTs. They must select a well-maintained JWT library, configure signature verification correctly, enforce expiry claims, and choose appropriate algorithms. Common implementation mistakes, such as accepting unsigned tokens or failing to validate the 'alg' header, can introduce critical authentication bypass vulnerabilities.
Security Engineers and Penetration Testers
Security practitioners test JWT implementations for known vulnerability classes including algorithm confusion, missing or weak signature verification, and insecure storage of tokens on the client side. These assessments typically require both static review of library configuration and runtime testing of how the application responds to malformed or manipulated tokens.
Identity and Access Management (IAM) Engineers
IAM engineers use JWTs as the token format in OAuth 2.0 and OpenID Connect flows, where they carry identity assertions and authorization grants. They are responsible for defining token lifetimes, scope structures, and key rotation policies, all of which affect the security posture of the broader authentication infrastructure.
Security Architects
Architects evaluating stateless authentication patterns must weigh the scalability benefits of JWTs against the structural limitations around revocation and payload confidentiality. Decisions about token expiry windows, refresh token strategies, and whether to sign or encrypt tokens are architectural choices with direct security implications.
Compliance and Risk Professionals
For systems subject to regulatory requirements around session management and access control, the use of JWTs introduces considerations around token revocation, auditability of issued claims, and secure storage. Compliance reviewers should assess whether the JWT implementation satisfies applicable session management requirements, particularly in contexts where immediate revocation of access is a control objective.

Inside JWT

Header
The first segment of a JWT, Base64URL-encoded JSON that declares the token type (typically 'JWT') and the signing algorithm used, such as HS256 or RS256. The algorithm field in the header is used by the receiving party to determine how to verify the token's signature.
Payload
The second segment of a JWT, Base64URL-encoded JSON containing claims. Claims are statements about an entity (typically the user) and additional metadata, and may include registered claims such as 'iss' (issuer), 'sub' (subject), 'exp' (expiration time), 'nbf' (not before), and 'iat' (issued at), as well as public and private claims.
Signature
The third segment of a JWT, produced by applying the algorithm declared in the header to the encoded header and payload using a secret or private key. The signature allows recipients to verify that the token has not been tampered with and, in asymmetric schemes, that it was issued by a trusted party.
Registered Claims
A set of predefined, interoperable claim names defined by RFC 7519, including 'iss' (issuer), 'sub' (subject), 'aud' (audience), 'exp' (expiration time), 'nbf' (not before), 'iat' (issued at), and 'jti' (JWT ID). These claims are optional but recommended for standardizing token semantics across systems.
Algorithm Field ('alg')
A field within the JWT header that specifies the cryptographic algorithm used to sign or encrypt the token. Improper trust of this field by the verifying party can introduce vulnerabilities, such as accepting 'none' as a valid algorithm or allowing algorithm confusion between symmetric and asymmetric schemes.
Base64URL Encoding
The encoding scheme applied to the header and payload segments of a JWT. Base64URL encoding is not encryption and does not provide confidentiality. The contents of a JWT header and payload are readable by anyone who possesses the token unless the token is also encrypted (JWE).

Common questions

Answers to the questions practitioners most commonly ask about JWT.

Does signing a JWT automatically protect the data inside it from being read by others?
No. A signed JWT (using JWS) provides integrity and authenticity, confirming that the token has not been tampered with and was issued by a trusted party, but it does not encrypt the payload. Anyone who possesses the token can base64-decode the header and payload and read the claims in plaintext. If the payload contains sensitive data, a JWE (JSON Web Encryption) token should be used instead, or sensitive fields should be omitted from the token entirely.
Can a JWT be invalidated before its expiration time if it is compromised?
Not by default. JWTs are stateless by design, meaning the server does not track issued tokens. A valid, signed token will typically be accepted until its 'exp' claim is reached, regardless of whether it has been compromised. To support early invalidation, applications must implement a server-side mechanism such as a token denylist or a token version counter stored in a database. This introduces statefulness and partially offsets the stateless benefits of JWTs, so the appropriate trade-off should be evaluated based on the application's security requirements.
What expiration ('exp') lifetime should be used for a JWT in a typical web application?
Short-lived access tokens are generally recommended, commonly in the range of 5 to 60 minutes, depending on the sensitivity of the resource being protected. Longer lifetimes increase the window of exposure if a token is compromised. Applications that require longer sessions typically pair short-lived access tokens with longer-lived refresh tokens, using the refresh token to obtain new access tokens without requiring the user to re-authenticate.
How should a server validate a JWT it receives, and what checks are required?
Validation should include verifying the signature against the expected algorithm and key, confirming the token has not expired by checking the 'exp' claim, verifying the 'nbf' (not before) claim if present, confirming the 'iss' (issuer) claim matches the expected token issuer, and verifying the 'aud' (audience) claim matches the intended recipient. Servers should explicitly specify the allowed algorithm rather than accepting whatever algorithm the token header declares, to prevent algorithm confusion attacks such as the 'alg: none' vulnerability.
Where should a JWT be stored in a browser-based application?
Each storage option involves trade-offs. Storing a JWT in localStorage is accessible to JavaScript, which exposes it to cross-site scripting (XSS) attacks. Storing it in an HttpOnly, Secure cookie prevents JavaScript access, mitigating XSS exposure, but requires CSRF protections to be in place. The appropriate choice depends on the threat model of the application. Many security practitioners favor HttpOnly cookies for access tokens in browser contexts, combined with anti-CSRF measures, though implementations vary based on application architecture.
What is the difference between using a symmetric versus an asymmetric algorithm for signing JWTs, and when should each be used?
Symmetric algorithms such as HS256 use a single shared secret for both signing and verification, meaning any party that can verify the token can also issue tokens. This is suitable when signing and verification occur within the same service or a tightly controlled set of trusted services. Asymmetric algorithms such as RS256 or ES256 use a private key for signing and a public key for verification, allowing tokens to be verified by external parties without granting them the ability to issue tokens. Asymmetric signing is generally preferred in distributed systems or when tokens are verified by third parties, as it limits the blast radius if a verifying party is compromised.

Common misconceptions

JWT payloads are encrypted and their contents are confidential by default.
Standard JWTs use Base64URL encoding for the header and payload, which provides no confidentiality. Anyone who obtains the token can decode and read its contents without knowing the signing key. Confidentiality requires using JSON Web Encryption (JWE) in addition to or instead of standard signed JWTs.
A valid JWT signature guarantees the token has not been revoked and is still authorized for use.
Signature verification only confirms that the token was signed by the expected party and has not been tampered with. JWTs are typically stateless and self-contained, meaning a validly signed token remains usable until its expiration time unless the application implements an additional revocation mechanism such as a token blocklist or short expiration windows.
The algorithm declared in the JWT header can be trusted and used directly to select the verification method.
Blindly trusting the 'alg' field in the JWT header is a well-known vulnerability class. Attackers may modify the header to specify 'none' to bypass signature verification, or switch from an asymmetric algorithm to a symmetric one to exploit a public key as a shared secret. Verifiers should enforce the expected algorithm explicitly rather than deriving it from the token itself.

Best practices

Explicitly specify and enforce the expected signing algorithm on the verifier side rather than accepting the algorithm declared in the JWT header. Reject tokens that specify 'none' or any algorithm not included in an allowlist.
Set short expiration times ('exp' claim) appropriate to the sensitivity of the operation, and implement a server-side revocation or blocklist mechanism for use cases where immediate invalidation of tokens (such as logout or credential change) is required.
Never store sensitive or confidential data in the JWT payload unless the token is also encrypted using JWE, because the payload is only Base64URL-encoded and is readable by any party that obtains the token.
Validate all relevant registered claims on receipt, including 'exp' (expiration), 'nbf' (not before), 'iss' (issuer), and 'aud' (audience), to prevent token reuse across different contexts or after expiration.
Use asymmetric signing algorithms (such as RS256 or ES256) for scenarios where multiple services need to verify tokens but only one service should be able to issue them, reducing the risk of a compromised verifier being used to forge tokens.
Protect JWTs in transit and at rest using transport-layer security, and store tokens in ways that mitigate client-side theft, such as using HttpOnly and Secure cookie flags when storing tokens in browser environments.