Install & Compatibility
Where this runs
tested against v1.7.4 · 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
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.418s · 35.7MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.6s · import 0.408s · 36MB
34MB installed
● package 34MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
jwt, jwk
✓ from joserfc import jwt, jwk
RSAKey
✓ from joserfc.jwk import RSAKey
serialize_compact, deserialize_compact
✓ from joserfc.jws import serialize_compact, deserialize_compact
✗ from joserfc.rfc7797 import serialize_compact, deserialize_compact
Deprecated rfc modules were removed in v1.4.0; use the direct jws module instead.
ClaimsRegistry
✓ from joserfc.jwt import BaseClaimsRegistry
✗ from joserfc.jwt import ClaimsRegistry
Renamed to BaseClaimsRegistry in v1.4.0.
This quickstart demonstrates how to encode and decode a JSON Web Token (JWT) using a symmetric key. It also includes an example of explicit claims validation, which is a crucial step for production environments.
import os
from joserfc import jwt, jwk
# For demonstration, use a simple symmetric key. In production, use a secure, generated key.
secret_key = os.environ.get('JOSERFC_SECRET_KEY', 'your-super-secret-key-that-is-at-least-32-chars')
# 1. Import or generate a JWK
# For symmetric keys, use 'oct' (octet) key type
key = jwk.import_key(secret_key, 'oct')
# 2. Define JWT header and claims
header = {"alg": "HS256", "typ": "JWT"}
claims = {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
# 3. Encode the JWT
encoded_jwt = jwt.encode(header, claims, key)
print(f"Encoded JWT: {encoded_jwt}")
# 4. Decode the JWT
token = jwt.decode(encoded_jwt, key)
print(f"Decoded Header: {token.header}")
print(f"Decoded Claims: {token.claims}")
# 5. Validate claims (important for production)
claims_registry = jwt.JWTClaimsRegistry()
try:
claims_registry.validate(token.claims, now=1516239022) # 'now' for reproducible example
print("Claims validated successfully.")
except jwt.InvalidClaimError as e:
print(f"Claim validation failed: {e}")
Debug
Known issues
breakingThe deprecated `joserfc.rfcXXXX` modules (e.g., `joserfc.rfc7797` for JWS compact serialization/deserialization) were removed in favor of direct usage of modules like `joserfc.jws`.fixUpdate import paths and usage to directly use methods from `joserfc.jws`, `joserfc.jwe`, etc. For instance, `joserfc.jws.serialize_compact` instead of `joserfc.rfc7797.serialize_compact`.
affects: >=1.4.0
breaking`jwt.ClaimsRegistry` was renamed to `jwt.BaseClaimsRegistry`.fixAdjust import statements and class instantiations to use `BaseClaimsRegistry`.
affects: >=1.4.0
breakingError classes related to JWT claims and JWS/JWE operations have changed significantly. `InvalidTokenError` and `ExpiredTokenError` were deprecated in favor of `InvalidClaimError`, and `ValueError` in JWS/JWE registries was replaced by `UnsupportedAlgorithmError`. Other new specific errors like `MissingKeyTypeError` and `InvalidKeyIdError` were introduced.fixReview error handling code to catch the new, more specific exception types. Use `InvalidClaimError` for JWT claim validation failures.
affects: >=1.4.1, >=1.6.1
gotchaUnlike some other JWT libraries (e.g., `PyJWT`), `joserfc` separates token decoding from claims validation. The `.decode()` method only extracts header and payload; explicit validation using `jwt.JWTClaimsRegistry` is required.fixAlways perform claims validation explicitly after decoding a token, for example, by creating an instance of `jwt.JWTClaimsRegistry` and calling its `validate` method on the token's claims.
affects: All versions
gotcha`joserfc` does not provide a built-in HTTP client for fetching JWK Sets from a URL (e.g., from an OpenID Connect discovery endpoint).fixUse a third-party HTTP client library like `requests` to retrieve JWK Sets from URLs, then use `jwk.JsonWebKey.import_key_set()` to load them.
affects: All versions
gotchaSecurity warnings are now shown when importing potentially weak `OctKey` and `RSAKey` instances, typically if the key size is insufficient.fixEnsure you are using sufficiently strong keys (e.g., RSA keys of at least 2048 bits, preferably 4096 bits, and symmetric keys of appropriate length for the chosen algorithm) to avoid these warnings and maintain security.
affects: >=1.4.1
Errors
Common errors & fixes
joserfc.errors.UnsupportedAlgorithmError: unsupported_algorithm: Algorithm of "HS384" is not recommended
By default, joserfc only allows a set of recommended algorithms for security reasons; algorithms like 'HS384' might not be in this default set.
fixEnable the unsupported algorithm manually by passing an `algorithms` parameter to the relevant registry or method (e.g., `jws.serialize_compact`, `jwt.encode`, `jwt.decode`). Example: `jws.serialize_compact(protected, payload, key, algorithms=['HS384'])` or by creating a custom registry.
TypeError: Object of type UUID is not JSON serializable
When using `jwt.encode` to encode claims, the `joserfc` library (which uses Python's `json` module internally) encounters data types like `UUID` or `datetime` that are not natively supported for JSON serialization.
fixPass a custom `JSONEncoder` subclass to the `encoder_cls` parameter of `jwt.encode` to handle the serialization of unsupported data types. For `datetime` objects, `joserfc` automatically converts `iat`, `exp`, and `nbf` to timestamps.
joserfc.errors.BadSignatureError
This error indicates that the JWS signature verification failed, typically because the token was tampered with, or an incorrect key was used for verification.
fixEnsure that the correct key (e.g., public key for asymmetric algorithms, or the shared secret for symmetric algorithms) is provided for signature verification and that the token has not been altered since it was signed.
joserfc.errors.MissingClaimError
When validating JWT claims using a `JWTClaimsRegistry`, this error is raised if an 'essential' claim, or any other required claim, is not present in the token's payload.
fixEnsure that the JWT includes all claims marked as 'essential' or otherwise required by the `JWTClaimsRegistry` used for validation.
joserfc.errors.ExceededSizeError: Header size of 'b''' exceeds 512 bytes.
This error occurs when the size of the JWT's header, payload, or signature exceeds the predefined maximum length enforced by the `joserfc` library's registry.
fixReduce the size of the JWT's components (header, payload, or signature) to stay within the configured limits. If necessary and after careful security consideration, adjust the `max_header_length`, `max_payload_length`, or `max_signature_length` on the registry used. Also, ensure a robust reverse proxy is in place to cap maximum header sizes.
Upgrade
Version history
1.7.4latest on PyPI · released Jul 19, 2026
Audit
Dependencies
cryptographyrequiredRequired for cryptographic operations.