Tamper-evident HMAC audit chain for LLM applications. Cryptographically link every span. Detect tampering. Prove provenance to regulators.
HMAC-SHA256 over a JCS-canonicalized body of each gen_ai span. Each entry's hmac depends on the previous. Mutating any byte of any entry breaks the chain at that exact seq.
Every span: SHA-256(canonical body) + HMAC(prev_hash + canonical_hash, secret). RFC 8785 JCS canonicalization. WAL + BEGIN IMMEDIATE for multi-writer correctness.
686 unit tests + 46 production-tests across 3 rounds. Zero failures post-v2.0.5. Validated under 16-way concurrent writers, SIGKILL recovery, and direct DB tampering.
Exported archives verify bit-identically across x86_64 ↔ aarch64. HMAC + JCS are architecture-independent by construction. Live on 2 independent production systems: GENA (9-ecosystem AI mesh, x86_64, Nuremberg) and ARA (AI Research Agency, aarch64, Helsinki).
200 spans across 14 days. Real HMAC chain produced by bijotel 2.0.5. Run three commands. Get cryptographic proof in <1 second.
pip install bijotel
curl -O https://bijotel.whiteandpoint.com/demo_chain.json
bijotel verify-export demo_chain.json \ --secret-hex bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded00000
We pre-built a variant with exactly one byte flipped in entry seq=100. The HMAC chain links are still correct — but the canonical_body integrity check (added in v2.0.3) catches it.
curl -O https://bijotel.whiteandpoint.com/demo_chain_tampered.json bijotel verify-export demo_chain_tampered.json \ --secret-hex bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded00000
Same data your bijotel verify-export call processes. Filter, paginate, click any row for full canonical body.
| seq | Time (UTC) | Provider | Model | Tokens (in/out) | Prompt excerpt |
|---|
Already using Langfuse / LangSmith / Helicone? Keep them. BIJOTEL adds what observability tools don't try to do.
| Your observability tool (Langfuse, LangSmith, Helicone) |
BIJOTEL (adds on top) |
|
|---|---|---|
| LLM call logging | ✓ | ✓ |
| Developer dashboard | ✓ | ✓ (bundled) |
| Prompt evaluation | ✓ | — |
| Streaming support | ✓ | — |
| HMAC tamper-evident chain | — | ✓ |
| Pre-call jailbreak gate (50 patterns) | — | ✓ |
| AST code safety check | — | ✓ |
| Regression drift detection | — | ✓ |
| Energy/CO₂ per-call tracking | — | ✓ |
| Multi-model consensus voting | — | ✓ |
| EU AI Act Article 12 support | — | Designed for |
BIJOTEL wires alongside your existing observability. Same SDK, same spans — observed by both, sealed only by BIJOTEL.
What BIJOTEL is — and what it is not.
# Install pip install "bijotel[anthropic]" # 3 lines in your code (lifespan / startup) from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor from bijotel.processors import HmacChainSpanProcessor provider = TracerProvider() provider.add_span_processor(HmacChainSpanProcessor( db_path="chain.db", secret_key=bytes.fromhex(os.environ["BIJOTEL_HMAC_SECRET"]), )) trace.set_tracer_provider(provider) AnthropicInstrumentor().instrument() # Every messages.create() is now sealed in chain.db # Verify any time: bijotel verify --db chain.db
BIJOTEL is built by white&point, the product arm of Aisophical SRL (Bucharest, Romania).
Research artefacts and philosophy live at aisophical.com. Products ship at whiteandpoint.com. Code distributes via GitHub and PyPI.
Contact: [email protected] · LinkedIn · GitHub