Skip to main content

A minimal, spec-first, framework-agnostic, async-only JWT validator with zero network dependencies.

Project description

async-jwt-core

A minimal, spec-first, framework-agnostic, async-only JWT validator with zero network dependencies.

PyPI version License: MIT


🚀 Why async-jwt-core? (The Problem We Solve)

In the modern Python async ecosystem, validating JWTs using JSON Web Key Sets (JWKS) usually forces you into one of two bad situations:

  1. Framework Lock-in: Libraries tied directly to FastAPI, Starlette, or Django.
  2. Opinionated I/O: Libraries that insist on making network calls for you (often using specific HTTP clients) to fetch keys.

async-jwt-core solves this by doing exactly one thing perfectly: Pure Cryptographic Validation without I/O.

We provide the core validation logic. You bring the keys. This gives you absolute control over how keys are fetched, cached, and stored, while ensuring your event loop never blocks.


💡 Core Examples: Why You Should Use It

1. The Direct Approach (FastAPI Dependency)

Validate a token in FastAPI without letting the JWT library block your event loop with hidden network calls.

from fastapi import FastAPI, Depends, HTTPException, Request
from async_jwt_core import Validator, ValidationError

app = FastAPI()
validator = Validator(algorithms=["RS256"])

@app.get("/protected")
async def protected_route(request: Request):
    try:
        # Extract token from request headers
        token = Validator.extract_token(request)
        
        # YOU fetch the keys (e.g., from Redis). No hidden I/O!
        jwks = await my_custom_key_fetcher() 
        
        # Validate!
        claims = await validator.validate(token, jwks)
        return {"message": f"Welcome {claims.sub}!"}
        
    except ValidationError as e:
        raise HTTPException(status_code=401, detail=str(e))

2. The Middleware Approach (FastAPI)

Just like you add CORSMiddleware, you can add our FastAPIMiddleware to protect all routes automatically!

from fastapi import FastAPI
from async_jwt_core import Validator
from async_jwt_core.middleware import FastAPIMiddleware

app = FastAPI()

# 1. Initialize validator (Uses ASYNC_JWT_ISSUER from ENV)
validator = Validator(algorithms=["RS256"])

# 2. Add middleware just like CORSMiddleware!
app.add_middleware(
    FastAPIMiddleware,
    validator=validator,
    jwks={"keys": [...]} # Pass your JWKS here
)

@app.get("/protected")
async def protected_route(request: Request):
    # Claims are automatically attached to request.state!
    claims = request.state.user_claims
    return {"message": f"Hello {claims.sub}"}

✨ Key Features

  • 🔒 Zero Network I/O – Keys are fetched externally.
  • Async-Only API – Designed from the ground up for asyncio.
  • 🧩 Framework Agnostic – Works with FastAPI, Sanic, aiohttp, Flask, or Django.
  • 🎯 Custom Claim Validation – Pass your own validation functions.
  • 📦 Ultra Lightweight – Only depends on cryptography.

🔐 Supported Algorithms

We support a vast range of modern cryptographic algorithms out of the box (12 total):

Type Algorithms
HMAC (Symmetric) HS256, HS384, HS512
RSA (Asymmetric) RS256, RS384, RS512
RSA-PSS (Asymmetric) PS256, PS384, PS512
ECDSA (Elliptic Curve) ES256, ES384, ES512

🌟 Extra Features to Help You (35+ Features Total)

1. Built-in Framework Middlewares

We now include ready-to-use middlewares for popular frameworks: FastAPIMiddleware, FlaskMiddleware, and DjangoMiddleware.

2. Unique Environment Variable Configuration

We use unique, non-conflicting environment variables to load defaults: ASYNC_JWT_ALGORITHMS, ASYNC_JWT_ISSUER, ASYNC_JWT_AUDIENCE.

3. Token Creation (Signing)

We are no longer just a validator! You can now create and sign tokens easily using Encoder.create_token().

📖 Examples (References for Users)

We provide full working examples in the GitHub repository:

🛠️ Installation

uv add async-jwt-core

📄 License

MIT

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

async_jwt_core-0.2.5.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

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

async_jwt_core-0.2.5-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file async_jwt_core-0.2.5.tar.gz.

File metadata

  • Download URL: async_jwt_core-0.2.5.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for async_jwt_core-0.2.5.tar.gz
Algorithm Hash digest
SHA256 0422a0e581105a80467944ca4cc40574119dbfe4760ffc024f96d8583fc884ca
MD5 00690062ad00b135275b37a04fb94d8f
BLAKE2b-256 c0aea855b6bacbde52b0e11819f397150058670ab2fd7efa1bfa64c0e665a89d

See more details on using hashes here.

File details

Details for the file async_jwt_core-0.2.5-py3-none-any.whl.

File metadata

  • Download URL: async_jwt_core-0.2.5-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for async_jwt_core-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c4ac84cdea711e4c15f22511ce282efaf6ef0f58bcbe4c2d3707c3c8d7dbc24a
MD5 1b9814c22a0669ce27681504a9a0a575
BLAKE2b-256 3082df534c7635259ecf5c6adc5348cebb07aee42cb494cdbe79aad28707dbde

See more details on using hashes here.

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