Skip to main content

Audit logging package for FastAPI applications

Project description

fastapi-audit

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

pip install fastapi-audit

Local Development

pip install -e /path/to/audit

Quick Start

from fastapi import FastAPI
from fastapi_audit import AuditMiddleware, AuditConfig

app = FastAPI()

app.add_middleware(
    AuditMiddleware,
    config=AuditConfig(
        control_db_url="postgresql+asyncpg://user:pass@localhost/audit_db"
    )
)

The legacy audit import path still works for compatibility, but fastapi_audit is the preferred public import path.

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={"hashira": "platform_admin", "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,
)

Database Migration

Create the audit_logs table in your audit database:

# Using Alembic
alembic upgrade head

# Or run the SQL migration directly
# See migrations/versions/001_create_audit_logs.py

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"
}

Legacy or organization-specific actor types can be mapped to canonical public values via AuditConfig.actor_type_aliases. By default, "hashira" maps to "platform_admin".

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

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.1.0.tar.gz (19.7 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.1.0-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fastapi_audit-0.1.0.tar.gz
  • Upload date:
  • Size: 19.7 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.1.0.tar.gz
Algorithm Hash digest
SHA256 78cb2f4f097a11c2bb592e65d364c84025c9d3b27b68dc6e1605725e7a465012
MD5 a6b66d881f71670a067bbb53510cc7e9
BLAKE2b-256 3e9bae21330c1b2a1f30e6fb8cf5285694f930692927d0bf05d6fb48c8a5fc73

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_audit-0.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: fastapi_audit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.8 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1b06cc925eaf33a3a3eef3e84d7487318bd3e39758346bab907c6c6847f07aad
MD5 3f430cb2402075091924d89edd20dbe2
BLAKE2b-256 a9242663fef2a1fcabcb13a366949e88da0c6b46ba2508e49ae9ff55f3538ff0

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_audit-0.1.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