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. It exposes a familiar PyJWT-like API while keeping verification explicit: decoding always requires a caller-provided algorithms allow-list.

This project is currently alpha software.

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, 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.

🚀 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 Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

oxyjwt-0.1.0-cp310-abi3-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

oxyjwt-0.1.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.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (779.0 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.10+macOS 11.0+ ARM64

oxyjwt-0.1.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.1.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: oxyjwt-0.1.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.1 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.1.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 df50b29fbfba956e1e0bf250ada1e94e979c2c0c61f0821d3ede562859052849
MD5 ae699c32c71c49e18597117d6b665a86
BLAKE2b-256 0be7fed138685be0d17f114b52c98eb983196c474961aea357a5e696ebf03b85

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.1.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.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 921ba05fa86552925d7512d93d0e8ad6894e0c36a2c57b66dd033da48484c0d1
MD5 68af8f5e5775e6bd7996e2c80e90cdb8
BLAKE2b-256 f9dfa8b83a22f27f4e50fab5b5b6b3c4e8c8ce00aa6136d953b5a3b60d034d5d

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.1.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.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 71a2706cc5a33d51efff6af9f9e13e17f512192ef26c470bdc81aed184f70509
MD5 422112a0ea0438d284a5a0ec9b3dc788
BLAKE2b-256 5e8cc7c3a8300447db3d623b6beb068beb959c8b8c164163b788d342ee31f30e

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.1.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.1.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9198fbeea8c67a47cc52356be7240258160a6e835b4ee0947d78163801de8437
MD5 5242e75223102d60e8bf72f6d83ce2d7
BLAKE2b-256 e6b7dda6e33e9f78c41f517b5bd2bad4237deaf921ab9288b289c582fe4ef43c

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.1.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.1.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for oxyjwt-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 27a6cc16a3eb7d714a6b69c499e5c0778245f6114bdb1ea1cbda62aa8d4cb2a7
MD5 49ba8d0ff11f88adf8af48dcfff4a2bb
BLAKE2b-256 d59f9fa34ca2a5bfe482bbb15b07d1bbce882734e64b1d2d107c4251b6121f77

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyjwt-0.1.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