Sentry is valuable because it collects context around a failure. In a healthcare application, that context can include patient identity, appointment details, clinical responses, access tokens, URLs, request data, or screen content. The engineering target is useful diagnostics that do not depend on raw identity, clinical text, or production payloads.
The safer sequence is: decide whether the vendor may receive PHI, map every capture surface, define an allowed telemetry schema, filter before transmission, scrub again before storage, minimize access and retention, and test the complete route through alerts and integrations.
Decide whether Sentry may receive PHI
HHS says a cloud provider that creates, receives, maintains, or transmits ePHI for a regulated organization is a business associate and requires an appropriate business associate agreement. HHS also says the customer must understand the cloud service, perform its own risk analysis, and establish risk-management policies. A vendor security page or HIPAA attestation does not replace those steps.
If PHI may reach Sentry, obtain the executed agreement before transmission and confirm the covered legal entity, account, plan, region, services, subprocessors, support path, incident duties, deletion, and retention. Ask expressly about errors, tracing, logs, metrics, profiling, replay, user feedback, attachments, AI features, and integrations; do not infer that a new feature is covered because the core service is.
If the agreement or internal approval does not cover the complete data path, design Sentry as a no-PHI destination or keep it out of that workflow. A no-PHI design still needs testing because an accidental disclosure can occur before a server-side setting gets a chance to act.
Map every capture surface
Errors and attachments
Messages, exception values, stack frames, local variables, causes, screenshots, minidumps, log files, and manually added context.
Requests and users
Full URLs, query strings, headers, cookies, bodies, GraphQL variables, route parameters, IP addresses, and user.* fields.
Activity
Automatic and manual breadcrumbs, console output, navigation, fetch/XHR metadata, feature flags, logs, metrics, and feedback.
Rich telemetry
Transactions, spans, profiles, session replay, DOM and media, AI inputs and outputs, alerts, exports, and integrations.
Build the inventory per SDK and version. JavaScript, native, mobile, and server SDKs do not have identical defaults. Integrations also add fields after initialization, so an approved baseline should identify the SDK package, version, integrations, feature flags, and every outbound product.
Configure collection explicitly
The current JavaScript documentation requires version-aware handling. sendDefaultPii defaults to false, but it is deprecated for removal in v11. The replacement dataCollection option is available from 10.57.0. When dataCollection is used, unspecified categories have permissive defaults: user information, headers, cookies, query parameters, request and response bodies, generative-AI content, stack-frame variables, and source context may be collected.
The docs also say full request URLs are always sent and explicit values such as Sentry.setUser() are sent regardless of dataCollection. Treat SDK defaults as a starting fact to verify, not as the privacy boundary.
Sentry.init({
dsn: SENTRY_DSN,
dataCollection: {
userInfo: false,
cookies: false,
httpHeaders: false,
httpBodies: [],
urlQueryParams: false,
genAI: { inputs: false, outputs: false },
stackFrameVariables: false,
frameContextLines: 0
},
enableLogs: false,
enableMetrics: false,
tracesSampleRate: 0,
replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 0
});
This is a conservative JavaScript 10.57+ starting point, not a universal configuration. Verify the exact option names and behavior for the installed SDK and framework. For an older SDK that does not support dataCollection, keep sendDefaultPii: false and audit its data-collected page and enabled integrations. Do not copy JavaScript settings into another platform and assume they mean the same thing.
Use the hook for each telemetry type
beforeSend is the final hook for error and message events after scope data has been applied. It does not automatically cover transactions, spans, logs, breadcrumbs, attachments, replay, or every integration payload. Wire the corresponding control for every enabled product:
| Surface | Control | Important limit |
|---|---|---|
| Errors and messages | beforeSend | Return null when an event cannot be made safe. |
| Transactions | beforeSendTransaction | Separate from beforeSend; return null to drop. |
| Spans | beforeSendSpan and ignoreSpans | The hook can modify but not drop spans; use ignoreSpans for dropping. |
| Logs | beforeSendLog | Logs are sent only when enabled, but attributes still need an allowlist. |
| Metrics | beforeSendMetric | Current JavaScript SDKs enable metrics by default; names and attributes need review. |
| Breadcrumbs | beforeBreadcrumb | Return null to discard unsafe automatic or manual breadcrumbs. |
| Attachments | hint.attachments in beforeSend or a global processor | Attachments are separate payload items; sanitizing the event object does not sanitize file bytes. |
| Replay | Replay privacy options and beforeAddRecordingEvent | Replay has its own capture and masking model. |
Event processors are useful for shared enrichment and scoped behavior, but Sentry documents their execution order as undetermined. Global processors run broadly; scope processors only apply while that scope is active. Use the final send hooks as the last validation gate, and test that framework integrations cannot append unsafe data afterward.
Sentry.init({
// ...explicit collection settings above...
beforeBreadcrumb: sanitizeBreadcrumb,
beforeSend: sanitizeErrorEvent,
beforeSendTransaction: sanitizeTransaction,
beforeSendSpan: sanitizeSpan,
beforeSendLog: sanitizeLog
});
function sanitizeErrorEvent(event, hint) {
if (hint.attachments) hint.attachments = [];
const safe = projectToAllowedErrorSchema(event);
return passesNoPhiChecks(safe) ? safe : null;
}
The functions above are architecture placeholders, not a complete sanitizer. Project telemetry into an allowlisted schema instead of recursively deleting suspicious key names. A denylist cannot reliably recognize clinical values, free text, renamed fields, encoded values, or identifiers embedded in URLs and error messages.
Normalize before capture
| Field | Risk | Safer pattern |
|---|---|---|
| URL | Patient IDs, emails, appointment IDs, search terms | Controlled route template such as /patients/:id/results |
| Error message | Backend or validation text may echo input | Stable error code and component name |
| Request body | Forms and API payloads may contain full clinical records | Do not attach; keep only approved metadata |
| User context | Name, email, IP address, medical record number, account details | Clear user; use a narrowly governed opaque incident token only when approved |
| Breadcrumb | Clicked labels, navigation text, console output | Allowlisted action and route category |
| Attachments | Screenshots, minidumps, logs, and files can contain complete records | Disable or clear by default; allow only reviewed synthetic artifacts |
| Local variables | Application objects may contain credentials or PHI | Disable unless a reviewed need and test justify capture |
Enable server-side scrubbing
Sentry exposes organization and project controls for data scrubbing, default scrubbers, custom sensitive fields, advanced rules, and IP-address removal. Enable and verify them as a second boundary so a missed SDK path is less likely to be stored. Do not assume the settings are enabled merely because the project exists.
Prefer removal over masking when a field has no diagnostic value. Add application-specific field names and patterns for patient, member, appointment, encounter, medical record, date of birth, phone, email, token, authorization, and clinical data. Test nested objects, arrays, alternative names, case changes, query strings, and message text.
Sentry's organization API documents that advanced scrubbing rules apply only to new incoming events. They do not retroactively clean stored data. Maintain an accidental-collection procedure that can disable ingestion, preserve appropriate audit evidence, identify downstream copies, and route deletion and incident assessment to authorized owners.
Keep replay off until proven safe
Start with replay disabled. Current browser Replay defaults mask all text and inputs and block media on the client, but replay still records DOM structure, interactions, basic fetch/XHR details including URLs, and console messages. The Replay docs explicitly require production masking tests and warn that UI-framework or SDK updates can change behavior.
If a reviewed product case justifies replay, confirm agreement scope, keep maskAllText, maskAllInputs, and blockAllMedia enabled, block sensitive routes and components, avoid network body allowlists, filter console recording, restrict replay access, and use the minimum sampling required. Test patient-facing states, validation errors, modals, custom inputs, canvases, third-party widgets, and UI changes. If a sensitive component cannot be verified, keep replay off for that route.
Observability features share the same risk
JavaScript logs are disabled by default, but console messages can still appear as breadcrumbs, and Replay captures console messages by default. If logs are enabled, send controlled templates and categorical attributes through beforeSendLog; never pass arbitrary objects, prompts, responses, SQL parameters, support text, or request payloads.
Tracing starts only when sampling is configured, but transactions and spans can contain full URLs, dynamic names, database statements, attributes, and AI content. Use route templates, restrict tracePropagationTargets, sanitize transaction and span data with their dedicated hooks, and use ignoreSpans when a span type should not leave the process. Disable generative-AI inputs and outputs unless a separately reviewed workflow needs them.
Keep profiling and stack-frame variables off unless their diagnostic value and data behavior have been reviewed. Sampling reduces volume; it is not a privacy control because any sampled item may still contain sensitive data.
Minimize retention, access, and copies
Record the actual retention for every enabled data type and plan rather than assuming one number covers the product. Sentry's security page says event retention depends on data and plan type and backups are deleted 90 days after creation; its attachment documentation says attachments persist for 30 days. Use the shortest available period that satisfies the approved operational need, and verify deletion behavior for events, issues, attachments, replays, logs, profiles, exports, and backups.
Apply least privilege at the organization, team, and project levels. Require MFA, disable open membership and anonymous shared issues, limit production team membership, set attachment-download and replay permissions separately, restrict API-token scopes, review audit logs, and remove stale users and tokens. Do not assume the generic Member role is read-only; current Sentry role documentation says members can view and act on events.
A clean event can become an unsafe disclosure when an alert or integration copies fields into email, chat, issue tracking, source control, support, or an AI assistant. Keep notifications minimal and link authorized staff back to Sentry instead of copying payloads into broader systems. Map each downstream destination and separately confirm its agreement, access, retention, export, and deletion behavior.
Test the failure path, not just the happy path
- Use only synthetic canary values, with a unique test-run prefix, for names, emails, phone numbers, record numbers, dates, tokens, and clinical-looking free text. Never use real patient data for this test.
- Place the canaries in full URLs and query strings, headers, cookies, bodies, exception messages, stack variables,
user.*, tags, context, breadcrumbs, logs, metrics, transaction names, span attributes, attachments, feedback, AI inputs and outputs, and replayed screens. - Trigger handled and unhandled frontend, backend, mobile, network, validation, timeout, and crash paths. Exercise every enabled integration and confirm local privacy hooks actually run.
- Inspect the serialized outbound envelopes in a controlled test transport or proxy before they reach Sentry. This proves the SDK boundary and catches attachment items that are not part of the event JSON.
- Inspect what Sentry stores after server-side scrubbing: raw event fields, issue details, users, breadcrumbs, logs, traces and spans, replays, profiles, attachments, and search indexes. Search for every unique canary.
- Inspect alerts, emails, exports, dashboards, issue trackers, chat messages, source integrations, support workflows, and AI features. Verify that a safe primary event did not create an unsafe downstream copy.
- Test least-privilege accounts, attachment and replay access, shared links, API tokens, audit logs, retention expiry, and the documented deletion and escalation path.
- Fail the release if any unapproved canary arrives. Repeat after SDK, framework, integration, schema, privacy-rule, product-feature, route, or UI changes.
Complete the review
Responding to Suspected PHI Exposure
Contain unsafe telemetry, preserve evidence, revoke access, assess scope, escalate the vendor, and recover safely.
Sentry vs Crashlytics
Compare vendor terms, PHI paths, and the appropriate use of each tool.
Healthcare Analytics Without PHI
Design allowlisted workflow events around controlled state instead of identity or clinical content.
HIPAA Vendor Checklist
Review BAA scope, features, subprocessors, retention, access, and incidents.
Official Sentry references: JavaScript data collected, SDK options, event processors, attachments, Replay privacy, organization privacy and access controls, and security, retention, and audit controls.
Official HHS references: HIPAA cloud-computing guidance and business associate guidance.