{
  "markdown": "# ai-audit-trail\n\n<!-- mcp-name: io.github.sundsoffice-tech/ai-audit-trail -->\n\n[![PyPI version](https://img.shields.io/pypi/v/ai-audit-trail.svg)](https://pypi.org/project/ai-audit-trail/)\n[![Python](https://img.shields.io/pypi/pyversions/ai-audit-trail.svg)](https://pypi.org/project/ai-audit-trail/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![CI](https://github.com/sundsoffice-tech/ai-audit-trail/actions/workflows/ci.yml/badge.svg)](https://github.com/sundsoffice-tech/ai-audit-trail/actions/workflows/ci.yml)\n[![Downloads](https://static.pepy.tech/badge/ai-audit-trail/month)](https://pepy.tech/project/ai-audit-trail)\n[![Tests](https://img.shields.io/badge/tests-234%20passed-brightgreen)](https://github.com/sundsoffice-tech/ai-audit-trail)\n[![mypy](https://img.shields.io/badge/mypy-strict-blue)](http://mypy-lang.org/)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/sundsoffice-tech/ai-audit-trail/badge)](https://scorecard.dev/viewer/?uri=github.com/sundsoffice-tech/ai-audit-trail)\n\n**Prove what your AI did, why, and that nobody changed the record.**\n\n> Tamper-evident Decision Receipts with Ed25519 signatures, SHA-256 hash-chains,\n> and formal compliance mappings. No blockchain, no SaaS, no lock-in.\n> Self-hosted, offline-verifiable, Python-native.\n\n---\n\n## Why this exists\n\nThe **EU AI Act** becomes mandatory for high-risk AI systems in **August 2026**. It requires tamper-evident logs proving every decision was made correctly (Art. 12). Most teams are solving this with normal logging — which is neither tamper-evident nor legally defensible in an audit.\n\n`ai-audit-trail` closes this gap with **cryptographic receipts** that any auditor can verify offline, without accessing your systems. Same principle as a blockchain — without the blockchain overhead, the SaaS dependency, or the vendor lock-in.\n\n## Who is this for\n\n- **Regulated AI teams** (FinTech, HealthTech, LegalTech, InsurTech) who must prove compliance\n- **Enterprise platform teams** deploying LLM agents with tool access\n- **Security and compliance officers** who need audit-ready evidence packages\n- **Developers** who want `pip install` and 3 lines of code, not a platform migration\n\n## What this library provides\n\n`ai-audit-trail` provides the **technical building blocks** that support EU AI Act, ISO 42001, and NIST AI RMF compliance. It does not, by itself, guarantee regulatory compliance — compliance is an organizational obligation that extends beyond any single software component. See our [Shared Responsibility Model](#shared-responsibility-model) below.\n\n---\n\n## Installation\n\n```bash\npip install ai-audit-trail                    # Core (Ed25519 + SHA-256 + PII)\npip install \"ai-audit-trail[redis]\"           # + Redis persistence\npip install \"ai-audit-trail[otel]\"            # + OpenTelemetry metrics\npip install \"ai-audit-trail[all]\"             # Everything\n```\n\n**Requirements:** Python 3.11+ | No external services required | Works air-gapped\n\n---\n\n## Quickstart\n\n```python\nfrom ai_audit import (\n    AuditConfig, init_audit_config,\n    ReceiptCollector, ReceiptStore, ReceiptAction,\n    verify_chain, get_verify_key_hex,\n)\n\n# 1. Configure once at startup\ninit_audit_config(AuditConfig(is_production=False))\nstore = ReceiptStore()\n\n# 2. Wrap every AI request\ncollector = ReceiptCollector(trace_id=\"req-1\", tenant_id=\"acme\")\ncollector.set_input(\"What is our GDPR policy?\")\ncollector.add_check(\"safety\", score=0.02, threshold=0.8, fired=False)\ncollector.set_output(\"Our GDPR policy states that...\")\ncollector.set_action(ReceiptAction.ALLOW)\ncollector.emit(store)\ncollector.cleanup()\n\n# 3. Verify tamper-evidence\nresult = verify_chain(store.get_by_tenant(\"acme\"), get_verify_key_hex())\nassert result.valid  # Ed25519 + SHA-256 + hash-chain verified\n```\n\n---\n\n## Architecture Overview\n\n```\nReceipt Creation        Verification & Compliance       Agentic AI Audit\n─────────────────       ──────────────────────────      ──────────────────\nReceiptCollector   ──>  verify_chain()                  ToolCallReceipt\n  set_input()           build_compliance_summary()      TraceGraph (DAG)\n  add_check()           build_crosswalk()               BehavioralContract\n  set_output()          export_evidence_package()       ProvenanceChain\n  set_action()          SPRTMonitor\n  emit()                DriftMonitor\n       │                EpochManager\n       v\n  ReceiptStore     ──>  StorageBackend ABC\n  (in-memory LRU)       InMemoryBackend\n  + Redis (optional)    (your custom backends)\n  + AuditBuffer\n```\n\n---\n\n## Core Features\n\n### Decision Receipts (Ed25519 + SHA-256 + Hash-Chain)\n\nEvery AI pipeline decision produces a **Decision Receipt** — a cryptographically sealed, hash-chained record:\n\n| What's proven | How |\n|---|---|\n| Input integrity | SHA-256 of NFKC-normalized, PII-stripped input |\n| Output integrity | SHA-256 of generated output |\n| Check results | Ordered check records with scores and thresholds |\n| Decision | Action taken (ALLOW / REJECT / ESCALATE / ...) |\n| Model provenance | Model ID + config digest |\n| Non-repudiation | Ed25519 signature (libsodium) |\n| Ordering | Hash-chain linkage (prev_receipt_hash) |\n\n**Three-stage verification (< 0.1 ms per receipt):**\n\n```\nEd25519 signature  →  detects forgery\nSHA-256 self-hash  →  detects corruption\nHash-chain link    →  detects insertions / deletions / reordering\n```\n\n### PII Redaction (GDPR Art. 17)\n\nPersonal data is stripped **before** hashing — the audit log never contains raw PII.\n\n```python\nfrom ai_audit import PiiConfig, PiiMode, PiiType\n\nconfig = PiiConfig(\n    enabled_types=frozenset({PiiType.EMAIL, PiiType.PHONE, PiiType.IP}),\n    mode=PiiMode.REDACT,  # or HASH (SHA-256) or MASK (a***m)\n)\ncollector = ReceiptCollector(tenant_id=\"acme\", pii_config=config)\n```\n\n| Mode | `alice@corp.com` becomes |\n|------|--------------------------|\n| `REDACT` | `[EMAIL]` |\n| `HASH` | `3d4e5f8a...` (deterministic SHA-256) |\n| `MASK` | `a***@c***.com` |\n\n### Crypto-Shredding (GDPR Right to Erasure)\n\nEncrypt PII fields with per-tenant AES-256-GCM keys. Destroy the key = data permanently unreadable, hash-chain intact.\n\n```python\nfrom ai_audit.shredding import AESGCMDEKStore, encrypt_field, shred_tenant\n\ndek_store = AESGCMDEKStore()\ndek_store.create_dek(\"tenant-acme\")\n\nfield = encrypt_field(\"sensitive PII\", dek_store, \"tenant-acme\")\nshred_tenant(\"tenant-acme\", dek_store)  # Key destroyed — data unrecoverable\n# Hash-chain remains mathematically intact (hashes ciphertext, not plaintext)\n```\n\n---\n\n## Compliance & Governance\n\n### ISO 42001 / NIST AI RMF Crosswalk\n\nMaps receipt data directly to recognized management controls with evidence pointers.\n\n```python\nfrom ai_audit.crosswalk import build_crosswalk, nist_function_map\n\ncrosswalk = build_crosswalk(receipts, chain_intact=True)\nfor entry in crosswalk:\n    print(f\"[{entry.status}] {entry.framework} {entry.control_id} — {entry.control_name}\")\n\nnist = nist_function_map(receipts)\nprint(nist[\"GOVERN\"].coverage)   # 0.0–1.0\nprint(nist[\"MEASURE\"].status)    # PASS / PARTIAL / FAIL\n```\n\n**ISO 42001 Controls:** A.6.2.8 (Logging), A.7.5 (Provenance), A.6.2.6 (Performance), A.8.4 (Output), A.5.3 (Risk)\n**NIST AI RMF:** GOVERN, MAP, MEASURE, MANAGE — with quantitative coverage scores\n\n### EU AI Act Compliance Reports\n\n```python\nfrom ai_audit.report import ComplianceReportGenerator\n\ngen = ComplianceReportGenerator(summary, verify_key_hex=get_verify_key_hex())\ngen.to_markdown()   # Documentation portals\ngen.to_json()       # Automated pipelines\ngen.to_html()       # Air-gapped servers\n```\n\nCovers Art. 9 (Risk), Art. 12 (Record-Keeping), Art. 13 (Transparency), Art. 17 (Quality), Art. 18 (Logging).\n\n### Evidence Package Export (Offline Verification)\n\nSelf-contained signed ZIP for external auditors — no system access required.\n\n```python\nfrom ai_audit.export import export_evidence_package, verify_evidence_package\n\nexport_evidence_package(receipts, verify_key_hex, signing_key, \"audit_2026.zip\")\n# Bundle: receipts.jsonl + chain_metadata.json + public_key.hex + manifest.json (signed) + verify.py\n\n# Auditor verifies offline:\n# python -m ai_audit verify audit_2026.zip\n```\n\n### Continuous Certification (SPRT)\n\nSequential Probability Ratio Test — live compliance status per tenant.\n\n```python\nfrom ai_audit.sprt import SPRTMonitor\n\nmonitor = SPRTMonitor(tenant_id=\"acme\")\nfor receipt in receipts:\n    state = monitor.update(is_reject=(receipt.action == \"reject\"))\nprint(state.status)      # CERTIFIED | MONITORING | FLAGGED\nprint(state.confidence)  # 0.0–1.0\n```\n\n### Drift Detection (Jensen-Shannon Divergence)\n\nDetects behavioral shifts in real-time — pure Python, no scipy required.\n\n```python\nfrom ai_audit.drift import DriftMonitor\n\nmonitor = DriftMonitor(window_size=100)\nfor receipt in receipts:\n    state = monitor.update(receipt.action.value)\nprint(state.status)       # STABLE | DRIFTING | CRITICAL_DRIFT\nprint(state.drift_score)  # JSD 0.0–1.0\n```\n\n---\n\n## Agentic AI Audit (World-First)\n\n### Agent Behavioral Contracts\n\nFormal (p, delta, k)-Satisfaction with Reliability Index Theta — transforms EU AI Act requirements into testable specifications.\n\n```python\nfrom ai_audit.contracts import BehavioralContract, Constraint, ContractMonitor\n\ncontract = BehavioralContract(\n    contract_id=\"safety-v1\",\n    constraints=[\n        Constraint(name=\"no_pii_leak\", kind=\"hard\", field=\"action\", operator=\"!=\", value=\"reject\"),\n        Constraint(name=\"quality\", kind=\"soft\", field=\"checks.safety.score\", operator=\"<=\", value=0.1, delta=0.5),\n    ],\n)\nmonitor = ContractMonitor(contract)\nfor receipt in receipts:\n    state = monitor.evaluate(receipt)\n\nprint(state.p)                   # Hard constraint satisfaction probability\nprint(state.delta)               # Maximum soft deviation observed\nprint(state.k)                   # Recovery steps after last violation\nprint(state.reliability_index)   # Theta: single compliance metric (0.0–1.0)\nprint(state.status)              # COMPLIANT | DEGRADED | VIOLATED\n```\n\n### Cryptographic Tool-Call Receipts\n\nEvery agent API call Ed25519-signed — no existing framework provides this.\n\n```python\nfrom ai_audit.toolcall import seal_tool_call, verify_tool_call_chain\n\nreceipt = seal_tool_call(\n    agent_id=\"researcher\",\n    tool_name=\"web_search\",\n    tool_args={\"query\": \"EU AI Act compliance\"},\n    tool_result=\"Found 5 relevant documents...\",\n    private_key=signing_key,\n    tenant_id=\"acme\",\n)\nassert receipt.verify(signing_key.verify_key)\n```\n\n### Multi-Agent Trace-Graphs (DAG)\n\nAudit delegation, handoff, and parallel orchestration — not just linear logs.\n\n```python\nfrom ai_audit.tracegraph import TraceGraph\n\ngraph = TraceGraph(trace_id=\"workflow-1\", tenant_id=\"acme\")\nroot = graph.add_node(agent_id=\"orchestrator\", action=\"plan\")\ngraph.add_node(agent_id=\"researcher\", action=\"search\", parent_id=root.node_id)\ngraph.add_node(agent_id=\"writer\", action=\"draft\", parent_id=root.node_id)\n\nassert graph.verify_integrity()  # Hash-based tamper detection\nassert not graph.has_cycles()    # DAG validation\nlineage = graph.get_agent_lineage(leaf_node.node_id)  # Root-to-leaf trace\n```\n\n### Epistemische Integritat / Unforgeable Provenance\n\nTrack WHERE every piece of information came from — proves a decision was not influenced by prompt injection.\n\n```python\nfrom ai_audit.provenance import ProvenanceChain, ProvenanceRecord, SourceType\n\nchain = ProvenanceChain(receipt_id=\"r1\", tenant_id=\"acme\")\nchain.add(ProvenanceRecord(source_type=SourceType.SYSTEM, source_id=\"prompt\", trust_level=1.0, content_hash=\"...\"))\nchain.add(ProvenanceRecord(source_type=SourceType.DOCUMENT, source_id=\"doc-123\", trust_level=0.8, content_hash=\"...\"))\nchain.add(ProvenanceRecord(source_type=SourceType.UNKNOWN, source_id=\"???\", trust_level=0.0, content_hash=\"...\"))\n\nsummary = chain.trust_summary()\nprint(summary.system_grounded)       # True — has SYSTEM source\nprint(summary.potentially_injected)  # True — has UNKNOWN source\nprint(summary.min_trust)             # 0.0 — weakest link\n```\n\n---\n\n## High-Throughput Architecture\n\n### Merkle-Tree Batch Sealing (RFC 6962)\n\nChain-of-Roots instead of chain-of-receipts — O(log N) verification per batch.\n\n```python\nfrom ai_audit.batch import MerkleBatcher\n\nbatcher = MerkleBatcher(tenant_id=\"acme\", private_key=key, max_batch_size=2048)\nfor receipt in receipts:\n    seal = batcher.add(receipt.receipt_id, receipt.seal_payload())\n    if seal:  # Auto-flushed at 2048 receipts\n        print(f\"Batch sealed: {seal.merkle_root[:16]}...\")\n\nassert batcher.verify_chain_of_roots(key.verify_key)\n```\n\n### Chain Epochs / Rollover\n\nPrevent unbounded chain growth. Old epochs can be archived or deleted.\n\n```python\nfrom ai_audit.epochs import EpochManager\n\nmgr = EpochManager(tenant_id=\"acme\", private_key=key, max_epoch_size=10_000)\nfor receipt in receipts:\n    seal = mgr.add_receipt(receipt)  # Auto-seals at 10k\nmgr.seal_epoch()                     # Or explicit rollover\nassert mgr.verify_epoch_chain(key.verify_key)\n```\n\n### Ring-Buffer with Backpressure\n\nBounded buffer for high-throughput ingestion — fail-closed, no silent data loss.\n\n```python\nfrom ai_audit.buffer import AuditBuffer, AuditBufferFullError\n\nbuffer = AuditBuffer(maxsize=50_000)  # ~5 seconds at 10k req/s\ntry:\n    buffer.put(receipt)\nexcept AuditBufferFullError:\n    # Backpressure — reject the request rather than lose audit data\n    pass\nbatch = buffer.drain(max_items=2048)\n```\n\n### Storage Backend ABCs\n\nPluggable persistence — bring your own database.\n\n```python\nfrom ai_audit.storage import StorageBackend, InMemoryBackend\n\n# Use the reference implementation for dev/test\nbackend = InMemoryBackend(max_receipts=50_000)\n\n# Or implement your own:\nclass PostgresBackend(StorageBackend):\n    def write_receipt(self, receipt): ...\n    def read_receipt(self, receipt_id): ...\n    def query_by_tenant(self, tenant_id, limit=100): ...\n    def healthcheck(self) -> bool: ...\n```\n\n### OpenTelemetry Instrumentation\n\nNative metrics for SRE dashboards — graceful no-op without OTel SDK.\n\n```python\n# pip install \"ai-audit-trail[otel]\"\nfrom ai_audit.telemetry import record_seal, record_append, record_drift\n\nrecord_seal(duration_seconds=0.000045, tenant_id=\"acme\")\nrecord_append(tenant_id=\"acme\", async_mode=True)\nrecord_drift(score=0.03, tenant_id=\"acme\")\n```\n\n**Metrics:** `ai_audit.seal_duration_seconds`, `ai_audit.append_total`, `ai_audit.redis_fallback_total`, `ai_audit.chain_break_total`, `ai_audit.drift_score`, `ai_audit.buffer_size`, `ai_audit.epoch_sealed_total`\n\n---\n\n## Production Setup\n\n### Persistent Signing Key\n\n```bash\npython -c \"import nacl.signing; print(nacl.signing.SigningKey.generate().encode().hex())\"\n```\n\n```python\ninit_audit_config(AuditConfig(is_production=True, signing_key_hex=\"your-64-char-hex-key\"))\n```\n\n### KMS Integration\n\n```python\nfrom ai_audit import KeyProvider, init_key_provider\n\nclass VaultKeyProvider(KeyProvider):\n    def get_signing_key(self) -> nacl.signing.SigningKey:\n        secret = vault_client.secrets.kv.read_secret(\"secret/ai-audit/key\")\n        return nacl.signing.SigningKey(bytes.fromhex(secret[\"data\"][\"key\"]))\n    def get_verify_key_hex(self) -> str:\n        return self.get_signing_key().verify_key.encode().hex()\n\ninit_key_provider(VaultKeyProvider())\n```\n\n### Redis Persistence\n\n```python\nimport redis\nstore = ReceiptStore(redis_client=redis.Redis(), use_lua=True)  # Lua mode: 10k+ req/s\n```\n\n---\n\n## Shared Responsibility Model\n\n| Responsibility | Library | Deployer |\n|---|:---:|:---:|\n| Ed25519 + SHA-256 signing and hashing | X | |\n| Hash-chain integrity | X | |\n| PII redaction (REDACT/HASH/MASK) | X | |\n| Merkle-Tree batch sealing (RFC 6962) | X | |\n| SPRT compliance certification | X | |\n| ISO 42001 / NIST AI RMF mapping | X | |\n| Evidence Package export + verification | X | |\n| Crypto-Shredding (AES-256-GCM) | X | |\n| Agent Behavioral Contracts | X | |\n| OpenTelemetry metrics | X | |\n| **Secure key storage (HSM/Vault)** | | X |\n| **PII type configuration** | | X |\n| **Durable storage backend** | | X |\n| **Access controls / RBAC** | | X |\n| **Human oversight (EU AI Act Art. 14)** | | X |\n| **Clock synchronization (NTP)** | | X |\n| **Incident response** | | X |\n| **Regulatory compliance certification** | | X |\n\n---\n\n## Examples\n\nSee the [`examples/`](examples/) directory:\n\n- **[end_to_end_audit.py](examples/end_to_end_audit.py)** — Full lifecycle: receipts, verification, crosswalk, evidence export\n- **[fastapi_middleware.py](examples/fastapi_middleware.py)** — FastAPI audit middleware pattern\n- **[langchain_callback.py](examples/langchain_callback.py)** — LangChain callback handler\n\n---\n\n## Performance\n\n| Operation | Typical Latency | Notes |\n|---|---|---|\n| `seal()` (hash + sign) | < 100 us | Ed25519 via libsodium C |\n| `verify_chain(1000)` | < 50 ms | Scales linearly |\n| `merkle_root(2048)` | < 5 ms | RFC 6962 SHA-256 |\n| Memory per receipt | ~1 KB | Pydantic V2 + orjson |\n\nRun benchmarks: `pytest tests/test_benchmark.py -v -s`\n\n---\n\n## Project Stats\n\n| Metric | Value |\n|---|---|\n| Tests | 196 |\n| Source modules | 26 |\n| `__all__` exports | 60 |\n| Type checking | mypy --strict, 0 errors |\n| Linting | ruff, 0 errors |\n| Python versions | 3.11, 3.12, 3.13 |\n| Security scans | 3 completed, 6 fixes applied |\n| NB validators consulted | 5 (Architecture, Enterprise, Performance, Agentic, Branding) |\n\n---\n\n## Security\n\nSee [SECURITY.md](SECURITY.md) for the full threat model, vulnerability reporting process, and supported versions.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for architecture invariants, the shared responsibility model, and contribution guidelines.\n\n---\n\n## License\n\nMIT — free for commercial use.\n\n---\n\n## Created and maintained by\n\n**[S&S Connect](https://github.com/sundsoffice-tech)** — Building trust infrastructure for autonomous AI systems.\n\n- **Maintainer:** Fabrice ([@sundsoffice-tech](https://github.com/sundsoffice-tech))\n- **Repository:** [github.com/sundsoffice-tech/ai-audit-trail](https://github.com/sundsoffice-tech/ai-audit-trail)\n- **PyPI:** [pypi.org/project/ai-audit-trail](https://pypi.org/project/ai-audit-trail/)\n- **Issues & Feedback:** [GitHub Issues](https://github.com/sundsoffice-tech/ai-audit-trail/issues)\n\nIf you use `ai-audit-trail` in production or research, we'd love to hear about it.\n",
  "bytes": 18453,
  "sha": "2b7973a8ad7d9dad66b9578c8a7895fb62d001fe43ddaeb8344190db23b5fab5",
  "repo_slug": "sundsoffice-tech/ai-audit-trail",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_sundsoffice_tech_ai_audit_trai_c0dcfd44/readme"
}