A Python JWT library powered by a Rust core.
Project description
OxyJWT
OxyJWT is a Python JWT/JWS library backed by a Rust core. The public API follows PyJWT for encode, decode, decode_complete, JWK/JWKS helpers, and the PyJWKClient. When signature verification is enabled (the default), you must pass an algorithms allow-list, matching common PyJWT usage. Unverified decode is available only when you explicitly set options["verify_signature"] to False (treat the payload as untrusted).
This project is still alpha software; see the changelog for 0.2.0 breaking changes (exception hierarchy).
Documentation
The full documentation is written with MkDocs and lives in docs-site/ as a standalone site:
Build it locally with:
python -m venv .venv
.venv/bin/python -m pip install -U -r docs-site/requirements.txt
.venv/bin/mkdocs serve -f docs-site/mkdocs.yml
Or build a static documentation image for deployment:
docker compose -f docs-site/docker-compose.yml up -d --build
The documentation will be available at http://localhost:8001. Override the host port with OXYJWT_DOCS_PORT=8002.
For production on https://oxyjwt.queryahub.com, use the Caddy-based stack in docs-site/:
cd docs-site
cp .env.example .env
docker compose -f docker-compose.prod.yml --env-file .env up -d --build
If Compose fails because port 80 (or 443) is already in use, see Production / troubleshooting in docs-site/README.md.
Installation
pip install oxyjwt
For local development:
python -m venv .venv
.venv/bin/python -m pip install -U pip maturin pytest cryptography pyjwt
.venv/bin/maturin develop --release
.venv/bin/python -m pytest
HMAC Example
import time
import oxyjwt
secret = "super-secret"
payload = {
"sub": "user-123",
"role": "admin",
"aud": "api",
"iss": "auth-service",
"exp": int(time.time()) + 3600,
}
token = oxyjwt.encode(payload, secret, algorithm="HS256", headers={"kid": "key-1"})
claims = oxyjwt.decode(
token,
secret,
algorithms=["HS256"],
audience="api",
issuer="auth-service",
)
Asymmetric Keys
Use explicit key constructors for RSA, PSS, ECDSA, and EdDSA:
import oxyjwt
signing_key = oxyjwt.EncodingKey.from_rsa_pem(private_pem)
verification_key = oxyjwt.DecodingKey.from_rsa_pem(public_pem)
token = oxyjwt.encode({"sub": "user-123", "exp": 1893456000}, signing_key, algorithm="RS256")
claims = oxyjwt.decode(token, verification_key, algorithms=["RS256"])
Supported algorithms in v1:
HS256,HS384,HS512RS256,RS384,RS512PS256,PS384,PS512ES256,ES384EdDSA
Exceptions
OxyJWT exposes a stable exception hierarchy:
try:
claims = oxyjwt.decode(token, key, algorithms=["HS256"])
except oxyjwt.ExpiredSignatureError:
...
except oxyjwt.InvalidTokenError:
...
All package exceptions inherit from oxyjwt.OxyJWTError.
Benchmarks
There is a small comparison script for OxyJWT, PyJWT, python-jose, and Authlib:
python -m venv .venv
.venv/bin/python -m pip install -U pip maturin ".[bench]"
.venv/bin/maturin develop --release
.venv/bin/python scripts/compare_jwt_libraries.py \
--algorithms all \
--iterations 1000 \
--rounds 3 \
--warmup 100 \
--json benchmark-results/all-algorithms.bench.json \
--markdown benchmark-results/all-algorithms.bench.md
The script covers HMAC, RSA, RSA-PSS, ECDSA, and EdDSA algorithms. Unsupported library/algorithm combinations are reported as 0 throughput. For a quicker smoke test, pass something like --algorithms HS256,RS256,EdDSA --iterations 100 --rounds 1.
Benchmark outputs are ignored by git because results depend on the machine, Python version, compiler flags, and CPU state.
The default Rust crypto backend is aws_lc_rs, chosen for stronger performance on RSA and ECDSA in local benchmarks. You can still build with rust_crypto for comparison:
PYO3_BUILD_EXTENSION_MODULE=1 maturin build --release --no-default-features --features rust_crypto
Security Notes
- Always pass a fixed server-side
algorithmslist todecode. - Never build the
algorithmslist from untrusted token headers. alg="none"is intentionally unsupported.- Raw
str/byteskeys are accepted only for HMAC algorithms. UseEncodingKey.from_*andDecodingKey.from_*for RSA, PSS, ECDSA, and EdDSA. - Validate
audienceandissuerfor application tokens when those claims are part of your trust model. decode_unverifiedandget_unverified_headerdo not authenticate a token. Use them only for inspection/debugging flows, never for authorization.
OxyJWT implements JWT/JWS signing and verification. JWE encryption is not part of the first version.
🚀 Performance Benchmarks
OxyJWT is built for absolute speed. By bypassing the Python GIL and leveraging Rust's cryptographic primitives, it completely destroys standard Python libraries in both symmetric and asymmetric cryptography.
Below is a performance comparison measured in Operations per second (ops/sec) (higher is better):
| Algorithm | Operation | ⚡ OxyJWT | PyJWT | Authlib | python-jose |
|---|---|---|---|---|---|
| HS256 | Encode | 620,270 | 140,670 | 99,408 | 99,507 |
| HS256 | Decode | 361,073 | 109,272 | 94,823 | 51,838 |
| RS256 | Encode | 1,934 | 35 | 35 | 35 |
| RS256 | Decode | 58,752 | 27,200 | 26,085 | 23,046 |
| EdDSA | Encode | 69,105 | 17,518 | 15,014 | N/A |
| EdDSA | Decode | 31,666 | 10,741 | 10,317 | N/A |
| ES256 | Encode | 46,559 | 19,632 | 16,199 | 19,723 |
Tested against standard Python ecosystem libraries. OxyJWT consistently dominates across all algorithms.
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 oxyjwt-0.2.0.tar.gz.
File metadata
- Download URL: oxyjwt-0.2.0.tar.gz
- Upload date:
- Size: 24.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
649bc62a44bc324fe19937474d9d60069ebfe9af5edf1e4a280f9a252dd001ab
|
|
| MD5 |
93d897dd863543d7abceb7d8f42e43cf
|
|
| BLAKE2b-256 |
2bb7236a87d014d3a7bdf672c2d707b5449cd89f96025d246cc6cf931a52e89a
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0.tar.gz:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0.tar.gz -
Subject digest:
649bc62a44bc324fe19937474d9d60069ebfe9af5edf1e4a280f9a252dd001ab - Sigstore transparency entry: 1388336537
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oxyjwt-0.2.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: oxyjwt-0.2.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
791767a6d94c58280193ec7935b07f9c368fd859b17230f280b9179a66fd30ff
|
|
| MD5 |
51448a1775c014854faa0871ac940a7a
|
|
| BLAKE2b-256 |
69c15d26a2ab75cf7c840a8cffc5de964543d593e9294989c0a19bea9ac7816d
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0-cp310-abi3-win_amd64.whl -
Subject digest:
791767a6d94c58280193ec7935b07f9c368fd859b17230f280b9179a66fd30ff - Sigstore transparency entry: 1388337127
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b58e987492b68a18b1640abbb3ac4a2d232c6f8cf9fb4046d928a9b7ec95db3b
|
|
| MD5 |
9abf78d220ded4927111a2adc81e382a
|
|
| BLAKE2b-256 |
4a14b26db05c2b1b824c17b24e21cae7beb5df32b4a63cc1dda49bc020caaff0
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
b58e987492b68a18b1640abbb3ac4a2d232c6f8cf9fb4046d928a9b7ec95db3b - Sigstore transparency entry: 1388336797
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 790.6 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4baafb218b3e740983bb3fb597e8f57be8f4a5ec8afe796b4b8e6f3db6d37ded
|
|
| MD5 |
896db180e8ba41ce76e1f836f2173018
|
|
| BLAKE2b-256 |
f02dab847b81dcf4ed4a553a24b244822ad0c01500449489fad2643128097b52
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
4baafb218b3e740983bb3fb597e8f57be8f4a5ec8afe796b4b8e6f3db6d37ded - Sigstore transparency entry: 1388337022
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oxyjwt-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: oxyjwt-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c19dd0dd1e7ab69539f3786e8e9ed3b93303e3cc3b70076adb989b86052979f
|
|
| MD5 |
b9a702c39184dddbb912ad4df7646c2d
|
|
| BLAKE2b-256 |
97558260ce13707ec152d44e95066a9f58cc611b909b09dc088153d1c792480c
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
0c19dd0dd1e7ab69539f3786e8e9ed3b93303e3cc3b70076adb989b86052979f - Sigstore transparency entry: 1388336680
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oxyjwt-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: oxyjwt-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27c5099416c5803ad54798e4e8ce05e0e11a1b639258d365bbe2a8969da50976
|
|
| MD5 |
ef6639227b01683c9ef253b2e8fba8ef
|
|
| BLAKE2b-256 |
29b494102d3f63b03e50b82ddff85f0d76f93d88cb2d3e09946ba8768286a84b
|
Provenance
The following attestation bundles were made for oxyjwt-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on QueryaHub/OxyJWT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyjwt-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
27c5099416c5803ad54798e4e8ce05e0e11a1b639258d365bbe2a8969da50976 - Sigstore transparency entry: 1388336911
- Sigstore integration time:
-
Permalink:
QueryaHub/OxyJWT@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QueryaHub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1892dcb1c8aaf96d2770c67a20154e7315c82561 -
Trigger Event:
push
-
Statement type: