Skip to main content

Auditoria de eventos rápida e íntegra (hash chain) para apps Python, com core em Rust.

Project description

rust-py-audit

PyPI Python License GitHub

Biblioteca de auditoria de eventos para aplicações Python, com core em Rust.

Registra eventos de auditoria (quem fez o quê, quando, em qual recurso) de forma rápida e estruturada, e encadeia cada evento ao anterior com SHA-256 — qualquer edição, remoção ou reordenação posterior do arquivo de log é detectável com verify().


Features

  • AuditLogger — API simples: log(...), verify(), last_hash()
  • Cadeia de hashes (SHA-256) — cada evento inclui o hash do evento anterior; alterar qualquer evento gravado quebra a cadeia de forma detectável
  • Armazenamento em JSONL — um evento por linha, append-only, sem necessidade de banco de dados
  • metadata livre — qualquer dict JSON-serializável (IP, motivo, request_id, etc.)
  • Middleware FastAPI — registra automaticamente requisições que alteram estado (POST/PUT/PATCH/DELETE)
  • Middleware Django — mesma ideia, suporta WSGI e ASGI
  • Core em Rust — geração de hash, serialização e I/O acontecem em Rust via PyO3; a API Python permanece simples

Requirements

  • Python 3.10+
  • Nenhuma dependência obrigatória em runtime

Opcionais, instaladas separadamente:

  • fastapi + starlette — para rust_py_audit.fastapi.AuditMiddleware
  • django — para rust_py_audit.django.AuditMiddleware

Installation

pip install rust-py-audit

Com extras opcionais:

pip install "rust-py-audit[fastapi]"
pip install "rust-py-audit[django]"

Quick Start

from rust_py_audit import AuditLogger

audit = AuditLogger(app_name="billing-api", file_path="./audit.jsonl")

event = audit.log(
    actor_id="user_123",
    action="DELETE_INVOICE",
    resource="invoice",
    resource_id="inv_987",
    metadata={"ip": "192.168.0.10", "reason": "duplicate invoice"},
)

print(event["id"])     # uuid v4
print(event["hash"])   # sha256, 64 caracteres hex

print(audit.last_hash())  # hash do último evento gravado

result = audit.verify()
print(result)
# {"valid": True, "total_events": 1, "last_hash": "..."}

Integridade da cadeia

Cada evento grava o hash do evento anterior (previous_hash) e o próprio hash (hash), calculado a partir do conteúdo do evento + previous_hash. O primeiro evento da cadeia tem previous_hash = null.

{"id":"evt_123","timestamp":"2026-06-17T10:00:00Z","app_name":"billing-api","actor_id":"user_123","action":"DELETE_INVOICE","resource":"invoice","resource_id":"inv_987","metadata":{"ip":"192.168.0.10"},"previous_hash":null,"hash":"abc123..."}

verify() relê o arquivo do zero e recalcula tudo — não confia em nenhum cache em memória:

result = audit.verify()

Se a cadeia estiver intacta:

{"valid": True, "total_events": 10, "last_hash": "..."}

Se algum evento foi editado, removido ou reordenado:

{"valid": False, "total_events": 10, "error_index": 4, "reason": "hash_mismatch"}
# ou "reason": "broken_chain" (evento removido/reordenado/forjado)

FastAPI

from fastapi import FastAPI
from rust_py_audit.fastapi import AuditMiddleware

app = FastAPI()
app.add_middleware(AuditMiddleware, app_name="billing-api", file_path="./audit.jsonl")


@app.delete("/invoices/{invoice_id}")
async def delete_invoice(invoice_id: str):
    return {"deleted": invoice_id}

Por padrão, só requisições POST/PUT/PATCH/DELETE são registradas. actor_id vem do header X-User-Id (ajustável via actor_header=); cai para "anonymous" se ausente.

Ver exemplo completo em examples/fastapi_app.py.


Django

# settings.py
MIDDLEWARE = [
    "rust_py_audit.django.AuditMiddleware",
    # ... outros middlewares ...
]

# Opcional:
RUST_PY_AUDIT_APP_NAME = "my-django-app"
RUST_PY_AUDIT_FILE_PATH = "./audit.jsonl"
RUST_PY_AUDIT_METHODS = {"POST", "PUT", "PATCH", "DELETE"}

actor_id vem de request.user.pk quando há um usuário autenticado (via django.contrib.auth); cai para "anonymous" caso contrário. O middleware suporta tanto aplicações WSGI quanto ASGI automaticamente.

Ver exemplo completo em examples/django_example/.


API Reference

AuditLogger(app_name, file_path="./audit.jsonl")

Parâmetro Tipo Descrição
app_name str Nome da aplicação, gravado em todo evento
file_path str Caminho do arquivo JSONL. Se já existir, a cadeia é retomada a partir do último hash gravado

audit.log(actor_id, action, resource, resource_id, metadata=None) → dict

Registra um evento e devolve o evento completo (já com id, timestamp, hash, etc.) como dict.

