QuantumAuth - Next-generation authentication and authorization protocol with post-quantum security
Project description
QAuth - Post-Quantum Authentication for Python
Next-generation authentication protocol designed to replace OAuth 2.0 and JWT with post-quantum security.
Installation
# Using pip
pip install qauth
# Using pip3
pip3 install qauth
# Using pipx (for CLI tools)
pipx install qauth
# Using poetry
poetry add qauth
# Using pdm
pdm add qauth
# Using uv
uv pip install qauth
Quick Start
from qauth import QAuthServer, QAuthClient, PolicyEngine
# Create a server instance
server = QAuthServer(
issuer="https://auth.example.com",
audience="https://api.example.com"
)
# Create an access token
token = server.create_token(
subject="user-123",
policy_ref="urn:qauth:policy:default",
validity_seconds=3600,
claims={
"email": "user@example.com",
"roles": ["user", "premium"],
},
)
# Validate a token
payload = server.validate_token(token)
print(f"Subject: {payload.sub.decode()}")
print(f"Expires: {payload.exp}")
Client-Side Usage
from qauth import QAuthClient
# Create a client instance (generates a new keypair)
client = QAuthClient()
# Get the client's public key (send to server during auth)
public_key = client.public_key
# Create proof of possession for API requests
proof = client.create_proof("GET", "/api/resource", token)
# Make API request with token and proof
import requests
response = requests.get(
"https://api.example.com/resource",
headers={
"Authorization": f"QAuth {token}",
"X-QAuth-Proof": proof,
},
)
Server-Side Validation
from qauth import QAuthValidator, ProofValidator
# Create a validator with pre-shared issuer keys
validator = QAuthValidator(
keys=issuer_keys,
issuer="https://auth.example.com",
audience="https://api.example.com",
)
# Validate token
try:
payload = validator.validate(token)
print(f"Token valid for user: {payload.sub}")
except Exception as e:
print(f"Token validation failed: {e}")
# Validate proof of possession
proof_validator = ProofValidator(client_public_key)
try:
proof_validator.validate(proof, "GET", "/api/resource", token)
print("Proof valid")
except Exception as e:
print(f"Proof validation failed: {e}")
Policy-Based Authorization
from qauth import PolicyEngine, Effect
engine = PolicyEngine()
# Load a policy
engine.load_policy({
"id": "urn:qauth:policy:api-access",
"version": "2026-01-30",
"issuer": "https://auth.example.com",
"rules": [
{
"id": "read-projects",
"effect": "allow",
"resources": ["projects/*"],
"actions": ["read", "list"],
},
{
"id": "admin-only",
"effect": "allow",
"resources": ["admin/**"],
"actions": ["*"],
"conditions": {
"custom": {
"role": {"in": ["admin"]},
},
},
},
],
})
# Evaluate authorization
result = engine.evaluate(
"urn:qauth:policy:api-access",
{
"subject": {
"id": "user-123",
"attributes": {"role": "user"},
},
"resource": {
"path": "projects/456",
},
"request": {
"action": "read",
},
},
)
if result.effect == Effect.ALLOW:
print("Access granted")
else:
print(f"Access denied: {result.reason}")
FastAPI Integration
from fastapi import FastAPI, Depends, HTTPException, Header
from qauth import QAuthValidator, ProofValidator, IssuerKeys
app = FastAPI()
# Configure validator
validator = QAuthValidator(
keys=issuer_keys,
issuer="https://auth.example.com",
audience="https://api.example.com",
)
async def verify_qauth(
authorization: str = Header(...),
x_qauth_proof: str = Header(...),
):
if not authorization.startswith("QAuth "):
raise HTTPException(401, "Invalid authorization header")
token = authorization[6:]
try:
payload = validator.validate(token)
except Exception as e:
raise HTTPException(401, f"Invalid token: {e}")
# In production, also verify the proof
return payload
@app.get("/api/resource")
async def get_resource(payload = Depends(verify_qauth)):
return {"user": payload.sub.decode()}
API Reference
QAuthServer
Server-side class for token creation and validation.
server = QAuthServer(issuer: str, audience: str)
# Get public keys for sharing with validators
keys = server.get_public_keys() -> IssuerKeys
# Create a token
token = server.create_token(
subject: str | bytes,
policy_ref: str,
audience: str | list[str] | None = None,
validity_seconds: int = 3600,
client_key: bytes | None = None,
device_key: bytes | None = None,
claims: dict[str, Any] | None = None,
) -> str
# Validate a token
payload = server.validate_token(token: str) -> TokenPayload
QAuthClient
Client-side class for proof of possession.
client = QAuthClient()
# Get client's public key
public_key = client.public_key -> bytes
# Create proof for API request
proof = client.create_proof(
method: str,
uri: str,
token: str,
body: bytes | None = None,
) -> str
PolicyEngine
Evaluate authorization policies.
engine = PolicyEngine()
# Load a policy
engine.load_policy(policy: dict[str, Any]) -> None
# Evaluate authorization
result = engine.evaluate(
policy_id: str,
context: dict[str, Any],
) -> EvaluationResult
Data Classes
@dataclass
class TokenPayload:
sub: bytes # Subject identifier
iss: str # Issuer
aud: list[str] # Audiences
exp: int # Expiration time
iat: int # Issued at
nbf: int # Not before
jti: bytes # Token ID
rid: bytes # Revocation ID
pol: str # Policy reference
ctx: bytes # Context hash
cst: dict # Custom claims
@dataclass
class EvaluationResult:
effect: Effect
matched_rule: str | None
reason: str
class Effect(Enum):
ALLOW = "allow"
DENY = "deny"
Requirements
- Python 3.9+
- cryptography >= 41.0.0
- pynacl >= 1.5.0
Why QAuth over JWT?
| JWT/OAuth Problem | QAuth Solution |
|---|---|
| Algorithm confusion attacks | Server-enforced, no client selection |
| Bearer tokens can be stolen | Proof-of-possession mandatory |
| No built-in revocation | Instant revocation system |
| Payload visible (base64) | Encrypted with XChaCha20-Poly1305 |
| Single signature | Dual: Ed25519 + ML-DSA-65 |
| No post-quantum security | ML-DSA-65 (NIST FIPS 204) |
Related Packages
- Rust:
cargo add qauth - TypeScript/Node.js:
npm install @qauth/sdk - Go:
go get github.com/tushar-agrawal/qauth
License
MIT License - LICENSE
Author
Tushar Agrawal - tusharagrawal.in
Links
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 Distribution
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 qauth-0.1.0.tar.gz.
File metadata
- Download URL: qauth-0.1.0.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
073dcb9b68754d80fefb31def85a39f40dc4bfb23056e30bcf50080d15495138
|
|
| MD5 |
678fdb588cac350922a9571371d1364a
|
|
| BLAKE2b-256 |
972d31399e679df8b0836b924e03ac54d8bc145554662f74cd36df7ebd216307
|
Provenance
The following attestation bundles were made for qauth-0.1.0.tar.gz:
Publisher:
qauth-ci.yml on Tushar010402/Tushar-Agrawal-Website
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qauth-0.1.0.tar.gz -
Subject digest:
073dcb9b68754d80fefb31def85a39f40dc4bfb23056e30bcf50080d15495138 - Sigstore transparency entry: 872426700
- Sigstore integration time:
-
Permalink:
Tushar010402/Tushar-Agrawal-Website@3dc941eb5f3af30a6582b920809ff11ccdbd05fc -
Branch / Tag:
refs/tags/qauth-v0.1.0 - Owner: https://github.com/Tushar010402
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
qauth-ci.yml@3dc941eb5f3af30a6582b920809ff11ccdbd05fc -
Trigger Event:
release
-
Statement type:
File details
Details for the file qauth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: qauth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b370c4c30d2ee1c0b0c0bc7b6ce29b9c219ec56dc494b472cf0a8f7053e7e6f3
|
|
| MD5 |
78a21af0e0243b8e901c7e35f576e058
|
|
| BLAKE2b-256 |
e9bc694a90f1fd736a5b878f8441a706fe0b2c57dbc3f3e8a7d4586573323df1
|
Provenance
The following attestation bundles were made for qauth-0.1.0-py3-none-any.whl:
Publisher:
qauth-ci.yml on Tushar010402/Tushar-Agrawal-Website
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qauth-0.1.0-py3-none-any.whl -
Subject digest:
b370c4c30d2ee1c0b0c0bc7b6ce29b9c219ec56dc494b472cf0a8f7053e7e6f3 - Sigstore transparency entry: 872426702
- Sigstore integration time:
-
Permalink:
Tushar010402/Tushar-Agrawal-Website@3dc941eb5f3af30a6582b920809ff11ccdbd05fc -
Branch / Tag:
refs/tags/qauth-v0.1.0 - Owner: https://github.com/Tushar010402
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
qauth-ci.yml@3dc941eb5f3af30a6582b920809ff11ccdbd05fc -
Trigger Event:
release
-
Statement type: