Skip to main content

Audit logging package for FastAPI applications

Project description

fastapi-audit

PyPI version Python versions License

Audit logging package for FastAPI applications.

Features

  • HTTP Request/Response Capture: Logs method, path, status code, response time, IP, and user agent
  • JWT-based Actor Identification: Extracts actor ID, type, and email from JWT tokens
  • ORM-level Diff Tracking: Captures INSERT, UPDATE, and DELETE operations across application sessions
  • Tenant-Aware Context Support: Works with application-provided tenant context
  • Sensitive Data Redaction: Automatically redacts passwords, tokens, secrets, and similar fields
  • Fire-and-Forget Writes: Writes audit records asynchronously to avoid adding request latency
  • Manual Audit Logging: Supports background tasks and non-HTTP contexts

Installation

From PyPI

# Core package (requires asyncpg for PostgreSQL)
pip install fastapi-audit[asyncpg]

Local Development

pip install -e /path/to/audit[asyncpg]

Database Driver

Only PostgreSQL with asyncpg is tested and supported at this time. Install it via the [asyncpg] extra:

pip install fastapi-audit[asyncpg]

Quick Start

from contextlib import asynccontextmanager
from sqlalchemy.ext.asyncio import create_async_engine

from fastapi import FastAPI
from fastapi_audit import AuditMiddleware, AuditConfig, create_tables

engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/audit_db")

@asynccontextmanager
async def lifespan(app: FastAPI):
    await create_tables(engine)
    yield
    await engine.dispose()

app = FastAPI(lifespan=lifespan)
app.add_middleware(
    AuditMiddleware,
    config=AuditConfig(control_db_url=str(engine.url))
)

Database Setup

Before using the middleware, provision the audit_logs table in your audit database:

from sqlalchemy.ext.asyncio import create_async_engine
from fastapi_audit import create_tables

engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/audit_db")
await create_tables(engine)

The create_tables() helper creates the audit_logs table and its associated enum type. Call it once during deployment or as part of a migration step.

Configuration

from fastapi_audit import AuditConfig

config = AuditConfig(
    # Required: Connection URL for the audit database
    control_db_url="postgresql+asyncpg://user:pass@localhost/audit_db",

    # Optional: Fields to redact (merged with defaults)
    redact_fields={"password", "token", "secret", "custom_field"},

    # Optional: Paths to exclude from audit logging
    exclude_paths={"/health", "/metrics"},

    # Optional: Map incoming actor_type values to canonical public values
    actor_type_aliases={"ops_admin": "platform_admin"},

    # Optional: Capture request/response bodies
    capture_request_body=True,
    capture_response_body=True,

    # Optional: Enable ORM diff capture
    capture_orm_diffs=True,

    # Optional: Log requests without authenticated actors
    log_anonymous=False,
)

Tenant Context

If your application is tenant-aware, the middleware can read tenant context from:

# Example: in your own tenant-resolution middleware
request.state.tenant = Tenant(tenant_id="...", tenant_slug="example-tenant")

The tenant object should have tenant_id and tenant_slug attributes.

JWT Token Requirements

The middleware extracts actor information from JWT tokens in the Authorization header. Expected JWT claims:

Claim Required Description
sub Yes User ID
actor_type No platform_admin, tenant_user, or anonymous (default)
email No User email address

Example JWT payload:

{
  "sub": "user-123",
  "actor_type": "platform_admin",
  "email": "user@example.com"
}

Organization-specific actor types can be mapped to canonical public values via AuditConfig.actor_type_aliases.

Manual Audit Logging

For background tasks or events outside the HTTP lifecycle:

from fastapi_audit import audit_log, ActorType
from sqlalchemy.ext.asyncio import AsyncSession

async def provision_tenant(db: AsyncSession):
    await audit_log(
        db=db,
        action="tenant.provisioned",
        actor_id="admin-user-id",
        actor_type=ActorType.PLATFORM_ADMIN,
        actor_email="admin@example.com",
        tenant_id="tenant-uuid",
        tenant_slug="example-tenant",
        metadata={"plan": "pro", "region": "us-east"}
    )

Environment Variables

All configuration can be set via environment variables with the AUDIT_ prefix:

export AUDIT_CONTROL_DB_URL="postgresql+asyncpg://..."
export AUDIT_CAPTURE_ORM_DIFFS="true"
export AUDIT_LOG_ANONYMOUS="false"

Architecture

HTTP Layer

The middleware intercepts requests and captures:

  • Request metadata such as method, path, and query params
  • Response metadata such as status code and response time
  • Actor information from JWT claims
  • Optional tenant context from request.state.tenant

ORM Layer

SQLAlchemy event listeners capture database changes:

  • Class-level listeners on AsyncSession work across application sessions
  • Context variables isolate diffs per request
  • INSERT, UPDATE, and DELETE operations are recorded

Storage

All audit logs are written to a single audit_logs table in the audit database, providing a unified view of application activity.

Requirements

  • Python 3.11+
  • FastAPI / Starlette
  • SQLAlchemy 2.0+ with async support
  • Pydantic v2
  • asyncpg (via pip install fastapi-audit[asyncpg])

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

fastapi_audit-0.2.0.tar.gz (25.9 kB view details)

Uploaded Source

Built Distribution

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

fastapi_audit-0.2.0-py3-none-any.whl (31.0 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_audit-0.2.0.tar.gz.

File metadata

  • Download URL: fastapi_audit-0.2.0.tar.gz
  • Upload date:
  • Size: 25.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_audit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 1c6cad25e8abf89f6842b40cc449bb42df3e939dd00d302620814e51c0236eda
MD5 8377c6da63b8fff4b49284db9a1cce09
BLAKE2b-256 f87a0219ddb0cfec0efd7bfcb1e43ca1c1f671129ae1936d498ba6d5f2aef0a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_audit-0.2.0.tar.gz:

Publisher: publish.yml on tanmaysheoran/fastapi-audit

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

File details

Details for the file fastapi_audit-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: fastapi_audit-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 31.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_audit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ca21438fbb41de713c8e9a6bfe69a40c7498b0cea87c528873cb7f526e85bd2a
MD5 fd809859a57520a4e96069b998db4508
BLAKE2b-256 9e15422a8250c83a05c60ac2dd2ee6b36c8741dcd139bc0056359b94acb87cda

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_audit-0.2.0-py3-none-any.whl:

Publisher: publish.yml on tanmaysheoran/fastapi-audit

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