Migrating onto Tracelane ingest mTLS
Audience: Design partners and early customers running a non-mTLS Tracelane ingest setup, or coming from another vendor’s plaintext OTLP endpoint. Operator runbook for SPIRE itself lives at SPIFFE/SPIRE ingest mTLS.Multi-tenant ingest enforces SPIFFE mTLS in release builds: those binaries bail at startup unless
TRACELANE_SPIRE_SOCKET is set. The documented exception is
single-tenant self-host, which can run plaintext (see below). This page walks you
from a fresh cluster (or one running plaintext dev ingest) to a
mTLS-only deployment. Confirm your exporters can buffer across the cutover before restarting ingest.
Pre-flight
If any of those is “no”, file an issue or reach out before continuing.
Migration in four steps
Step 1 — Bring up SPIRE (zero disruption to existing ingest)
Follow the operator runbook §1. At this point your existing plaintext ingest keeps running; SPIRE is installed but not yet wired into Tracelane.The ingest receiver has never read an
Authorization header. A
self-hosted ingest is either plaintext single-tenant (the tenant
comes from operator config, so there is exactly one and nothing to spoof) or
SPIFFE mTLS. A bearer token is what Tracelane Cloud’s gateway accepts at
POST /v1/traces; it is not an ingest mode.Step 2 — Register the workload entry
Pick the SPIFFE ID — it MUST match this exact shape (the path is enforced at parse time, not configurable):Step 3 — Cut ingest over to mTLS mode
Set the env vars before restarting:OTLP HTTP receiver listening (PLAINTEXT — dev only) instead,
you’re on a debug build. Multi-tenant release binaries do not run in plaintext;
re-pull from the release channel.
Step 4 — Update SDK / collector clients
Each agent that exports spans needs:- A client SVID — a SPIRE entry whose SPIFFE ID is exactly
spiffe://tracelane.dev/tenant/<your-workspace-uuid>/ingest-worker. The ingest server verifies the presented peer cert and enforces this full path shape (crates/ingest/src/auth.rs::parse_spiffe_id) — any other suffix (e.g./customer-app) or a non-UUID tenant segment is rejected fail-closed with401(result=invalid_path). Use theingest-workershape on the client side too; only the workspace UUID differs per tenant. - mTLS client config in your OTLP exporter pointing at the SPIRE agent socket so SDKs can read their own SVID at connect time.
TRACELANE_USE_SPIFFE=1 switch) is on the roadmap. Until then,
configure mTLS in your OTLP exporter directly — mount the SPIRE agent
socket into the exporter process and point its client TLS at it.
This applies to a self-hosted, multi-tenant ingest only. On Tracelane Cloud
the SDKs need no mTLS: they export to https://gateway.tracelane.dev with a
tlane_… key carrying the ingest scope, and the gateway forwards to ingest
inside its own network.
For non-SDK agents (raw OpenTelemetry Collector, fluentd, etc.) use the
go-spiffe or
java-spiffe helpers to
build the TLS config.
Failure modes you should expect to hit (and what to do)
Roll-back
If something goes wrong and you need to revert quickly:- Do not ship a debug build to prod. The plaintext fallback is debug-only and bypasses authentication entirely — re-deploying a debug binary as a “temporary workaround” silently disables ingest auth for every tenant.
- Stop ingest until SPIRE is fixed. The supervisor restart loop is the right place for this; new spans queue at the SDK side (default 60s buffer) so a brief outage doesn’t lose data.
- Open an incident via
[email protected]if you suspect a security regression — not a misconfiguration.
After migration
- Set up the Prometheus alerts in the operator runbook so a future SPIRE outage pages you, not your customers.
- Document your SVID rotation cadence and CA-rotation runbook locally; the Tracelane defaults (1h SVID TTL, hot bundle rotation) match SPIRE upstream defaults.
- For the Article-12 export (Enterprise plan), the same SVID identity is what binds audit events to the originating workspace. See Audit ledger for how this composes with the tamper-evident chain.