JOSE RFCs Implementation
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.
Warnings
- 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`.
- breaking `jwt.ClaimsRegistry` was renamed to `jwt.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.
- 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.
- 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).
- gotcha Security warnings are now shown when importing potentially weak `OctKey` and `RSAKey` instances, typically if the key size is insufficient.
Install
-
pip install joserfc
Imports
- 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
- ClaimsRegistry
from joserfc.jwt import BaseClaimsRegistry
Quickstart
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}")