Skip to main content

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 beta software on the 0.3.x line; see the changelog for 0.2.0 breaking changes (exception hierarchy) and 0.3.0 notes.

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 static site is served on http://127.0.0.1:8001 by default. Point your own reverse proxy at that upstream for HTTPS. Details and OXYJWT_DOCS_PORT are in docs-site/README.md.

Installation

pip install oxyjwt

Requires Python 3.10+. The wheel installs orjson as a runtime dependency (JSON serialization in the Python API layer).

For local development:

python -m venv .venv
.venv/bin/python -m pip install -U pip maturin pytest pytest-cov cryptography pyjwt
.venv/bin/maturin develop --release
.venv/bin/python -m pytest

See RELEASING.md for maintainer release steps.

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, HS512
  • RS256, RS384, RS512
  • PS256, PS384, PS512
  • ES256, ES384
  • EdDSA

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 algorithms list to decode.
  • Never build the algorithms list from untrusted token headers.
  • alg="none" is intentionally unsupported.
  • Raw str/bytes keys are accepted only for HMAC algorithms. Use EncodingKey.from_* and DecodingKey.from_* for RSA, PSS, ECDSA, and EdDSA.
  • Validate audience and issuer for application tokens when those claims are part of your trust model.
  • decode_unverified and get_unverified_header do 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.

Contributing and security

See CONTRIBUTING.md for development setup and pull request expectations. Report security issues privately via SECURITY.md.

🚀 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oxyjwt-0.3.0.tar.gz (24.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

oxyjwt-0.3.0-cp310-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (791.1 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

oxyjwt-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (1.4 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

oxyjwt-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file oxyjwt-0.3.0.tar.gz.

File metadata

  • Download URL: oxyjwt-0.3.0.tar.gz
  • Upload date:
  • Size: 24.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oxyjwt-0.3.0.tar.gz
Algorithm Hash digest
SHA256 c9539052b2a7264dea860d23af9511951f0af68f44dc1ad2a5755127278e9257
MD5 f7a4cddb7a55d72527653483f2491281
BLAKE2b-256 351971e72b9025a5a91fb64f6a5c7df08a3bd9750a92d546f9631a3936e310c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0.tar.gz:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyjwt-0.3.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: oxyjwt-0.3.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

Hashes for oxyjwt-0.3.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7578662fb4e240f916a18f6440154e7b5beb9dc782134069f29bd08cb2a04979
MD5 701c90aefc492806afe9bf4fc8dbe7c6
BLAKE2b-256 c3a5d8fada82808954afbd3143cd76d6815555eefc8f0b0edf04a828c41dbdbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 61d90d5864d58b7c262bf0b4d5239348e62e49451f9bc32e0e5f1b4d16edb0c4
MD5 41111adaf4ec95aa310dd33f11852196
BLAKE2b-256 8719e3a98f31aa64ff3492b4649f7c417ee146fca038a0a2ba0351e6f119b49b

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ad736a21932af378e6823ff656ee7d0f34868ca16d36881cfe81e78bf8612b5d
MD5 e97bc175eda7a2bfd6a9a91450b56369
BLAKE2b-256 d517b8e2ad5b6a7d43d77f26fe202adfa85c838f479a433e02a675b31c103034

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyjwt-0.3.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d6064531a22c3c6e282e24621694eb272fbf86c66e4edf25ffc8b42b4f7ebe61
MD5 ceefd0804d23ca78bff1d32a4a59b9f2
BLAKE2b-256 c117083fd6b443d527ca7401b83ec9bb34eca1f231047a33bc7d11029e012928

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyjwt-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 881a0d02713f0adfa48b99e54bda4e7c47fc4f145d512e613ead5a57965f8210
MD5 73f1f3d9a79b1f9253d668ff46eca769
BLAKE2b-256 2b98771ee21e2f0dba61a1681aeebeb790371a547cdd6bf2c8d046e9c6be5c00

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on QueryaHub/OxyJWT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page