Skip to main content

CloudEvents-style audit event model, builder, integrity signing and Kafka publishing for Mobius Python (FastAPI) services.

Project description

mobius-auditlog-py

Build, sign, and publish CloudEvents-style audit events from Mobius Python (FastAPI / Starlette) services.

  • PyPI: pip install mobius-auditlog-py
  • Import package: mobius_auditlog
  • Python: 3.10+

Install

pip install mobius-auditlog-py

pydantic, starlette, and py-kafka-producer-client are installed automatically.

Quick start (auto-capture middleware)

from fastapi import FastAPI
from kafka_producer_client import KafkaProducerConfig
from mobius_auditlog import setup_auditlog

app = FastAPI()

setup_auditlog(
    app,
    topic="audit-logs",
    signing_key="your-hmac-key",                # optional signature
    kafka_config=KafkaProducerConfig(bootstrap_servers="broker:9092"),
    capture_payloads=False,                      # set True to buffer req/resp bodies
    compliance_category="GDPR",
)

The middleware emits one audit event per request: action (route, method, status, severity), network (client IP + user-agent), objectref (from the path), and the envelope/subject from the request context. It skips health/metrics/swagger paths.

The event schema

AuditLogEvent — flat envelope + nested sections, serialized with empty values omitted and keys alphabetically ordered:

Section Fields
envelope id, specversion, timestamp, traceid, transactionid, tenantid
subject userid, type, groups[]
kubernetes namespacename, podname, containername, nodename
objectref resource, resourceid, apiversion
action name, method, severity, status
network sourceip, useragent
eventdata requestpayload{}, responsepayload{}, metadata{issensitive, compliancecategory}
security hash, signature
event.to_dict()    # pruned dict (empties dropped), ready to publish
event.to_json()    # canonical JSON: pruned + sorted keys (used for hashing)

Building events manually

from mobius_auditlog import AuditLogBuilder

event = (
    AuditLogBuilder()
    .from_context()                              # tenant/trace/txn/subject from context
    .object_ref(resource="order", resourceid="order-789", apiversion="v1.0")
    .action(name="order.create", method="POST", severity="INFO", status="SUCCESS")
    .network(sourceip="1.2.3.4", useragent="curl/8")
    .event_data(requestpayload={"amount": 42}, issensitive=True, compliancecategory="PCI")
    .build()
)

from_context() pulls identity fields from the request context or fallback headers. It maps the outer envelope tenantid to a fixed platform tenant ID (defaults to "2cf76e5f-26ad-4f2c-bccc-f4bc1e7bfb64", overridable via the KAFKA_PLATFORM_TENANT_ID environment variable). The user's trace, transaction, and subject identity (userid/type) are preserved from context/headers. It also pulls kubernetes metadata from downward-API env vars (POD_NAMESPACE, POD_NAME, CONTAINER_NAME, NODE_NAME).

Integrity: hash + signature

from mobius_auditlog import seal, verify, compute_hash

seal(event, signing_key="key")     # sets security.hash (+ signature)
verify(event, signing_key="key")   # True if hash + signature match
  • hash = SHA-256 over the canonical JSON excluding the security block.
  • signature = HMAC-SHA256 of the hash with your key (omitted if no key).

The publisher seals events automatically before sending.

Publishing

The publisher depends only on a small protocol — no hard Kafka coupling:

class LogEventSender(Protocol):
    def send(self, value: dict, *, topic: str) -> Any: ...

setup_auditlog resolves a publisher from (in order) kafka_senderkafka_producerkafka_config → the configured py-kafka-producer-client singleton. Or use it directly:

from mobius_auditlog import AuditLogPublisher, PyKafkaProducerClientSender, set_publisher

publisher = AuditLogPublisher(PyKafkaProducerClientSender(client),
                              topic="audit-logs", signing_key="key")
set_publisher(publisher)
publisher.publish(event)           # seals + sends, fire-and-forget

Publishing runs on a background thread and never raises into the request path.

Payload capture

With capture_payloads=True, the middleware buffers request and response bodies (JSON-parsed, size-capped at 64 KB) into eventdata.requestpayload / responsepayload. Off by default for privacy and overhead. Non-JSON bodies are stored as {"_raw": "..."}.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

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

mobius_auditlog_py-1.0.3.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

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

mobius_auditlog_py-1.0.3-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file mobius_auditlog_py-1.0.3.tar.gz.

File metadata

  • Download URL: mobius_auditlog_py-1.0.3.tar.gz
  • Upload date:
  • Size: 12.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for mobius_auditlog_py-1.0.3.tar.gz
Algorithm Hash digest
SHA256 7699ee6aa8dc3ca22dcc5a4dda9de5aa31ec8c641a51bf2b4b727dc4249572d9
MD5 bd38d49f5764a8d36991181b1e67edb9
BLAKE2b-256 99c7e48a90775c49cb8a9f0eabb93c339a8ca06de97407d26636db9d9217c785

See more details on using hashes here.

File details

Details for the file mobius_auditlog_py-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for mobius_auditlog_py-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 a91919e0e0f2791b1065cd8e797209f9a223bbd7b171faea5b41a10faa12cf93
MD5 a58ab190bd314478d82747b709c1e238
BLAKE2b-256 51e72339e537c9fde4e54a0b9948c3c3a589a27eb0a4a6314f924e02d61c8d4c

See more details on using hashes here.

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