tracelane/tracelane
The flight recorder for AI agents. Apache 2.0. Contribute to tracelane/tracelane development by creating an account on GitHub.
1 stars · 0 forks
README
Tracelane flight recorder for AI agents.
Get started free → · Docs · Discussions
What it does Tracelane sits between your AI agents and your LLM providers. You get:
BYOK proxy — point agents at https://gateway.tracelane.dev, pass your own API key. 0% markup.
Full-fidelity traces — LLM calls, tool invocations, agent steps and retries captured as OTel spans using the GenAI semantic conventions, at full fidelity for everything routed through the gateway. Full capture is the default; there is no sampling you have to turn off. The one bound we do apply is a per-trace ceiling (10,000 spans / 64 MiB, env-tunable) so a runaway agent cannot exhaust your storage — it clips that trace, never your other traces.
Tamper-evident audit ledger — every recorded event is hash-chained per tenant and batch-anchored to a public transparency log. tlane verify re-checks the chain offline, from the export alone, with no call back to us. That is the part you can hand to an auditor.
Inline heuristic guardrails — cost, schema, and prompt-injection rails run in-request at the gateway (ML ensemble on the roadmap). Detection is observe-first by default: a rail records and flags rather than blocking, because a false-positive block breaks a legitimate run.
Cross-language ledger conformance — the audit verifier is implemented three times, in Rust, Python and TypeScript, and all three are held to one shared corpus of 8 conformance vectors that includes deliberately-forged and boundary-numeric cases. 10 Rust + 14 Python + 19 TypeScript conformance tests run in CI, plus a round-trip job asserting the three implementations agree. That is the suite behind "a third party can verify offline" — you can run it in this clone. Note the honest scope: evals/ here carries the 20 conformance evals; some internal suites target private ADRs and infrastructure and are not part of this repo, so the test script says so rather than pretending to pass.
Time-travel trace viewer — step through any recorded agent trace span-by-span with tlane replay (read-only). Cross-model re-execution is on the roadmap.
MCP tool-definition pinning and lethal-trifecta detection — shipped, and free on every tier including OSS self-host. Both run as guardrail rails in-request at the gateway: pinning compares a live tool definition against the hash you approved and flags divergence; the trifecta rail flags the untrusted-input + private-data + exfiltration-path combination. Observe-first, like every other rail.
Not shipped — named here because they appear elsewhere in our docs and we would rather you learn it from us than from the source. These are part of the predictive layer, separate from the rails above, and none of them fires on LLM traffic today — for two different reasons:
Browser stuck-loop prediction and A2UI catalog conformance gate on payload fields (mcp_server_name, tool_name, protocol) that a /v1/chat/completions request does not carry, so they never reach their scoring path. The distilled SLM judge is not enabled: no trained model ships, so it cannot flag anything.
See apps/docs/predictive-guardrails.mdx for per-rail status. How Tracelane compares
Tracelane LiteLLM Portkey Langfuse LangSmith
Measured gateway overhead (p50) 2 ms † partial (Python proxy 14–15 ms, same bench; Rust build not public) 3–4 ms, same bench run — (no gateway) — (no gateway)
Rust hot path ✓ — (Python proxy measured; Rust gateway announced, no public build) — (TypeScript/Node.js) — (no gateway) — (no gateway)
BYOK, 0% token markup ✓ ✓ ✓ — partial (lists an LLM Gateway; BYOK not documented)
OTel-native ingest ✓ partial partial ✓ partial
Multi-agent swimlanes ✓ — — ✓ ✓
Sessions ✓ (per-user identity on the roadmap) — — ✓ ✓
Eval loop (datasets, experiments, online evals, annotation queues, CI gate) ✓, proven on prod — — ✓ ✓
Prompt management + playground ✓ — ✓ ✓ ✓
MCP server for traces ✓ (@tracelanedev/mcp on npm) — — — —
Claude Code flight recorder ✓ — — — —
Tamper-evident ledger, offline-verifiable ✓ — — — —
Self-host, single Compose file ✓ ✓ ✓ ✓ (+ Kubernetes) partial (Enterprise BYOC)
License Apache 2.0 MIT (core) MIT MIT none for OSS; Enterprise self-hosted SKU is proprietary
✓ = shipped and documented · partial = supported with a real limit · — = not documented on the vendor's own page as of 2026-09-07 (not necessarily absent). Not yet: SOC 2 report, configurable data residency, HIPAA/BAA, documented SAML SSO, contractual SLA, documented Slack/PagerDuty alert integrations. Stated as limits, not discovered as gaps — see the full matrix for what each competitor has instead. Full matrix with sources: https://docs.tracelane.dev/comparisons † Benchmark: 2 ms p50 / 4 ms p95 / 5 ms p99 added latency on LiteLLM's AIGatewayBench harness (4 vCPU, two runs, capture on) — https://docs.tracelane.dev/benchmarks Quick start Hosted (zero infra):
1. Sign up at https://app.tracelane.dev → Settings → API Keys → Create
export TRACELANE_API_KEY=tlane_... export TRACELANE_GATEWAY_URL=https://gateway.tracelane.dev Self-host (Docker Compose): git clone https://github.com/tracelane/tracelane cd tracelane cp infra/self-host/.env.example infra/self-host/.envEdit infra/self-host/.env and set BOTH:
TRACELANE_MASTER_KEY — your gateway key: openssl rand -base64 32
a provider key — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.
Without a provider key the gateway starts fine and every request 401s.
docker compose -f infra/self-host/docker-compose.yml up -d
Load the file you just edited INTO YOUR SHELL. `export FOO="$BAR"` cannot work
here — BAR was set in a file, so it is empty in the shell and the gateway
answers 401 on your very first request.
set -a; source infra/self-host/.env; set +a export TRACELANE_GATEWAY_URL=http://localhost:8080 export TRACELANE_API_KEY="$TRACELANE_MASTER_KEY" Add --build to compile the gateway and ingest from source instead of pulling the published images. That is a full Rust release build of the workspace and takes roughly 25 minutes on 8 cores — the images are the fast path, and --build is for when you are changing the code. Self-host runs headless: the compose file brings up ClickHouse, NATS, the gateway (:8080) and ingest. There is no dashboard container — the web UI is hosted-only today. Authenticate with the TRACELANE_MASTER_KEY from your .env; per-key minting via POST /v1/keys needs a Postgres control plane, which self-host does not run. The tamper-evident audit ledger DOES run in self-host, with one limit worth knowing before you rely on it. Events are hashed into the chain and persisted to ClickHouse audit_log (the hosted product keeps the canonical ledger in Postgres and copies it to ClickHouse; a self-host without Postgres has only the ClickHouse chain) — measured on a clean stack, four chat requests produce eight linked rows with zero chain breaks. What self-host does not have is chain resumption across a gateway restart. The head is recovered from the Postgres control plane, which self-host does not run, so on restart the sequence begins again at genesis and you get duplicate seq values that an offline verifier cannot reconstruct across the boundary. In practice: the ledger is verifiable within a gateway lifetime, and a restart starts a new segment. If you need one continuous, offline-verifiable chain across restarts today, that is Tracelane Cloud. We would rather state the boundary than let you find it in a verifier's output. (infra/dev/docker-compose.yml is the contributor data-plane — ClickHouse, NATS, Postgres, Grafana on :3001 — and deliberately starts no gateway. Use it with cargo run -p gateway when hacking on the gateway itself.) Then instrument your agent with the SDK — explicit init() + per-client wrapping (nothing is patched on import). endpoint is https://gateway.tracelane.dev on Tracelane Cloud (the key needs the ingest scope) or the receiver you run when self-hosting: from tracelane import init, instrument_anthropicinit(endpoint="https://gateway.tracelane.dev", api_key="tlane_...")
from anthropic import Anthropic
client = Anthropic() instrument_anthropic(client) # now messages.create() emits spans import { init, instrumentOpenAI } from "@tracelanedev/sdk";
init({ endpoint: "https://gateway.tracelane.dev", apiKey: process.env.TRACELANE_API_KEY!, });
import OpenAI from "openai"; const client = new OpenAI(); instrumentOpenAI(client); // now chat.completions are traced Architecture Agent / SDK │ ▼ ┌─────────────────────────────────────┐ │ Rust Gateway (Axum + tokio) │ │ - BYOK routing to 191 providers │ │ - Inline heuristic guardrails │ │ - OTLP span emit │ └────────────────┬────────────────────┘ │ NATS JetStream ▼ ┌─────────────────────────────────────┐ │ Rust Ingest Workers │ │ - High-throughput batch writes │ │ - ClickHouse batch writes │ │ - Full-fidelity capture (default) │ └────────────────┬────────────────────┘ │ ┌───────────┴───────────┐ ▼ ▼ ClickHouse Cloudflare (hot tier) R2 (cold, roadmap)
Repository structure
Path Language Purpose
crates/gateway/ Rust BYOK LLM proxy, inline guardrails, audit chain
crates/ingest/ Rust OTLP receiver, NATS consumer, ClickHouse writer
crates/shared/ Rust Shared types (ChatRequest, TracelaneSpan, TenantId)
crates/tracelane-audit-cli/ Rust tracelane-audit — standalone offline ledger verifier
crates/policy/ Rust PII redactors (wired into the audit + guardrail paths) + a Cedar policy-engine scaffold that is not wired in V1
apps/web/ TypeScript Next.js 15 dashboard
apps/mcp/ TypeScript Tenant-scoped MCP server
packages/sdk-typescript/ TypeScript Agent instrumentation SDK
packages/sdk-python/ Python Agent instrumentation SDK
packages/cli/ TypeScript tlane CLI
evals/ TypeScript 20 conformance evals — 10 fault-tolerance, 7 gateway-correctness, and one each for ingest-schema, PII-redaction and prompt-injection
ml/ Python Trajectory Guard / SLM judge — training + export pipeline; no trained weights ship yet
spec/openagenttrace/ Markdown OpenAgentTrace v0.1 spec
spec/aft-1/ Markdown Agent Failure Taxonomy — 13 published failure modes
infra/dev/ YAML/SQL Docker Compose + ClickHouse schema
The tracelane.dev marketing site is hosted separately and is not part of this repository: its source is mostly deployment configuration for the hosted service (edge worker bindings, the sign-up form backend, production security headers), which nobody building, self-hosting or verifying Tracelane needs. Development
Prerequisites: Rust 1.95 (pinned in rust-toolchain.toml; MSRV 1.88), Node.js 22+, pnpm 9+
pnpm install cargo build --workspace
Start local services
docker compose -f infra/dev/docker-compose.yml up -dRun gateway
cargo run -p gatewayRun ingest
cargo run -p ingestRun the tests
cargo test --workspace --all-features pnpm test Migrating from LiteLLM Tracelane's gateway is memory-safe Rust with no admin configuration endpoints, no eval, and no import-by-string of untrusted config. If you are moving an existing LiteLLM deployment, the importer reads your config directly. One command reads your existing config and emits a Tracelane gateway config: npx @tracelanedev/cli import-litellm --config litellm_config.yaml Then point your agents at TRACELANE_GATEWAY_URL. The gateway is OpenAI-path compatible (/v1/chat/completions), and the request body follows the Anthropic tool schema ({name, description, input_schema}). Both tool shapes are accepted: an OpenAI-shaped tools: [{type: "function", function: {...}}] array and the Anthropic shape are normalised to one internal representation, so no request rewriting is required. Full guide: docs.tracelane.dev/migrations/from-litellm Verifying Tracelane releasesUse a current cosign release to verify.
cosign verify-blob \ --bundle gateway-x86_64-unknown-linux-gnu.cosign.bundle \ --certificate-identity-regexp="https://github.com/tracelane/tracelane/.*" \ --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ gateway-x86_64-unknown-linux-gnu All binaries are Cosign-signed (keyless OIDC) with build provenance attested via actions/attest-build-provenance, and a CycloneDX SBOM is published with each release. We use Grype + Syft + OSV-Scanner (not Trivy) in CI. Honest note on this repository: it is published from a separate development tree. Commits here are squashed publications, so main carries no branch protection and no review history you can inspect. Judge the code and the releases, not the commit graph. Migrating from Helicone One command rewrites your Helicone base URL and auth headers to Tracelane (config + environment only — no trace re-import needed): npx @tracelanedev/cli migrate helicone --apply Full guide: docs.tracelane.dev/migrations/from-helicone Pricing OSS self-host is $0 forever under Apache 2.0, with no commercial restriction. What it runs is the headless stack — ClickHouse, NATS, gateway and ingest; there is no dashboard container, and the web UI is hosted-only today (see Self-host above). Hosted tiers (free / $29 Builder / $229 Team / $799 Business / $2,499+ Enterprise), metered on six usage dimensions (ingest, hot indexed window, series, query compute, cold archive, evaluations) with unlimited seats on every paid tier, are documented at tracelane.dev/pricing, and the same ladder is published at docs.tracelane.dev/pricing. CommunityDiscussions: github.com/tracelane/tracelane/discussions — ask questions, share traces, get help Issues: github.com/tracelane/tracelane/issues Security: security@tracelane.dev (90-day responsible disclosure)
Star history
License Apache 2.0. See LICENSE and LICENSE-PLEDGE.md. Apache 2.0 grants are perpetual and irrevocable, so every release already published under Apache 2.0 stays Apache 2.0 — neither we nor any future owner can take that back. LICENSE-PLEDGE.md sets out what we commit to beyond that, and is explicit about where the commitment is enforceable and where it is only a promise.