How Sentry's beforeSend Hook Scrubs PII Before Reports Are Sent in DeskcommCRM
DeskcommCRM's centralized sentryScrubHooks module intercepts every error, transaction, span, and breadcrumb through Sentry's beforeSend and related hooks to strip CPF numbers, emails, authorization headers, and URL tokens before telemetry leaves the runtime.
DeskcommCRM implements a comprehensive PII protection layer for Sentry 10 by centralizing all data-scrubbing logic in lib/sentry/scrub.ts. This TypeScript module exports sentryScrubHooks, a collection of functions that attach to every Sentry initialization across Node.js, Edge, and client runtimes, ensuring that personally identifiable information is redacted before any report reaches Sentry's servers.
Architecture of the PII Scrubbing System
Centralized Hook Collection
The sentryScrubHooks object consolidates four distinct lifecycle hooks into one importable constant. According to the DeskcommCRM source code, these hooks attach to different telemetry types:
beforeSend: Processes error events containing exceptions and messagesbeforeSendTransaction: Handles transaction events for performance monitoringbeforeSendSpan: Cleans individual span data within distributed tracesbeforeBreadcrumb: Sanitizes breadcrumb metadata before attachment to the event stream
All four hooks are defined and exported from a single location to eliminate the "triple-copy bug" of duplicated sanitization logic across runtime-specific configuration files.
Link: sentryScrubHooks definition, lines 48-88
Header Sanitization Strategy
Sensitive HTTP headers are identified using isSensitiveHeader() combined with scrubHeaders(). The implementation matches headers against a broad regular expression covering Authorization, Cookie, API-Key, Token, and similar patterns, then removes them entirely from the request object before transmission.
Link: header scrubbing logic, lines 46-55
Step-by-Step PII Scrubbing Process
1. Event-Wide URL Redaction
The scrubEventUrls() function orchestrates the cleaning of all URL-related fields in an event. It applies scrubUrl() to request URLs, transaction names, and trace data to ensure no credential-bearing paths leave the system.
Link: scrubEventUrls implementation, lines 30-45
2. Credential Path and Query String Masking
Within scrubUrl(), two specific protections operate:
- Credential Path Redaction: Webhook and invite URLs containing tokens as the final path segment are masked using the
CREDENTIAL_PATHregex. For example,/webhooks/whatsapp/abcd1234becomes/webhooks/whatsapp/[TOKEN]. - Query String Value Masking: Parameter keys are preserved for debugging, but values are replaced with
[REDACTED].
Links: credential path logic, lines 77-89; query-string masking, lines 92-95
3. Message Content Sanitization
Free-form text fields—including exception messages and log entries—are processed by scrubMessage(). This function applies regex patterns to detect and replace:
- CPF numbers (Brazilian tax IDs)
- Phone numbers
- Email addresses
Each pattern is substituted with a contextual placeholder like [CPF], [PHONE], or [EMAIL].
Link: message scrubbing implementation, lines 52-57
4. OpenTelemetry Attribute Scrubbing
For distributed tracing compatibility, scrubAttributes() targets OpenTelemetry-style span attributes such as url.full and http.url. This ensures that PII embedded in trace metadata is equally protected, preventing leakage through alternative telemetry channels.
Link: attribute scrubbing, lines 99-115
Cross-Runtime Implementation
The same sentryScrubHooks are injected into every Sentry initialization file, eliminating duplicate logic and ensuring consistent PII protection across environments.
Node.js Server Configuration
// lib/sentry/server.config.ts
import * as Sentry from '@sentry/nextjs';
import { sentryScrubHooks } from './scrub';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
beforeSend: sentryScrubHooks.beforeSend,
beforeSendTransaction: sentryScrubHooks.beforeSendTransaction,
beforeSendSpan: sentryScrubHooks.beforeSendSpan,
beforeBreadcrumb: sentryScrubHooks.beforeBreadcrumb,
});
Edge Runtime Configuration
// lib/sentry/edge.config.ts
import * as Sentry from '@sentry/nextjs';
import { sentryScrubHooks } from './scrub';
export const onError = Sentry.EdgeErrorHandler({
beforeSend: sentryScrubHooks.beforeSend,
});
Client-Side Configuration
// lib/sentry/client.ts
import * as Sentry from '@sentry/nextjs';
import { sentryScrubHooks } from './scrub';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
beforeSend: sentryScrubHooks.beforeSend,
beforeSendTransaction: sentryScrubHooks.beforeSendTransaction,
});
Summary
- Single source of truth: All scrubbing logic resides in
lib/sentry/scrub.ts, preventing code duplication across server, edge, and client configurations. - Four-hook coverage: Errors (
beforeSend), transactions (beforeSendTransaction), spans (beforeSendSpan), and breadcrumbs (beforeBreadcrumb) are all sanitized through a unified interface. - Comprehensive patterns: The system removes authorization headers, masks CPF/email/phone patterns, redacts tokens from URL paths, and strips query string values.
- Runtime agnostic: Identical hooks protect Node.js, Edge, and browser environments without modification, ensuring LGPD-compliant scrubbing regardless of execution context.
Frequently Asked Questions
What is Sentry's beforeSend hook and when does it execute?
The beforeSend hook is a Sentry SDK configuration callback that executes synchronously immediately before an error event is transmitted to Sentry's servers. In DeskcommCRM, this hook receives the event object, applies scrubMessage() and scrubEventUrls(), and returns the sanitized event or null to drop the report entirely.
How does the scrubber handle sensitive HTTP headers?
The scrubHeaders() function iterates over request headers and removes any key matching the sensitive header regex, which includes Authorization, Cookie, X-API-Key, and token variants. This operation occurs within beforeSend before the event payload leaves the process, ensuring credentials never reach external servers.
Which types of personally identifiable information does DeskcommCRM remove?
According to the source implementation in lib/sentry/scrub.ts, the scrubber targets Brazilian CPF numbers, email addresses, phone numbers, bearer tokens in URL paths, and all query string values. It also strips sensitive HTTP headers that might contain session identifiers or API credentials.
Can I use these hooks in both Node.js and Edge runtimes?
Yes. The sentryScrubHooks export is runtime-agnostic and imported into sentry.server.config.ts for Node.js, sentry.edge.config.ts for Vercel Edge, and the client instrumentation for browsers. This ensures consistent PII scrubbing regardless of where the code executes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →