Skip to content

Support the new DataCollection option (successor to SendDefaultPii) #5420

Description

@jamescrosswell

Overview

The DataCollection spec replaces the binary SendDefaultPii flag with a structured DataCollection option that gives users per-category control over automatically collected data:

  • UserInfo (id/email/username/ip) — default true
  • Cookies, HttpHeaders (request/response), UrlQueryParams — key-value collection behavior: off / denyList (default) / allowList over a canonical sensitive-terms denylist, values replaced with [Filtered]
  • HttpBodies — which of the four directions (incoming/outgoing × request/response) to attach
  • GraphQL (document/variables), GenAI (inputs/outputs), DatabaseQueryData, Queues, StackFrameVariables, FrameContextLines

Reference implementation: sentry-javascript, tracked in getsentry/sentry-javascript#20141 (foundation PR getsentry/sentry-javascript#20965). JS shipped the entire migration in v10 minor releases with zero behavior changes for existing users; removal of sendDefaultPii is deferred to their next major.

Strategy

Following the JS playbook:

  • Resolve once, read everywhere: DataCollection is resolved to an internal fully-populated config at SDK init; all consumers read only the resolved object.
  • Bridge: when DataCollection is not set, the resolved config is derived from SendDefaultPii (true → everything on; false/unset → restrictive + GDPR deny-terms). If both are set, SendDefaultPii is ignored.
  • New permissive defaults (user identity and HTTP bodies collected by default) apply only when the user explicitly sets DataCollection — nobody's behavior changes until the next major.
  • User-set data is never gated (e.g. an explicitly set User); DataCollection only gates automatic collection.
  • Integration-level options take precedence over the global DataCollection layer (e.g. MaxRequestBodySize, SentryAIOptions.RecordInputs).
  • Every PR is independently shippable and behavior-neutral. Phase 0 tightens default privacy with no new API and is useful standalone.

Phases

Phase 0 — Hardening pre-work (no new API, each independently useful)

Phase 1 — Foundation (option is a documented no-op after this)

Phase 2 — Consumer migrations (behavior-neutral, one PR per area)

Phase 3 — Deprecation (minor)

Phase 4 — Defaults flip (minor, only for explicit DataCollection users)

Phase 5 — Next major

.NET-specific notes

  • Native propagation: until sentry-java / sentry-cocoa implement the spec, the resolved config is down-converted to the native sendDefaultPii boolean (conservatively).
  • Config binding: the option shape must bind from appsettings.json (BindableSentryOptions and friends) — a requirement JS didn't have.
  • [Obsolete] timing: unlike JSDoc @deprecated, [Obsolete] produces compiler warnings that break TreatWarningsAsErrors builds. Docs/changelog deprecation lands in a minor; attribute timing to be decided (see the deprecation sub-issue).
  • Spec categories .NET can't act on yet (Queues — no queue integration captures args; StackFrameVariables / FrameContextLines — native-layer only): included in the option shape from day one and forwarded to native where relevant. JS added graphQL/databaseQueryData late and had to re-gate integrations (getsentry/sentry-javascript#22219) and rename queryParamsurlQueryParams (getsentry/sentry-javascript#22217) — we use final spec names from the start.
  • Docs work (options page, migration guide, "data collected" pages) is tracked separately in sentry-docs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureNew feature or requestTracking Issuepublic APIAdditions/modifications to, or removals from, the public API surface area.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions