You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Product telemetry: consent model + export to the public OTLP ingest #29
musher-dev/infra#760 gives the estate a public, authenticated OTLP ingest that the Python SDK can send product telemetry to: errors, API-call usage and latency for Musher's own observability, not customer data.
Tier
Endpoint
prod
https://otlp.musher.dev/otlp
non-prod
https://otlp.staging.musher.dev/otlp
Both are standard OTEL_EXPORTER_OTLP_ENDPOINT bases: the SDK appends /v1/traces and /v1/logs. Use OTLP/HTTP only; gRPC is not exposed.
Asks
Decide the consent model. Infra deliberately left this to this repo. Prior art: gh CLI (GH_TELEMETRY + DO_NOT_TRACK); for a library, default-off is the norm.
Honour DO_NOT_TRACK (any truthy value) and OTEL_SDK_DISABLED=true.
Add a product switch (e.g. MUSHER_TELEMETRY=0) plus a config setting.
Document what is collected.
Say whether the default is opt-in or opt-out.
Embed the ingest key at release build.
Infra publishes a signed JWT key for client=sdk as a GitHub Actions variable; it is not secret.
Send it as Authorization: Bearer <key>.
If the SDK is later given a user session, it may prefer the platform-api aud=otlp session token (see the platform-api issue linked in musher-dev/infra#760).
Scrub. Send no file paths, args, env values or hostnames. The collector also deletes host.name and applies a fail-closed attribute allowlist, but the producer is the first line of defence.
Set service.name.service.name=musher-python-sdk and service.version are informational: the collector overwrites identity from the key's claims.
Blocked on
Infra rollout of musher-dev/infra#760, phases 1 and 3.
Later, not now
Customers' own app telemetry through the SDK (multi-tenant ingest) is a separate future feature. Infra reserves a tenant claim for it. This issue covers Musher's product telemetry about SDK usage only.
The ingest exists now (musher-dev/infra#800), so here is the export contract:
Endpoint.https://otlp.musher.dev/otlp for every tier: OTLP/HTTP …/v1/traces and …/v1/logs. gRPC and metrics are not accepted.
Auth.Authorization: Bearer <key>. Each client is an Ed25519 key issuer, and the token's claims (client, env, service) set service.name and deployment.environment.name at the gateway. Whatever the payload says is overwritten.
Volume. Cloudflare rate-limits /otlp/v1/ to 20 req / 10 s per colo + IP. Batch.
No key exists for this client yet. Only console, backstage and edge-workers are minted. When the consent model is settled and you're ready to export, ask infra for a client. On our side that means a generation in terraform/platform/signing-material (otlp_ingest_key_generations), a provider in the gateway's config/15-admit.yaml, and the JWKS re-baked into the image. A CLI binary can't keep a secret either, so like the browser keys, the key is an identifier rather than a credential. If per-user attribution matters, platform-api#722's session token is the better path.
Activity
justinmerrell commentedon Oct 25, 2026
The ingest exists now (musher-dev/infra#800), so here is the export contract:
https://otlp.musher.dev/otlpfor every tier: OTLP/HTTP…/v1/tracesand…/v1/logs. gRPC and metrics are not accepted.Authorization: Bearer <key>. Each client is an Ed25519 key issuer, and the token's claims (client,env,service) setservice.nameanddeployment.environment.nameat the gateway. Whatever the payload says is overwritten./otlp/v1/to 20 req / 10 s per colo + IP. Batch.No key exists for this client yet. Only
console,backstageandedge-workersare minted. When the consent model is settled and you're ready to export, ask infra for a client. On our side that means a generation interraform/platform/signing-material(otlp_ingest_key_generations), a provider in the gateway'sconfig/15-admit.yaml, and the JWKS re-baked into the image. A CLI binary can't keep a secret either, so like the browser keys, the key is an identifier rather than a credential. If per-user attribution matters, platform-api#722's session token is the better path.🤖 Generated with Claude Code