Privacy and Security

Sanitization boundaries, visible replay data, prohibited event data, and access controls

Separate data paths

Journey events and Session Replay have different privacy boundaries:

  • Journey events are structured metadata, sanitized before database storage and again before PostHog delivery.
  • Identity enrichment deliberately sends verified email, display name (username), stable user/guest IDs and admin/zQA flags as restricted-access PostHog person properties. See Identity and zQA Filters. This does not authorize sending email or profile payloads in arbitrary event metadata.
  • Session Replay records rendered browser state. Its SDK configuration controls whether visible text, inputs, images, and elements are masked or blocked.

Do not assume event sanitization protects replay content. They are separate mechanisms.

Journey-event sanitization

The event sanitizer removes sensitive or content-bearing keys, including passwords, secrets, tokens, authorization headers, cookies, messages, bodies, content, email, phone, links/URLs, descriptions, transcripts, Offers, and Agreements.

It also:

  • removes social-profile URL values
  • redacts strings that look like email addresses or URLs
  • truncates strings, arrays, object depth, and key counts
  • permits safe metadata suffixes such as count, type, status, provider, reason, enabled, failed, and success
  • normalizes paths and replaces IDs or email-like path segments
  • stores only the referrer domain in PostHog

Allowed examples

{
  onboardingStep: "profile",
  authMethod: "google",
  result: "success",
  durationMs: 1240,
  errorCode: "confirmation_expired",
  linkCount: 3
}

Never send in journey-event metadata

  • email addresses or phone numbers
  • passwords, one-time codes, or auth tokens
  • cookies, headers, or network bodies
  • chat/message text or transcripts
  • Offer or Agreement text
  • private document contents
  • full private URLs or sensitive query strings

Only the trusted identity path may send email and username as person properties. The browser event sanitizer also rejects reserved PostHog controls ($set, $identify-style keys) and identity/admin/zQA fields, including nested attempts. The server inserts a non-PII identity-flags snapshot after that boundary. Raw guest access cookies, passwords, auth tokens and one-time codes are prohibited in every analytics identity path.

Person enrichment is best-effort and does not backfill old profiles automatically. Limit project access, review retention and deletion procedures for person data, and update user-facing privacy disclosures before broad use. Email is personal data even when sent as a person property rather than an event property.

Replay URL sanitization

Before replay capture, Zooly strips query parameters whose keys look sensitive, including token, secret, password, authorization, auth, code, email, OTP, key, and signature. The same sanitizer is applied to current URL, referrer, pathname, and replay request names.

This protects URL secrets; it does not remove matching text already rendered in the DOM.

Current replay visibility

SDK options currently override remote project masking with fully visible text, attributes, images, and form values. This behavior applies in every environment once the code and PostHog token are deployed.

The V2 consent model remains in code, but hasFullSessionReplayConsent() currently returns true regardless of stored preference. Re-enabling an interactive consent policy requires changing that gate and restoring a user-visible decision path.

Required controls

  • Restrict the PostHog project and recordings to authorized internal administrators.
  • Do not create public replay links.
  • Use the shortest practical recording retention; the rollout target is seven days.
  • Keep console recording and network bodies disabled.
  • Review Privacy Policy and Cookie Policy before broad Production use.
  • Run a dedicated privacy smoke test after every replay-SDK change.
  • Treat screenshots and exported recordings as sensitive data.

Safer future state

Before long-term Production use, define explicit selectors for payment, credentials, documents, and other sensitive surfaces, restore password masking, and restore a consent/revocation UX. The event pipeline can continue independently even when replay is disabled.