Skip to main content

Client Logging and Telemetry Sanitization

This document describes how RECORD-3297 protects client-side logs and telemetry from leaking sensitive data.

Scope​

Sanitization applies to runtime logging and telemetry paths in the web app:

  • Shared logger dispatch in src/utils/logger.ts
  • Log payload sanitization policy in src/utils/logSanitization.ts
  • New Relic telemetry/error recording in src/providers/instrumentation/newrelic/instrumentation.ts
  • Error boundary logging in src/app/error.tsx and src/app/global-error.tsx
  • Network failure diagnostics in src/utils/fetcher.ts

Redaction Policy​

The sanitization policy is centralized in src/utils/logSanitization.ts and is shared by logger and telemetry layers.

Sensitive keys​

Objects are key-sanitized when field names indicate potentially sensitive content. Coverage includes tokens and auth fields, account/session identifiers, payment fields, and PII-oriented keys. Examples:

  • token-like: token, accessToken, refreshToken, authorization, apiKey, cookie
  • auth/secret-like: password, pin, secret, bearer, jwt
  • session/device-like: session, sessionId, session_id, deviceId, device_id
  • payment-like: cvv, cvc, card, cardNumber, iban, billing
  • PII-like: email, phone, firstName, lastName, fullName, username, address

Sensitive string patterns​

String content is sanitized with pattern redaction:

  • Bearer credentials: Bearer [REDACTED]
  • JWT-like tokens: [REDACTED_JWT]
  • Email addresses: [REDACTED_EMAIL]
  • Phone numbers: [REDACTED_PHONE]
  • Card numbers (Luhn-valid): [REDACTED_CARD]
  • URL query/hash removal: query and fragment are removed from URL-like values
  • Inline key-value fragments: session_id=..., device_id=..., authorization=..., cvv=... are redacted to [REDACTED]

Type behavior​

  • primitives: strings sanitized, numbers/booleans preserved
  • URL values: reduced to safe path-only form for relative URLs, query/hash stripped for absolute URLs
  • Error objects: name/message/stack/cause sanitized recursively
  • arrays and nested objects: recursively sanitized
  • circular references: replaced with [Circular]
  • deep recursion guard: replaced with [Truncated] beyond max depth

Logging Strategy​

Shared logger​

All runtime logger calls sanitize arguments before provider dispatch. This means all logger methods (debug/info/log/warn/error) route through the same sanitization boundary.

Console bypass handling​

Runtime direct console usage in targeted app paths has been replaced by shared logger usage, so sanitization cannot be bypassed by normal runtime code paths.

Telemetry Strategy​

New Relic calls sanitize event names, custom attributes, and error details before emission:

  • recordEvent uses sanitized names and attributes
  • recordError sanitizes context attributes and error details
  • noticeError receives sanitized error strings

Additionally, high-risk telemetry attributes have been reduced to safe metadata in relevant call paths (for example booleans instead of raw media URLs).

Network and Error Boundary Behavior​

Fetcher diagnostics​

Network failure logging uses safe metadata rather than raw URLs/payloads:

  • endpointPath (pathname only)
  • status
  • statusText

No raw request/response headers, cookies, or body payload dumps are intentionally emitted in fetcher diagnostics.

Error boundaries​

Error boundary and global error boundary logging now rely on sanitized logger payload behavior and avoid unsafe raw field leakage.

Sanitized Evidence Samples​

Representative outputs after sanitization:

{
accessToken: "abc",
profile: { email: "user@example.com", phone: "+1 202-555-0179" }
}
  • Output object:
{
accessToken: "[REDACTED]",
profile: { email: "[REDACTED]", phone: "[REDACTED]" }
}

Validation Evidence​

Focused test evidence command:

pnpm test:once src/utils/tests/logSanitization.test.ts src/app/tests/error.test.tsx src/app/tests/global-error.test.tsx src/providers/instrumentation/newrelic/tests/instrumentation.test.ts --no-coverage

Result:

  • 4/4 suites passed
  • 27/27 tests passed

Acceptance Criteria Checklist​

  • AC: No credentials/tokens/session IDs/device IDs exposed in client logs

    • Covered by inline/string/object sanitization tests in src/utils/tests/logSanitization.test.ts
  • AC: PII and payment-related values are redacted in logs and telemetry

    • Covered by policy tests and telemetry tests in src/providers/instrumentation/newrelic/tests/instrumentation.test.ts
  • AC: Error reporting preserves diagnostics without leaking sensitive payloads

    • Covered by sanitized error processing in src/providers/instrumentation/newrelic/instrumentation.ts and boundary tests in src/app/tests/error.test.tsx and src/app/tests/global-error.test.tsx
  • AC: Runtime logging does not bypass sanitization strategy

    • Covered by migration to shared logger in targeted runtime modules and logger sanitization behavior in src/utils/logger.ts
  • AC: Production logging is non-verbose and safer by default

    • Covered by production log-level floor in src/utils/logger.ts and src/utils/logSanitization.ts
  • AC: Network diagnostics avoid raw response/request sensitive payload emission

    • Covered by safe endpoint/status logging behavior in src/utils/fetcher.ts

Notes​

  • redactString in src/utils/string.ts remains available for non-security partial masking use cases.
  • Security-sensitive logging and telemetry paths must use src/utils/logSanitization.ts policy behavior as the canonical approach.