Skip to main content

ttt-otel

OpenTelemetry SpanProcessor that seals every LLM trace span into the Proof-of-Time (PoT) chain via api.kenosian.com.

Install it alongside any OTel-compatible LLM framework (Langfuse, Phoenix, OpenLLMetry, …) to get cryptographic, tamper-evident audit trails for every agent interaction — without modifying your existing tracing code.


How it works

LLM agent span ends
       │
       ▼
 TTTSpanProcessor.on_end()        ← non-blocking, span is never mutated
       │
       ▼
 Canonical fields extracted
 (trace_id, span_id, name, model,
  blake3(input), blake3(output), timestamps)
       │
       ▼
 content_hash = blake3(canonical_json)
       │
       ▼
 POST /pot/generate               ← background thread, never blocks export
   body: {eventId: content_hash,
          prevEventId: <last_hash>}
       │
       ▼
 Server returns {pot_hash, signature, timestamp_ns}
 Seal stored in-memory (+ optional file persist)

Privacy: raw prompt / completion text is never sent to the PoT server. Only the blake3 hash of each field travels over the wire.


Quick start

from opentelemetry.sdk.trace import TracerProvider
from ttt_otel import TTTSpanProcessor

provider = TracerProvider()
provider.add_span_processor(
    TTTSpanProcessor(api_key="<YOUR_TTT_API_KEY>")  # or os.environ["TTT_API_KEY"]
)

Tamper detection

from ttt_otel import verify
from ttt_otel._hash import canonical_fields_from_span

# Re-derive the hash from the original span and check it on the server
result = verify(
    canonical_fields_from_span(span),
    api_key="<YOUR_TTT_API_KEY>",
)
print(result["valid"])          # True  → seal matches
print(result["chain_intact"])   # True  → causal chain unbroken

If the span's output was modified after sealing, content_hash will differ from the sealed event_id on the server, so verify() returns valid=False.

See examples/tamper_demo.py for a self-contained 30-second demo.


Environment variables

Variable Default Description
TTT_API_KEY (required) API key (kns-…) for api.kenosian.com
TTT_SERVER_URL https://api.kenosian.com Override for self-hosted deployments

Installation

pip install ttt-otel          # once published to PyPI
# or, from source:
pip install .

Running tests

pytest

Works with any OpenTelemetry backend

TTTSpanProcessor is a standard SpanProcessor. It attaches to any TracerProvider alongside an OTLP exporter — the two processors run independently. You only need to swap the exporter's endpoint and auth header.

Backend OTLP/HTTP endpoint Auth header
Langfuse ✅ https://cloud.langfuse.com/api/public/otel/v1/traces Authorization: Basic base64(pk:sk)
Arize Phoenix ✅ Local: http://localhost:6006/v1/traces · Cloud: https://app.phoenix.arize.com/v1/traces Cloud: Authorization: Bearer <api-key>
MLflow 3.6+ ✅ http://<tracking-server>/v1/traces x-mlflow-experiment-id: <id>
Any OTLP-compatible collector Per-collector docs Per-collector docs

Helicone note: Helicone is an LLM proxy/gateway, not an OTLP backend. It does not expose an OTLP /v1/traces ingest endpoint. Use Arize Phoenix or MLflow if you need a direct OTLP-compatible observability backend.


Examples

File What it shows
examples/tamper_demo.py 3-span agent session, one span tampered, tamper detected
examples/langfuse_otel.py Langfuse OTLP pipeline + TTTSpanProcessor
examples/phoenix_otel.py Arize Phoenix OTLP pipeline + TTTSpanProcessor (local & cloud)
examples/mlflow_otel.py MLflow 3.6+ OTLP pipeline + TTTSpanProcessor

Metadata

Release files for ttt-otel 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ttt-otel 0.1.0
File Size Uploaded
ttt_otel-0.1.0.tar.gz 13.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ttt-otel 0.1.0
File Interpreter ABI Platform
ttt_otel-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.1 kB

Release files / ttt_otel-0.1.0.tar.gz

Download URL ttt_otel-0.1.0.tar.gz
Size 13.4 kB
Tags Source
SHA-256 checksum
How to use checksums
48ed17ad1cc0ad42c09205c93c2aedfca18e5f317b709401d82d9962c73bce33
BLAKE2b-256 checksum
How to use checksums
eda25296da1d056f3340bec77b050006399d77ccbeb0fb9fcc7e6c393e8618c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / ttt_otel-0.1.0-py3-none-any.whl

Download URL ttt_otel-0.1.0-py3-none-any.whl
Size 10.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c258b3157cfac1badc5c71257361bc62cc8b92df3f5bb607a7bebd5d5ee96d9
BLAKE2b-256 checksum
How to use checksums
e760beb166e37a2c9352d57a51f1081aa8e4fbfdc6b5d96a90b3d9e694ca5a68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page