Context governance for agentic AI — tamper-evident audit trails for LLM context inputs
Project description
Provena
Context governance for agentic AI systems. (MVP)
Your AI agent just made a decision based on data from 6 different sources. Can you tell me which ones? Can you prove the data wasn't tampered with? Can you verify it was still current?
Provena adds tamper-evident audit trails to any AI agent's context pipeline — in 3 lines of Python.
from provena import ContextTrail
trail = ContextTrail()
@trail.track(source="retriever")
def search(query):
return retriever.search(query)
Every call to search() is now logged with a SHA-256 content hash, provenance validation,
and a hash-chained audit trail that detects tampering.
Why Provena?
AGT governs what agents DO. Guardrails AI governs what agents SAY. Provena governs what agents KNOW.
No existing tool governs the context input layer. Provena fills this gap with:
- Tamper-evident audit trails — SHA-256 hash-chained (Merkle-style) logging with optional HMAC signing
- Provenance validation — Verify that context carries proper source metadata (VALID / MISSING / INCOMPLETE)
- Freshness checking — Detect stale context via metadata timestamps and regex temporal detection (FRESH / STALE / UNKNOWN)
- Any context source — RAG retrievers, tool outputs, agent messages, memory recalls, MCP resources
- Sub-1ms overhead — Pure Python, no ML models, no ONNX, no model downloads
- Zero dependencies — Core library uses only the Python standard library
Install
pip install provena # core (zero dependencies)
pip install provena[cli] # + CLI tools (click, rich)
pip install provena[otel] # + OpenTelemetry export
pip install provena[langchain] # + LangChain adapter
pip install provena[llamaindex] # + LlamaIndex adapter
pip install provena[all] # everything
Quick Start
from provena import ContextTrail, ProvenanceMetadata
from datetime import datetime, timezone
trail = ContextTrail(storage_path="audit.db")
# Track any function that produces context
@trail.track(source="retriever")
def search(query):
return retriever.search(query)
@trail.track(source="tool:pricing_api")
def get_price(product_id):
return api.get(f"/price/{product_id}")
# Manual logging with provenance metadata
trail.log(
content="The enterprise plan costs $499/month.",
source="tool:pricing_api",
provenance=ProvenanceMetadata(
source_url="https://api.example.com/pricing",
created_at=datetime.now(timezone.utc),
),
)
# Verify the audit trail hasn't been tampered with
verdict = trail.verify_chain()
print(f"Chain intact: {verdict.intact}")
print(f"Total records: {verdict.total_records}")
CLI
Install with pip install provena[cli], then:
# Verify hash chain integrity
provena --db audit.db verify
# PASS — Chain intact (42 records verified)
# Query the audit log
provena --db audit.db audit --source retriever --format json
# Generate a governance report
provena --db audit.db report --format text
# Quick summary
provena --db audit.db summary
For HMAC-signed trails, pass --signing-key or set PROVENA_SIGNING_KEY.
Integrations
LangChain
from provena.integrations.langchain import ProvenaCallback
chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever,
callbacks=[ProvenaCallback(trail=trail)],
)
LlamaIndex
from provena.integrations.llamaindex import ProvenaPostprocessor
query_engine = index.as_query_engine(
node_postprocessors=[ProvenaPostprocessor(trail=trail)]
)
OpenTelemetry
trail = ContextTrail(
storage_path="audit.db",
otel_enabled=True,
otel_service_name="my-agent",
)
# Every log() call now emits an OTel span with governance attributes
Architecture
Your Application
│
│ Retriever ──┐
│ Tool Call ──┤
│ Agent Msg ──┼──► ContextTrail ──► LLM Context Window
│ Memory ──┤ │
│ MCP ──┘ │
│ ┌─────┴──────────────┐
│ │ ProvenanceValidator │
│ │ FreshnessChecker │
│ │ HashChain (SHA-256) │
│ │ SQLite Backend │
│ │ OTel Exporter │
│ └────────────────────┘
Compliance
Provena maps directly to EU AI Act requirements (enforcement: August 2, 2026):
| Article | Requirement | Provena Feature |
|---|---|---|
| Art. 10 | Data lineage | Provenance validation for every context input |
| Art. 12 | Tamper-evident logging | SHA-256 hash-chained audit trail with HMAC signing |
| Art. 13 | Transparency | trail.summary() and source tracking |
| Art. 14 | Human oversight | trail.annotate() for reviewer decisions |
Also addresses OWASP ASI06 (Memory & Context Poisoning).
Contributing
We welcome contributions! See CONTRIBUTING.md for development setup, architecture guide, and PR process.
Please read our Code of Conduct before participating.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file provena-0.12.0.tar.gz.
File metadata
- Download URL: provena-0.12.0.tar.gz
- Upload date:
- Size: 102.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65a2febcb36488f437a2de8e6c1361feb889ba20426ff0a6270324ab64ff5a8b
|
|
| MD5 |
9be1fd07fe9b559c04016b352e81e06b
|
|
| BLAKE2b-256 |
704bd446f90f47adcae3e46c80930d6c83a309c176ed8f18587c8f29f3ae3215
|
Provenance
The following attestation bundles were made for provena-0.12.0.tar.gz:
Publisher:
publish.yml on rajfirke/provena
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provena-0.12.0.tar.gz -
Subject digest:
65a2febcb36488f437a2de8e6c1361feb889ba20426ff0a6270324ab64ff5a8b - Sigstore transparency entry: 2204817776
- Sigstore integration time:
-
Permalink:
rajfirke/provena@3ac19d726bf435497e53a7b6b41ffaa5383720ab -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/rajfirke
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3ac19d726bf435497e53a7b6b41ffaa5383720ab -
Trigger Event:
push
-
Statement type:
File details
Details for the file provena-0.12.0-py3-none-any.whl.
File metadata
- Download URL: provena-0.12.0-py3-none-any.whl
- Upload date:
- Size: 45.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35566413394dfe1bea01308b62c8d5b3e4e80831bb797aa37134ec886e911be7
|
|
| MD5 |
953d087625e0079c9bfff3f1d9a5789d
|
|
| BLAKE2b-256 |
c79c4a52337844d8e1b84854877c8a154b274180cea792d2e3f532e05c6e54e5
|
Provenance
The following attestation bundles were made for provena-0.12.0-py3-none-any.whl:
Publisher:
publish.yml on rajfirke/provena
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provena-0.12.0-py3-none-any.whl -
Subject digest:
35566413394dfe1bea01308b62c8d5b3e4e80831bb797aa37134ec886e911be7 - Sigstore transparency entry: 2204817789
- Sigstore integration time:
-
Permalink:
rajfirke/provena@3ac19d726bf435497e53a7b6b41ffaa5383720ab -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/rajfirke
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3ac19d726bf435497e53a7b6b41ffaa5383720ab -
Trigger Event:
push
-
Statement type: