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

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762695419.tar.gz
Algorithm Hash digest
SHA256 158b7e0ed9cc97a38c3b40da4bdfe59e532075ba6dc62a17b813d2057e0ed4d9
MD5 200a49a2b9e012be697b9571678298c0
BLAKE2b-256 df7c4759428cb70a8fa83196a74371d276b9d6c61014911d54386a82b310e414

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for axioms_fastapi-0.0.1rc11762695419-py3-none-any.whl
Algorithm Hash digest
SHA256 466bb26b627c128ede28ee1d74e116660d39607551e865da702df2c13fb51f0d
MD5 0ad8953c0c87d0f534396dcb51abf528
BLAKE2b-256 7a505eb82d816b63bb840c4247098e8c6f36bb8a083e369a413d77a3b058523a

See more details on using hashes here.

Provenance

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