contextbom
A bill of materials for every prompt. Know exactly what went into your AI model — every source, every transformation, every redaction — as a signed, auditable manifest.
pip install contextbom
import contextbom as cbom
from openai import OpenAI
ctx = cbom.Context()
# Stamp provenance as you gather context. add() returns the (possibly transformed)
# text to place into your prompt.
docs = ctx.add(retriever.search(query), source="qdrant://kb/policies",
source_type="retrieval", sensitivity="internal")
history = ctx.add(memory.recall(user_id), source="mem0://user/123",
source_type="memory", sensitivity="pii")
ticket = ctx.add(fetch_ticket(id), source="https://jira.co/T-42",
source_type="url", transforms=[cbom.redact_pii])
# Call any model, your way. Record which model saw this context.
ctx.set_model("gpt-5", provider="openai")
response = OpenAI().chat.completions.create(
model="gpt-5", messages=build_prompt(docs, history, ticket))
ctx.record_completion(response.choices[0].message.content)
print(ctx.manifest.to_json()) # full lineage of everything the model saw
ctx.manifest.to_json("call.cbom.json") # or persist it
Output — a CBOM manifest for that call (hashes and metadata only — never the context text itself, so it's safe to log and retain):
{
"producer": {"name": "contextbom-python", "version": "0.2.0"},
"model": {"id": "gpt-5", "provider": "openai"},
"cbom_version": "0.1",
"manifest_id": "6ab7c315-4dcf-422e-be0c-78973a3574ad",
"created_at": "2026-07-27T11:52:58Z",
"segments": [
{
"id": "seg-1",
"role": "user",
"source": {"uri": "qdrant://kb/policies", "type": "retrieval"},
"hash": "sha256:7579e8...",
"tokens": 812,
"sensitivity": "internal"
},
{
"id": "seg-2",
"role": "user",
"source": {"uri": "https://jira.co/T-42", "type": "url"},
"hash": "sha256:17bb9a...",
"hash_original": "sha256:bae7ec...",
"tokens": 240,
"sensitivity": "pii",
"authorized_by": "user:akshat",
"transforms": [
{"type": "redact_pii", "hash_after": "sha256:17bb9a...",
"detail": {"removed": 1, "engine": "regex"}}
]
}
],
"completion": {
"response_hash": "sha256:50f1f2...",
"usage": {"input_tokens": 1052, "output_tokens": 48}
}
}
Why
- Audit & compliance — EU AI Act Article 12 requires logging what high-risk AI systems processed. A CBOM manifest is that record.
- Security — see exactly which tool output entered the prompt when investigating an injection or leak. Prove secrets never left the boundary.
- Debugging — "why did the model say that?" starts with "what did the model see?"
- Trust — a verifiable manifest makes AI decisions explainable to auditors, customers, and courts.
What it is / isn't
| ✅ An open spec (JSON) + SDKs that stamp provenance onto context at assembly time | ❌ A gateway or proxy you must deploy |
| ✅ Works with any model, any framework | ❌ Another agent framework |
| ✅ Complements CycloneDX ML-BOM / SPDX (static artifacts) with runtime lineage | ❌ A replacement for SBOM standards |
| ✅ A record of what entered a model call | ❌ A memory layer or context store |
| ✅ OpenTelemetry export (roadmap) | ❌ A hosted service |
Features
cbom.Context— wrap context assembly; automatic manifest generation- Transforms — built-in, recordable
redact_pii,strip_secrets,truncate cbom view/cbom verify— CLI (installed with the package) that renders any prompt color-coded by source and sensitivity, and verifies hash chains- JSONL audit log — append every call's manifest to a log with
ctx.log() - Signing — optional Sigstore-style attestation of manifests (roadmap, v0.3)
- Integrations — LangChain callback (auto-emit manifests from any chain/agent run) and MCP middleware (stamp every tool response) ship today; LlamaIndex on the roadmap
Integrations
LangChain — one handler, every LLM call gets a manifest:
from contextbom.integrations.langchain import CBOMCallbackHandler
handler = CBOMCallbackHandler(log_path="cbom.jsonl")
chain.invoke({...}, config={"callbacks": [handler]})
# retrieved docs -> retrieval segments, prompts -> literal segments, per-call manifests
MCP — wrap your tool caller once; every tool response is provenance-stamped (and secret-stripped by default) before it enters context:
from contextbom.integrations.mcp import wrap_tool_caller
call = wrap_tool_caller(ctx, session.call_tool, server="github")
result = await call("search", {"q": "..."}) # recorded as mcp://github/search
Optional extras: pip install "contextbom[pii]" (Presidio-backed PII detection — the manifest records which engine ran), "contextbom[tokens]" (tiktoken counts), "contextbom[all]".
Spec
The manifest format is defined in SPEC.md. v0.1 is deliberately small: segments, sources, hashes, transforms, sensitivity labels, signatures. Extensions are namespaced.
Contributing
The spec is developed in the open — issues and RFCs welcome. Good first contributions: SDK ports (TypeScript, Go), framework integrations, transform plugins.
Apache-2.0.
Metadata
Release files for contextbom 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| contextbom-0.2.0.tar.gz | 137.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| contextbom-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.1 kB
Release files / contextbom-0.2.0.tar.gz
| Download URL | contextbom-0.2.0.tar.gz |
|---|---|
| Size | 137.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
23998953488e77cb5a0d07531aac8b6b7bb39487c61d8ee52c9e9834509c8eae
|
|
BLAKE2b-256 checksum How to use checksums |
5a2d1a939222b4534974aca6a98984a379ce50e0dd8f40fa1f51aad61f5ab2eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / contextbom-0.2.0-py3-none-any.whl
| Download URL | contextbom-0.2.0-py3-none-any.whl |
|---|---|
| Size | 17.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7c1d9d9f0affb75846ac41e20311737963180946fe1e2a357b2e42544e5847bb
|
|
BLAKE2b-256 checksum How to use checksums |
7f18862a8dff65e0c46b59a662cfda3c0f9a30a97966cd291ccb646b6f055efd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|