Skip to content

Product telemetry: consent model + export to the public OTLP ingest #29

Open

Description

@justinmerrell

Context

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

  1. 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.
  2. 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).
  3. 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.
  4. 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.

Activity

  1. justinmerrell commented on Oct 25, 2026

    @justinmerrell
    ContributorAuthor

    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.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions