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

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762699396.tar.gz
Algorithm Hash digest
SHA256 d0945a1b76dda4224ff3c9c3eb1ab7fc1f08099f514f5ddff6bdfbc21a6031ee
MD5 53893328493fe9a1fce7a8b3f19a565d
BLAKE2b-256 fd4d8545e220fd44ca0e5b3844c19906e8b1e7d6df2f2ec80a90c6de36633125

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762699396-py3-none-any.whl
Algorithm Hash digest
SHA256 5a9cde744aa365fc385ae29cc1138a1e6bd320ff4c26a3cac0d90c8fa6eb3c53
MD5 862efba40055e40027cbe37d125ca6b9
BLAKE2b-256 1f087a3b35ed0019ae6ddec3b4a3651821a696e873c9971e7a9e457504d1c468

See more details on using hashes here.

Provenance

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