Skip to main content

OAuth2/OIDC authentication and authorization for FastAPI APIs

Project description

axioms-fastapi PyPI Pepy Total Downloads

OAuth2/OIDC authentication and authorization for FastAPI APIs. Supports authentication and claim-based fine-grained authorization (scopes, roles, permissions) using JWT tokens.

Works with access tokens issued by various authorization servers including AWS Cognito, Auth0, Okta, Microsoft Entra, etc.

GitHub Release GitHub Actions Test Workflow Status PyPI - Version Python Wheels Python Versions GitHub last commit PyPI - Status License PyPI Downloads

Features

  • JWT token validation with automatic public key retrieval from JWKS endpoints
  • Algorithm validation to prevent algorithm confusion attacks (only secure asymmetric algorithms allowed)
  • Issuer validation (iss claim) to prevent token substitution attacks
  • FastAPI dependency injection for authentication and authorization
  • Flexible configuration with support for custom JWKS and issuer URLs
  • Support for custom claim and/or namespaced claims names to support different authorization servers
  • Async-ready and production-tested

Installation

pip install axioms-fastapi

Quick Start

1. Configure your FastAPI application

from fastapi import FastAPI, Depends
from axioms_fastapi import init_axioms, require_auth, require_scopes

app = FastAPI()

# Initialize Axioms with your configuration
init_axioms(
    app,
    AXIOMS_AUDIENCE="your-api-audience",
    AXIOMS_DOMAIN="your-auth.domain.com"
)

2. Protect your routes

from axioms_fastapi import require_auth, require_permissions

@app.get("/api/protected")
async def protected_route(payload=Depends(require_auth)):
    """Route protected by JWT authentication."""
    user_id = payload.sub
    return {"user_id": user_id, "message": "Authenticated"}

@app.get("/api/admin")
async def admin_route(
    payload=Depends(require_auth),
    _=Depends(require_permissions(["admin:write"]))
):
    """Route requiring admin:write permission."""
    return {"message": "Admin access granted"}

Configuration

The SDK supports the following configuration options:

  • AXIOMS_AUDIENCE (required): Your resource identifier or API audience
  • AXIOMS_DOMAIN (optional): Your auth domain - constructs issuer and JWKS URLs
  • AXIOMS_ISS_URL (optional): Full issuer URL for validating the iss claim (recommended for security)
  • AXIOMS_JWKS_URL (optional): Full URL to your JWKS endpoint

Configuration Hierarchy:

  1. AXIOMS_DOMAIN → constructs → AXIOMS_ISS_URL (if not explicitly set)
  2. AXIOMS_ISS_URL → constructs → AXIOMS_JWKS_URL (if not explicitly set)

Environment Variables

Create a .env file:

AXIOMS_AUDIENCE=your-api-audience
AXIOMS_DOMAIN=your-auth.domain.com

# OR for custom configurations:
# AXIOMS_ISS_URL=https://your-auth.domain.com/oauth2
# AXIOMS_JWKS_URL=https://your-auth.domain.com/.well-known/jwks.json

Usage Examples

Basic Authentication

from fastapi import FastAPI, Depends
from axioms_fastapi import init_axioms, require_auth

app = FastAPI()
init_axioms(app, AXIOMS_AUDIENCE="api.example.com", AXIOMS_DOMAIN="auth.example.com")

@app.get("/profile")
async def get_profile(payload=Depends(require_auth)):
    return {
        "user_id": payload.sub,
        "email": payload.get("email"),
        "name": payload.get("name")
    }

Scope-Based Authorization (OR Logic)

from axioms_fastapi import require_auth, require_scopes

@app.get("/api/resource")
async def resource_route(
    payload=Depends(require_auth),
    _=Depends(require_scopes(["read:resource", "write:resource"]))
):
    # User needs EITHER 'read:resource' OR 'write:resource' scope
    return {"data": "success"}

Role-Based Authorization

from axioms_fastapi import require_auth, require_roles

@app.get("/admin/users")
async def admin_route(
    payload=Depends(require_auth),
    _=Depends(require_roles(["admin", "superuser"]))
):
    # User needs EITHER 'admin' OR 'superuser' role
    return {"users": []}

