JOSE RFCs Implementation

raw JSON →
1.6.3 verified Tue May 12 auth: no python install: verified

joserfc is a Python library that provides a comprehensive implementation of several essential JSON Object Signing and Encryption (JOSE) standards, including JWS, JWE, JWK, JWA, and JWT. It is derived from Authlib, but features a redesigned API specific to JOSE functionality. It strictly follows the latest versions of the JOSE standards, guaranteeing interoperability and compliance. The current version is 1.6.3 and it maintains an active release cadence with regular updates.

pip install joserfc
error joserfc.errors.UnsupportedAlgorithmError: unsupported_algorithm: Algorithm of "HS384" is not recommended
cause By default, joserfc only allows a set of recommended algorithms for security reasons; algorithms like 'HS384' might not be in this default set.
fix
Enable 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.
error TypeError: Object of type UUID is not JSON serializable
cause 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.
fix
Pass 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.
error joserfc.errors.BadSignatureError
cause This error indicates that the JWS signature verification failed, typically because the token was tampered with, or an incorrect key was used for verification.
fix
Ensure 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.
error joserfc.errors.MissingClaimError
cause 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.
fix
Ensure that the JWT includes all claims marked as 'essential' or otherwise required by the JWTClaimsRegistry used for validation.
error joserfc.errors.ExceededSizeError: Header size of 'b''' exceeds 512 bytes.
cause 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.
fix
Reduce 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.
breaking The 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`.
fix Update 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`.
breaking `jwt.ClaimsRegistry` was renamed to `jwt.BaseClaimsRegistry`.
fix Adjust import statements and class instantiations to use `BaseClaimsRegistry`.
breaking Error 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.
fix Review error handling code to catch the new, more specific exception types. Use `InvalidClaimError` for JWT claim validation failures.
gotcha Unlike 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.
fix Always 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.
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).
fix Use a third-party HTTP client library like `requests` to retrieve JWK Sets from URLs, then use `jwk.JsonWebKey.import_key_set()` to load them.
gotcha Security warnings are now shown when importing potentially weak `OctKey` and `RSAKey` instances, typically if the key size is insufficient.
fix Ensure 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.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.33s 35.1M
3.10 alpine (musl) - - 0.34s 34.0M
3.10 slim (glibc) wheel 2.6s 0.24s 36M
3.10 slim (glibc) - - 0.23s 34M
3.11 alpine (musl) wheel - 0.58s 37.2M
3.11 alpine (musl) - - 0.64s 36.1M
3.11 slim (glibc) wheel 2.4s 0.57s 38M
3.11 slim (glibc) - - 0.49s 37M
3.12 alpine (musl) wheel - 0.43s 29.0M
3.12 alpine (musl) - - 0.49s 27.9M
3.12 slim (glibc) wheel 2.5s 0.48s 29M
3.12 slim (glibc) - - 0.52s 28M
3.13 alpine (musl) wheel - 0.40s 28.8M
3.13 alpine (musl) - - 0.42s 27.6M
3.13 slim (glibc) wheel 2.1s 0.45s 29M
3.13 slim (glibc) - - 0.46s 28M
3.9 alpine (musl) wheel - 0.31s 35.3M
3.9 alpine (musl) - - 0.31s 34.3M
3.9 slim (glibc) wheel 3.0s 0.32s 36M
3.9 slim (glibc) - - 0.29s 35M

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}")