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.1rc11762698864.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.1rc11762698864-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762698864.tar.gz
Algorithm Hash digest
SHA256 807df3337f7e8d981ee62239fc3724dd73c138a55c13282d4147982e1ac6d59f
MD5 86a8444999a2c595eb692cb3e93e0104
BLAKE2b-256 b9fd715b5231bd2020b6b6892308b706e67376b575d0cd6f0771e18469d36457

See more details on using hashes here.

Provenance

The following attestation bundles were made for axioms_fastapi-0.0.1rc11762698864.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.1rc11762698864-py3-none-any.whl.

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762698864-py3-none-any.whl
Algorithm Hash digest
SHA256 07c736df6acb5da2cc782eb7bfcc68ad9fa1a829a8fecfdef4da8c08bc698dd2
MD5 4958ded4ddb6b261d5c168003a028e9e
BLAKE2b-256 ae1a2946387311718c88b10a7f0e692103a74d6a116ebbe9717aff16cc694587

See more details on using hashes here.

Provenance

The following attestation bundles were made for axioms_fastapi-0.0.1rc11762698864-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