Permission-Based Authorization

from axioms_fastapi import require_auth, require_permissions

@app.post("/api/resource")
async def create_resource(
    payload=Depends(require_auth),
    _=Depends(require_permissions(["resource:create"]))
):
    return {"message": "Resource created"}

AND Logic (Chaining Dependencies)

@app.get("/api/strict")
async def strict_route(
    payload=Depends(require_auth),
    _=Depends(require_scopes(["read:resource"])),
    __=Depends(require_scopes(["write:resource"]))
):
    # User needs BOTH 'read:resource' AND 'write:resource' scopes
    return {"data": "requires both scopes"}

Mixed Authorization

@app.get("/api/advanced")
async def advanced_route(
    payload=Depends(require_auth),
    _=Depends(require_scopes(["openid", "profile"])),  # openid OR profile
    __=Depends(require_roles(["editor"])),              # AND editor role
    ___=Depends(require_permissions(["resource:read", "resource:write"]))  # AND read OR write
):
    # User needs: (openid OR profile) AND (editor) AND (read OR write)
    return {"data": "complex authorization"}

Custom Claim Names

Support for different authorization servers with custom claim names:

init_axioms(
    app,
    AXIOMS_AUDIENCE="api.example.com",
    AXIOMS_DOMAIN="auth.example.com",
    AXIOMS_ROLES_CLAIMS=["cognito:groups", "roles"],
    AXIOMS_PERMISSIONS_CLAIMS=["permissions", "cognito:roles"],
    AXIOMS_SCOPE_CLAIMS=["scope", "scp"]
)

Error Handling

The SDK raises AxiomsHTTPException for authentication and authorization errors:

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from axioms_fastapi import init_axioms, AxiomsHTTPException

app = FastAPI()
init_axioms(app, AXIOMS_AUDIENCE="api.example.com", AXIOMS_DOMAIN="auth.example.com")

@app.exception_handler(AxiomsHTTPException)
async def axioms_exception_handler(request: Request, exc: AxiomsHTTPException):
    return JSONResponse(
        status_code=exc.status_code,
        content=exc.detail,
        headers=exc.headers
    )

Security Features

  • Algorithm Validation: Only secure asymmetric algorithms allowed (RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512)
  • Issuer Validation: Validates iss claim to prevent token substitution attacks
  • Automatic JWKS Retrieval: Fetches and caches public keys from JWKS endpoints
  • Token Expiration: Validates exp claim
  • Audience Validation: Validates aud claim
  • Key ID Validation: Validates kid header

License

MIT

Links

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

axioms_fastapi-0.0.1rc11762698585.tar.gz (34.7 kB view details)

Uploaded Source

Built Distribution

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

axioms_fastapi-0.0.1rc11762698585-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file axioms_fastapi-0.0.1rc11762698585.tar.gz.

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762698585.tar.gz
Algorithm Hash digest
SHA256 c344ee13d624b5235304c60d8815eb1ca25c9c542c7929b6016dd80fb753f9c7
MD5 395e975439542736bc5b34afe3d72251
BLAKE2b-256 e030b35b5a5c54a9af4b48fff54b1edc2e44e544d7c6aeda350e5ae5d2392a4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for axioms_fastapi-0.0.1rc11762698585.tar.gz:

Publisher: release.yml on abhishektiwari/axioms-fastapi

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

File details

Details for the file axioms_fastapi-0.0.1rc11762698585-py3-none-any.whl.

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762698585-py3-none-any.whl
Algorithm Hash digest
SHA256 5b920479a74f1c75047d575abb081704b1c907dea5973ae0e613f5e4c01aa236
MD5 a8045e5b475cac495ad5eb51e8799722
BLAKE2b-256 076334fb4a37ea27125b56eb987fc7af45c855a18df039f13b9990651c93d89c

See more details on using hashes here.

Provenance

The following attestation bundles were made for axioms_fastapi-0.0.1rc11762698585-py3-none-any.whl:

Publisher: release.yml on abhishektiwari/axioms-fastapi

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