A Python-wrapped Rust library for RSA JWT generation and validation
Project description
Here’s the updated README with a focus on the features, including the use of jsonwebtoken under the hood and KID rotation support.
Rust-Based RSA JWT Library
This library offers a high-performance, Rust-based JWT solution with Python bindings via PyO3. Designed for security and speed, it incorporates advanced features like KID rotation, blocking claims, and TTL enforcement.
Features
-
Powered by
jsonwebtoken:- The library leverages the jsonwebtoken crate, a popular and robust JWT library in Rust.
- Provides support for industry-standard algorithms (
RS256,HS256, and more).
-
KID Rotation:
- Supports Key ID (KID) rotation, allowing seamless switching between keys without disrupting existing tokens.
- Keys are managed via
KeyStore, where each key pair can be registered with a uniquekid.
-
Custom Validation Rules:
- Claim Blocking: Reject tokens containing specific blocked values.
- Claim Matching: Ensure claims match predefined expected values.
- TTL Enforcement: Enforce a time-to-live (TTL) for tokens.
-
Exception Handling:
- Provides detailed Python exceptions for better catching.
-
High Performance:
- Faster token generation and validation compared to PyJWT.
Installation
-
Clone the repository:
git clone <repository-url> cd <repository-directory>
-
Install dependencies:
pip install maturin
-
Build and install the Python package:
maturin develop -
Verify installation:
python -c "import key_manager; print('Installed successfully!')"
Quick Start
Example Usage
import time
from datetime import datetime, timedelta, timezone
from key_manager import KeyManager, KeyStore, TokenValidation, BlockedKeyError, MissingMatchClaimError, ExpiredToken
# Load keys
private_key_path = "path/to/private_key.pem"
public_key_path = "path/to/public_key.pem"
# Prepare claims
exp = datetime.now(timezone.utc) + timedelta(hours=1)
claims = {
"sub": "user123",
"custom_claim": "example_value",
"exp": int(exp.timestamp()),
"iat": int(time.time()),
}
# Initialize KeyStore and KeyManager
key_store = KeyStore()
key_store.load_keys("default", private_key_path, public_key_path, "RS256", is_default=True)
key_manager = KeyManager(key_store)
# Generate a token
token = key_manager.generate_token_by_kid("default", claims)
print("Generated Token:", token)
# Validate the token with custom rules
validation = TokenValidation()
validation.claims = {"custom_claim": "example_value"} # Require exact match
validation.block = {"is_admin": ["False"]} # Block if "is_admin" is False
validation.ttl = 60 # Enforce TTL of 60 seconds
try:
decoded = key_manager.verify_token_by_kid(token, "default", validation)
print("Token is valid. Decoded claims:", decoded)
except BlockedKeyError as e:
print("BlockedKeyError:", e)
except MissingMatchClaimError as e:
print("MissingMatchClaimError:", e)
except ExpiredToken as e:
print("ExpiredToken:", e)
except Exception as e:
print("Validation failed:", e)
Key Rotation
Key rotation is seamlessly supported:
- Register multiple keys using
KeyStore.register_keys()orKeyStore.load_keys()methods. - Assign a unique
kidto each key. - Specify the desired
kidduring token generation and validation.
Benchmarking
The provided test script compares the performance of this library against PyJWT.
Run Benchmark
python benchmark.py
Expected Output
Benchmarking PyJWT vs Rust-based RSA JWT
PyJWT:
Generation time: 0.001234 seconds
Validation time: 0.001567 seconds
Rust-based RSA JWT:
Generation time: 0.000789 seconds
Validation time: 0.000923 seconds
Performance Comparison:
Token generation: Rust is 1.56x faster than PyJWT
Token validation: Rust is 1.70x faster than PyJWT
Exception Types
| Exception Name | Description |
|---|---|
BlockedKeyError |
Raised when a token contains blocked claim values. |
MissingMatchClaimError |
Raised when a claim value doesn't match the expected value. |
ExpiredToken |
Raised when the token exceeds the enforced TTL. |
InvalidTokenError |
Raised for general invalid token errors. |
ExpiredSignatureError |
Raised when the token has expired. |
DecodeError |
Raised for decoding errors. |
Testing
Save the provided Python script as benchmark.py and update paths for your key files.
Let me know if further updates are needed!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jwk_key_manager-0.1.10.tar.gz.
File metadata
- Download URL: jwk_key_manager-0.1.10.tar.gz
- Upload date:
- Size: 32.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e5eeb6e714b376e8f1ef3d01860e20630a67ff633844b743c49832b417f78ac
|
|
| MD5 |
9fc9c44108d4b6d3bf7a63f0f486c057
|
|
| BLAKE2b-256 |
791ddde25a68f75633ab0c17cc29a7e1f3a71676bdf04468326b40fc78c80a50
|
File details
Details for the file jwk_key_manager-0.1.10-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: jwk_key_manager-0.1.10-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 999.4 kB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
468e6cc44c2bcddb08df253513e3dc406e54969bce82ff622a098b154f5ecea4
|
|
| MD5 |
78f502bb89775bfae14bf91f7c36dfdb
|
|
| BLAKE2b-256 |
b165875ac44c3c1e4e37f482780c64bd59600ad20c90ebb155f831afeac1b3fb
|
File details
Details for the file jwk_key_manager-0.1.10-cp311-cp311-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: jwk_key_manager-0.1.10-cp311-cp311-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 977.0 kB
- Tags: CPython 3.11, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ed48f6c7db403af95fa9ebc8e7fa13b105763e3ca7638049a6a72f4057d1222
|
|
| MD5 |
255869df54dad5ced54dd6b66e0edb25
|
|
| BLAKE2b-256 |
a799604af8bc558d0a8f327c8dd88d2f872c2b6653ec1c214e5ff12bcc039905
|