Every AI decision. Sealed. Verified. Provable.

Tamper-evident HMAC audit chain for LLM applications. Cryptographically link every span. Detect tampering. Prove provenance to regulators.

pip install bijotel
spans in demo chain
days of history
providers
models
1000+
unit tests passing
46
production tests · 0 fail

What makes it forensic

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.

🔒

SEALED

Every span: SHA-256(canonical body) + HMAC(prev_hash + canonical_hash, secret). RFC 8785 JCS canonicalization. WAL + BEGIN IMMEDIATE for multi-writer correctness.

VERIFIED

1000+ unit tests + 46 production-tests across 3 rounds. Zero failures through v2.16.0. Validated under 4 concurrent writer processes, SIGKILL recovery, and direct DB tampering.

🌍

PORTABLE

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) — together sealing 46,000+ spans across 70+ days of continuous operation, 0 chain breaks.

Verify this demo chain yourself

200 spans across 14 days. Real HMAC chain, bijotel-chain-v1 format — verifies on current bijotel (2.16.0). Run three commands. Get cryptographic proof in <1 second.

1
Install BIJOTEL
pip install bijotel
2
Download the demo chain
curl -O https://bijotel.whiteandpoint.com/demo_chain.json
200 spans, 302KB, bijotel-chain-v1 format
3
Verify integrity
bijotel verify-export demo_chain.json \
  --secret-hex bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded0bd1ed00aded00000
Public demo secret. Used only for this demo chain.
Expected output: Export VALID — HMAC chain verified.

Now try a tampered version

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
Expected output: Export INVALID: canonical_body tampered at seq=100: body hashes to c1711163… but canonical_hash claims 273564cf…

Browse the chain

Same data your bijotel verify-export call processes. Filter, paginate, click any row for full canonical body.

seqTime (UTC)ProviderModelTokens (in/out)Prompt excerpt

How BIJOTEL fits your observability stack

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
Rekor / Sigstore transparency-log anchoring
Cross-org federated verification
Deterministic replay verification
EU AI Act Article 12 supportDesigned for

BIJOTEL wires alongside your existing observability. Same SDK, same spans — observed by both, sealed only by BIJOTEL.

Honest scope

What BIJOTEL is — and what it is not.

BIJOTEL is NOT

  • A prompt evaluator (use Langfuse Eval, Braintrust)
  • A complete observability solution (use it alongside Langfuse, LangSmith, Helicone)
  • An error tracker (use Sentry)
  • Certified by any compliance body — yet
  • A replacement for legal review of your AI governance
It IS: a cryptographic forensic layer for audit traceability and tampering detection. Designed to support EU AI Act Article 12 record-keeping requirements.

Quickstart

# 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

About

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: contact@aisophical.com · LinkedIn · GitHub