Skip to main content

AuthAction JWT verification SDK for Python — Django, Flask, and FastAPI

Project description

authaction-python-sdk

JWT verification SDK for Python backends. Validates AuthAction access tokens via JWKS — handles key fetching, caching, and rotation automatically.

Works with Django REST Framework, Flask, and FastAPI.

Installation

# Core only
pip install authaction-python-sdk

# With Django support
pip install "authaction-python-sdk[django]"

# With Flask support
pip install "authaction-python-sdk[flask]"

# With FastAPI support
pip install "authaction-python-sdk[fastapi]"

Core

from authaction import AuthAction

aa = AuthAction(
    domain=os.getenv("AUTHACTION_DOMAIN"),    # e.g. myapp.eu.authaction.com
    audience=os.getenv("AUTHACTION_AUDIENCE"), # e.g. https://api.myapp.com
)

# Verify a raw token — raises TokenExpiredError / TokenInvalidError on failure
payload = aa.verify_token(token)

# Verify from Authorization header — returns None on missing/invalid, never raises
payload = aa.verify_request(request.headers.get("Authorization"))

print(payload["sub"])   # user identifier
print(payload["email"]) # any JWT claim

Django REST Framework

1. Configure settings

# settings.py
AUTHACTION = {
    "DOMAIN":   os.getenv("AUTHACTION_DOMAIN"),
    "AUDIENCE": os.getenv("AUTHACTION_AUDIENCE"),
}

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "authaction.django.AuthActionAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
}

2. Use in views

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response

@api_view(["GET"])
@permission_classes([AllowAny])
def public_view(request):
    return Response({"message": "Public"})

@api_view(["GET"])
def protected_view(request):
    return Response({"sub": request.user.sub, "email": request.user.email})

request.user is an AuthenticatedToken — access any JWT claim as an attribute:

request.user.sub        # str
request.user.email      # any claim
request.user.payload    # dict — all raw claims

Flask

from authaction import AuthAction
from authaction.flask import make_require_auth

aa = AuthAction(
    domain=os.getenv("AUTHACTION_DOMAIN"),
    audience=os.getenv("AUTHACTION_AUDIENCE"),
)
require_auth = make_require_auth(aa)

@app.get("/public")
def public_route():
    return {"message": "Public"}

@app.get("/protected")
@require_auth
def protected_route():
    from flask import g
    return {"sub": g.current_user["sub"]}

The decoded payload is available as g.current_user (a dict) inside decorated routes.


FastAPI

from fastapi import FastAPI, Depends
from authaction import AuthAction
from authaction.fastapi import make_require_auth

aa = AuthAction(
    domain=os.getenv("AUTHACTION_DOMAIN"),
    audience=os.getenv("AUTHACTION_AUDIENCE"),
)
require_auth = make_require_auth(aa)

app = FastAPI()

@app.get("/public")
def public_route():
    return {"message": "Public"}

@app.get("/protected")
def protected_route(user: dict = Depends(require_auth)):
    return {"sub": user["sub"], "email": user.get("email")}

Scope enforcement

require_admin = make_require_auth(aa, scopes=["admin"])

@app.delete("/users/{user_id}")
def delete_user(user_id: str, user: dict = Depends(require_admin)):
    ...  # raises HTTP 403 if token lacks 'admin' scope

Exceptions

from authaction.exceptions import TokenExpiredError, TokenInvalidError

try:
    payload = aa.verify_token(token)
except TokenExpiredError:
    # token exp claim is in the past
    ...
except TokenInvalidError:
    # bad signature, wrong issuer/audience, malformed JWT
    ...

Environment variables

AUTHACTION_DOMAIN=your-tenant.eu.authaction.com
AUTHACTION_AUDIENCE=https://api.your-app.com

How JWKS caching works

Uses PyJWT's PyJWKClient which:

  • Fetches public keys from https://<domain>/.well-known/jwks.json on first use
  • Caches up to 16 keys in-process (LRU, configurable via jwks_cache_keys)
  • Automatically re-fetches when an unknown kid is encountered (key rotation)

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

authaction_python_sdk-0.1.0.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

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

authaction_python_sdk-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file authaction_python_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: authaction_python_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for authaction_python_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 59fc9ad70fbd11f0c57a8a3c2e61c6893d504d13f664ba98162e9108d6dd7fe2
MD5 b1d2078620e511298dff90399e8d9d94
BLAKE2b-256 433541dbdc94b9171a7a6245ae3783d1ddeec3e0ec4e51abd502cffe1f106981

See more details on using hashes here.

File details

Details for the file authaction_python_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for authaction_python_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 296cacd6a2240a311d7b3b4a6f0f7150a1d3ef421c5c13a90f008d7d1b7a9a49
MD5 0ebc944f6579605050ae66000226d773
BLAKE2b-256 4c7840ca68ac093c07811a01bdd83ef571069f44b417e88db0eb8369014fa5ce

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