Skip to main content
Every memory operation in Memproof emits lifecycle events to an audit trail powered by Trailproof. These events form a tamper-evident, hash-chained record of what happened, when, and why.

Event Types

Each operation progresses through a sequence of namespaced events:
Event TypeEmitted When
memproof.pipeline.receivedOperation enters the control path
memproof.pipeline.risk_assessedRisk engine produces a score and level
memproof.pipeline.policy_decidedPolicy engine returns allow/deny/approve/quarantine
memproof.pipeline.approval_requestedOperation is sent to the approval broker
memproof.pipeline.provider_attemptedAdapter backend call is made
memproof.pipeline.committedMemory successfully persisted
memproof.pipeline.blockedOperation denied or quarantined

Choosing a Trail Store

Events are stored in memory. Suitable for development and testing. Data is lost on process exit.
mp = Memproof(
    policy="memproof.yaml",
    trail_store="memory",   # this is the default
)

Event Signing

Provide a signing key to enable HMAC-SHA256 signing. Trailproof signs each event and stores the signature in the TrailEvent:
mp = Memproof(
    policy="memproof.yaml",
    trail_store="jsonl",
    trail_store_path="./memproof_audit.jsonl",
    trail_signing_key="your-secret-key-from-vault",
)
Store the signing key in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.). If the key is compromised, an attacker could forge valid signatures for fabricated events.

Verifying the Audit Trail

Trailproof links each event to its predecessor using SHA-256 hashes. Call verify_audit_trail() / verifyAuditTrail() to validate the entire hash chain and detect any tampering:
result = mp.verify_audit_trail()

if result.valid:
    print(f"Chain intact: {result.event_count} events verified")
else:
    print(f"Chain broken: {result.error}")
    # Investigate the broken link
Run verification on a schedule (e.g., every hour or as part of a health check) to detect tampering early. If the chain breaks, the verification result identifies the first invalid event.

Querying the Audit Trail

Use the query_audit_trail() / queryAuditTrail() method to search events:
# All committed events for a tenant
events = mp.query_audit_trail(
    event_type="memproof.pipeline.committed",
    metadata={"tenant_id": "acme-corp"},
    limit=50,
)

for event in events:
    print(f"{event.event_type} at {event.timestamp}")
You can also retrieve all events for a single operation by filtering on operation_id in the metadata:
events = mp.query_audit_trail(
    metadata={"operation_id": "op-abc123"},
)

TrailEvent Structure

Each event in the audit trail is a Trailproof TrailEvent:
class TrailEvent:
    event_id: str           # globally unique ID
    event_type: str         # e.g. "memproof.pipeline.committed"
    timestamp: datetime     # UTC timestamp
    actor: str | None       # who triggered the event
    metadata: dict          # operation_id, tenant_id, stage-specific data
    hash: str               # SHA-256 hash for chain integrity
    prev_hash: str | None   # hash of the previous event in the chain
    signature: str | None   # HMAC-SHA256 signature (if signing enabled)

Environment Variable Configuration

All trail settings can be configured via environment variables:
export MEMPROOF_TRAIL_STORE="jsonl"
export MEMPROOF_TRAIL_STORE_PATH="./memproof_audit.jsonl"
export MEMPROOF_TRAIL_SIGNING_KEY="your-secret-key"
See Configuration for the full environment variable reference.

Learn More

For advanced Trailproof features — custom stores, chain semantics, and more — see the Trailproof documentation.