Registry / auth-security / pyjwt
library2.13.0pypypi✓ verified 27d ago

PyJWT is the canonical Python implementation of JSON Web Tokens (RFC 7519), supporting HMAC (HS256/384/512), RSA (RS256/384/512, PS256/384/512), EC (ES256/384/512), and OKP (EdDSA) algorithms. Current stable version is 2.12.1 (released March 2026). The project follows an irregular release cadence driven by security advisories and feature PRs, with several releases per year. Asymmetric algorithms (RS*, ES*, PS*, EdDSA) require the optional `cryptography` extra.

pip install pyjwt
INSTALL
IMPORT
SIG · PYJWT
P
pyjwt
auth-securitypythonv2.13.0
Install
1.7s avg
Import
118ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.13.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.910 runs
installs and imports cleanly · install 0.0s · import 0.121s · 18.3MB
glibc
py 3.103.910 runs
installs and imports cleanly · install 1.7s · import 0.114s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

jwt (module)
import jwt
Top-level module exposes encode(), decode(), get_unverified_header(), and all exception classes.
PyJWKClient
from jwt import PyJWKClient
Used for automatic JWKS endpoint fetching and key resolution (e.g. Auth0, Cognito).
PyJWK
from jwt import PyJWK
Wraps a single JSON Web Key; returned by PyJWKClient.get_signing_key_from_jwt().
ExpiredSignatureError
from jwt.exceptions import ExpiredSignatureError
from jwt.exceptions import ExpiredSignature
ExpiredSignature (no 'Error' suffix) was removed in 2.0. Use ExpiredSignatureError, InvalidAudienceError, InvalidIssuerError.
InvalidAudienceError
from jwt.exceptions import InvalidAudienceError
from jwt.exceptions import InvalidAudience
InvalidAudience (no 'Error' suffix) was removed in 2.0.
PyJWKClientConnectionError
from jwt import PyJWKClientConnectionError
Raised when PyJWKClient cannot reach the JWKS endpoint; exported at top level since 2.8.0.

Encode and decode a signed JWT with HS256, validating exp/aud/iss claims. token is a str in PyJWT 2.x.

import os import jwt from datetime import datetime, timezone, timedelta SECRET = os.environ.get('JWT_SECRET', 'change-me-use-32-plus-chars-prod!') # Encode payload = { "sub": "user-123", "iss": "my-service", "aud": "my-api", "exp": datetime.now(tz=timezone.utc) + timedelta(hours=1), "iat": datetime.now(tz=timezone.utc), } token: str = jwt.encode(payload, SECRET, algorithm="HS256") print("token type:", type(token)) # <class 'str'> in 2.x # Decode — always pass algorithms= to prevent alg confusion attacks try: decoded = jwt.decode( token, SECRET, algorithms=["HS256"], # required; never omit audience="my-api", # validates 'aud' claim issuer="my-service", # validates 'iss' claim options={"require": ["exp", "iat", "sub"]}, ) print(decoded) except jwt.ExpiredSignatureError: print("token expired") except jwt.InvalidTokenError as e: print("invalid token:", e)
Debug
Known issues
breakingjwt.encode() returns str in 2.x, not bytes. Calling .decode('utf-8') on the result raises AttributeError.
fix
Remove any .decode('utf-8') calls on the encode() return value. It is already a str in 2.0+.
affects: <2.0
breakingException aliases ExpiredSignature, InvalidAudience, and InvalidIssuer were removed in 2.0. Code catching these names will silently fail to catch the exception.
fix
Catch jwt.ExpiredSignatureError, jwt.InvalidAudienceError, and jwt.InvalidIssuerError respectively.
affects: <2.0
breakingjwt.decode(token, key, verify=False) does nothing in 2.x and raises a deprecation warning. Passing extra kwargs to decode() is flagged RemovedInPyjwt3Warning.
fix
Use options={"verify_signature": False} to skip verification, e.g. jwt.decode(token, options={"verify_signature": False}).
affects: 1.x pattern used in 2.x
breakingCVE-2026-32597 (GHSA-752w-5fwx-jx9f, CVSS 7.5 HIGH): versions < 2.12.0 silently accept JWS tokens with unknown crit header extensions, violating RFC 7515 §4.1.11.
fix
Upgrade to pyjwt>=2.12.0 immediately.
affects: <2.12.0
gotchaalgorithms= parameter is required in jwt.decode(). Omitting it accepts any algorithm, enabling alg:none and key-confusion attacks (CVE-2022-29217).
fix
Always pass a hard-coded allowlist: jwt.decode(token, key, algorithms=["HS256"]). Never derive the list from the token header.
affects: all 2.x
gotchaOptional claims (exp, iat, nbf, sub, jti) are only validated when present. A token missing exp is accepted even if you call decode() without options.
fix
Pass options={"require": ["exp", "iat", "sub"]} to enforce presence and validation of critical claims.
affects: all 2.x
gotchaRSA/EC/PS*/EdDSA algorithms silently fail with an unhelpful ImportError or InvalidAlgorithmError if the cryptography package is not installed.
fix
Install pyjwt[cryptography] when using any non-HMAC algorithm.
affects: all 2.x
Errors
Common errors & fixes
jwt.exceptions.InvalidAlgorithmError: The specified alg value is not allowed
The `algorithms` parameter was either not provided or did not include the algorithm used to sign the token when calling `jwt.decode()`. PyJWT requires explicit declaration of allowed algorithms for security reasons.
fix
Pass a list of explicitly allowed algorithms, matching the token's 'alg' header, to the `algorithms` parameter in `jwt.decode()`. Example: `jwt.decode(token, secret, algorithms=['HS256'])`
NotImplementedError: Algorithm 'RS256' could not be found. Do you have cryptography installed?
You are attempting to use an asymmetric algorithm (such as RS*, ES*, PS*, or EdDSA) but the optional `cryptography` dependency for PyJWT is not installed.
fix
Install PyJWT with the `crypto` extra to include the `cryptography` dependency: `pip install "pyjwt[crypto]"` (note the quotes for shell compatibility).
jwt.exceptions.InvalidSignatureError: Signature verification failed
The secret key or public key provided to `jwt.decode()` does not match the key used to sign the token, or the token itself is malformed or has been tampered with.
fix
Ensure the `key` parameter passed to `jwt.decode()` is the correct secret (for symmetric algorithms like HS256) or the correct public key (for asymmetric algorithms like RS256) that was used during the token's encoding.
AttributeError: 'module' object has no attribute 'encode'
This error often occurs due to a naming conflict when both the `PyJWT` library (which provides the `jwt` module) and an older, incompatible `jwt` package are installed simultaneously.
fix
Uninstall both packages (`pip uninstall jwt pyjwt`) to remove any conflicting installations, then reinstall only PyJWT (`pip install pyjwt`).
Upgrade
Version history
2.13.0latest on PyPI · released May 21, 2026
Audit
Dependencies
cryptographyoptionalRequired for RSA, EC, PS*, and EdDSA algorithms. Not needed for HMAC-only usage.
typing_extensionsrequiredRequired on Python < 3.11 (added in 2.12.1).
Agent activity
33 hits · last 30 days
node
30
OpenAI (training)
1
Resources
pyjwt — pip install pyjwt · libregistry