Campo do evento Tipo Descrição
id str UUID v4
timestamp str RFC3339 / UTC, ex: 2026-06-17T10:00:00Z
app_name str Vem do AuditLogger
actor_id str Quem realizou a ação
action str Ex: DELETE_INVOICE
resource str Ex: invoice
resource_id str Ex: inv_987
metadata dict Livre — qualquer JSON serializável
previous_hash str | None Hash do evento anterior na cadeia
hash str SHA-256 (64 hex chars) do evento + previous_hash

audit.verify() → dict

Relê o arquivo e revalida a cadeia inteira do zero. Ver Integridade da cadeia.


audit.last_hash() → str | None

Hash do último evento gravado (cache em memória, O(1)) — None se nenhum evento foi registrado ainda.


Building from Source

Requer Rust e maturin.

git clone https://github.com/robertolima-dev/rust-py-audit
cd rust-py-audit

python3 -m venv .venv
source .venv/bin/activate
pip install maturin

# Build de desenvolvimento (instala no ambiente Python atual)
maturin develop

# Wheel de release
maturin build --release

Running tests

# Testes unitários em Rust
cargo test --no-default-features

# Testes de integração em Python
pip install -e ".[dev]"
pytest tests/

Architecture

Python API (rust_py_audit)
    ├── AuditLogger(...)        ──► src/audit_logger.rs (PyO3 #[pyclass])
    │       ├── log()           ──► src/event.rs    (AuditEvent)
    │       │                   ──► src/hash.rs     (SHA-256 determinístico)
    │       │                   ──► src/storage.rs  (append em JSONL)
    │       ├── verify()        ──► src/verifier.rs (revalida a cadeia)
    │       └── last_hash()     ──► cache em memória
    │
    ├── fastapi.AuditMiddleware ──► audit.log() a cada request mutante
    └── django.AuditMiddleware  ──► idem, WSGI/ASGI

O core é compilado para uma extensão nativa (.so/.pyd) por maturin e PyO3. A camada Python é fina — só roteia chamadas e oferece os adaptadores de framework.


License

MIT — ver LICENSE.

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

rust_py_audit-0.1.0.tar.gz (35.1 kB view details)

Uploaded Source

Built Distributions

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

rust_py_audit-0.1.0-cp310-abi3-win_amd64.whl (234.8 kB view details)

Uploaded CPython 3.10+Windows x86-64

rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl (583.5 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_aarch64.whl (543.7 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (379.1 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (368.8 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

rust_py_audit-0.1.0-cp310-abi3-macosx_11_0_arm64.whl (328.0 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

rust_py_audit-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl (335.9 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: rust_py_audit-0.1.0.tar.gz
  • Upload date:
  • Size: 35.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.14.0

File hashes

Hashes for rust_py_audit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c969c2e1c96378d8b4fe4fe990d497574434d313be00de8393a886107ca4a2de
MD5 d26b9924464b6ff6ff356b80e8f92cd2
BLAKE2b-256 a1aaad568bbba77dcf2df53e97d79a25cddc43cf21d4d32424e52e77fcefd37d

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 d61f736a7b0ea54746258d390425ecb07194fa6462836d6856935164fc2f5596
MD5 6c2a4e998ecfa14080d25ff4e83bca57
BLAKE2b-256 b352d6198af2d667c1103b3b2d662bf0f8a26866f51be41e1659668251461abe

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 3281f63c0e13e2a97af23c1015cee3ed7463b73dc63b1363e94152c7216f1dd0
MD5 11ad8f9dc43c210a294a52428271ff73
BLAKE2b-256 38910abd0cfa9f081f79128f4af1d9dec2da9e94b401f2339a555a42181c3eef

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e9aeba58c7474a797169ce6b1378cbc610bf26b718ac3b91e9a821e442278542
MD5 c4492c6428918d564340703039e0fb69
BLAKE2b-256 eabd1a9cbe78a94f84aa5b3acf0ed37b886a01d5ba9872f2b9c90bca0a3d22db

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4c6eb8e13384719c97094efa74ffdf3e7a908dfe3355b577b2141601432ca8ad
MD5 2da246d967e30cbb41dfbb02852a99f9
BLAKE2b-256 84523567075c8f9b81ea865d79518da620e9a9f4e638a72b87f33e2e739f5cf2

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 60a694b750493662f48a595aad5db68baa2015f55514c8a878f038dd8095d1f6
MD5 105dec36777ab844cef13bc50a5802c8
BLAKE2b-256 04a32339e446388d7955f9d666fad71a5a5c746afe9a998c56128e226714e273

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a46d06fa629d42f89c8323f0437e3c2cd1a9a0ee9397cbb7c53b6a6ebcf1f65b
MD5 12c6faa0db42a9e556e2150e3c636ca0
BLAKE2b-256 41b8bf7252f2da2cfc29ef456287bfb0c01dc939f5eb8878267ecd9abe4d33ec

See more details on using hashes here.

File details

Details for the file rust_py_audit-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rust_py_audit-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 17386b2684763f564ef81713d8b5b79d25c6b1230e07785f21add6300c5d21dc
MD5 7692c598d6292ea608f207b04438de06
BLAKE2b-256 3a5ec8f26d1c353865815522303afa223c2deef5b977e4da082fc987a94c2581

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