* Enable trusted trace object upload authority * Fix trace object authority registration edge cases Generated-By: looper 0.9.4 (runner=fixer, agent=codex)
Open Design Telemetry Relay
Cloudflare Worker relay for opt-in Open Design telemetry. The shipped desktop client sends redacted Langfuse ingestion batches here after the user enables metrics. This Worker holds the Langfuse write credentials and forwards valid batches to Langfuse.
The relay keeps Langfuse secret keys out of packaged clients. Release builds only include the public relay URL; the Worker adds Langfuse authentication server-side after validating the request. If the relay is unavailable, the daemon retries, logs the failure, and continues the user flow without blocking the CLI or desktop app.
The same Worker also exposes a write-only trace object ingest endpoint at
POST /api/objects/batch. It accepts Open Design observability objects such as
attachments, produced artifacts, and over-threshold input text snapshots, writes
them through the TRACE_OBJECT_BUCKET R2 binding, and returns trace-safe
storage_ref / sha256 / size metadata for Langfuse manifests.
Object ingest accepts a short-lived upload token signed by Worker-held
authority. The Worker issues that token only after the same Worker has already
seen the run's trace-safe object scope in a normal /api/langfuse telemetry
batch and stored it in TRACE_OBJECT_SCOPE_KV. Caller-supplied metadata plus
the public marker header is not enough to authorize a production upload. The
long-lived signing secret stays in the Worker and is never packaged into the
daemon/client.
Local development can bypass the relay by setting direct LANGFUSE_PUBLIC_KEY
and LANGFUSE_SECRET_KEY environment variables for the daemon. Packaged
release config should use only OPEN_DESIGN_TELEMETRY_RELAY_URL.
Abuse controls
The Worker requires the Open Design telemetry marker header, validates the Langfuse ingestion batch shape and size before forwarding, and uses Cloudflare Rate Limiting bindings for two independent keys:
TELEMETRY_CLIENT_RATE_LIMITER: anonymous installation/user id, 120 requests per minute.TELEMETRY_IP_RATE_LIMITER: CloudflareCF-Connecting-IP, 600 requests per minute.
Object ingest uses the same rate limit bindings with a separate marker value,
X-Open-Design-Telemetry: object-ingestion-v1. POST /api/objects/batch must
include a signed upload token, and the Worker re-checks the namespace, size, and
sha256 before writing to R2. POST /api/objects/authorize reads only bounded
metadata, checks that every requested object exactly matches a previously
registered telemetry scope, then returns a five-minute token. The Worker also
applies IP rate limiting before reading object bodies. It enforces a 10 MiB
single-object limit and a 20 MiB request-body limit by default. Oversized
objects are reported as unavailable instead of being written.
Secrets
pnpm --dir apps/telemetry-worker dlx wrangler secret put LANGFUSE_PUBLIC_KEY
pnpm --dir apps/telemetry-worker dlx wrangler secret put LANGFUSE_SECRET_KEY
pnpm --dir apps/telemetry-worker dlx wrangler secret put TRACE_OBJECT_UPLOAD_SECRET
LANGFUSE_BASE_URL defaults to https://us.cloud.langfuse.com in
wrangler.toml.
Object ingest should use a Cloudflare R2 binding, not S3/R2 access keys in the packaged client or daemon. Required worker configuration:
[[r2_buckets]]
binding = "TRACE_OBJECT_BUCKET"
bucket_name = "open-design-observability"
[[kv_namespaces]]
binding = "TRACE_OBJECT_SCOPE_KV"
id = "<cloudflare-kv-namespace-id>"
[vars]
TRACE_OBJECT_PREFIX = "observability"
TRACE_OBJECT_MAX_BYTES = "10485760"
TRACE_OBJECT_BATCH_MAX_BYTES = "20971520"
Deploy
pnpm --filter @open-design/telemetry-worker deploy
After deploy, set the repository variable OPEN_DESIGN_TELEMETRY_RELAY_URL to
the Worker route, for example:
https://telemetry.open-design.ai/api/langfuse
Opening /api/langfuse or /health in a browser returns relay health JSON.
Telemetry ingestion still uses POST to /api/langfuse.
Object ingestion uses POST to /api/objects/batch.
Release workflows bake only this public relay URL into packaged config. The Langfuse secret key stays in Cloudflare Worker secrets.