Skip to content

feat: add masked session replay lifecycle - #17194

Open
graphaelli wants to merge 2 commits into
LibreChat-AI:devfrom
graphaelli:session-replay-opt-in
Open

graphaelli wants to merge 2 commits into
LibreChat-AI:devfrom
graphaelli:session-replay-opt-in

Conversation

@graphaelli

Copy link
Copy Markdown
Collaborator

Summary

Session replay already has SDK and proxy support. This adds session-replay opt-in while keeping recording off by default. The browser masks DOM text and input values, stops recording when authentication or replay permission disappears, and preserves the general RUM sampling decision when replay is toggled.

How it works

Enable replay explicitly through YAML:

telemetry:
  rum:
    enabled: true
    sessionReplay:
      enabled: true

Alternatively, set RUM_ENABLED=true and RUM_SESSION_REPLAY_ENABLED=true using the existing collector/authentication settings. YAML flags take precedence over environment settings.

  • Keep existing same-origin transport: RUM spans use /api/rum/v1/traces; replay records and ordinary browser logs share /api/rum/v1/logs. The authenticated proxy keeps collector credentials out of the browser.
  • When replay is disabled (after first being enabled), remove SDK replay records from both OTLP JSON and protobuf batches before forwarding. Preserve ordinary log records and envelope metadata in mixed batches; drop replay-only batches without claiming collector acceptance. Reject malformed or unrecognized JSON envelopes while filtering rather than forwarding opaque data.
  • Resolve proxy policy from the cached deployment base config, not browser input or per-user overrides. Move RUM startup-config behavior into TypeScript under packages/api, leaving the legacy JavaScript module as wiring.

Type of change

  • Feature
  • Refactor
  • Tests / tooling
  • Configuration documentation

Testing

Reproduction:

  1. Configure the existing HyperDX/ClickStack collector connection and proxy authentication settings.
  2. Enable RUM with replay disabled. Interact with LibreChat and confirm normal browser spans continue without recordings.
  3. Enable replay separately, reload, and interact with a synthetic prompt without submitting an LLM request.
  4. Open the session in ClickStack/HyperDX and confirm the page is reconstructed with text and inputs masked and browser spans correlated by rum.sessionId.
  5. Disable replay while leaving RUM_CLIENT_LOGS=true. Confirm ordinary logs still ingest, replay-only requests are dropped, and mixed batches retain only ordinary records.

Automated checks on rebased head 9289e3634:

  • 822 focused tests passed: 74 API RUM/policy/proxy tests, 134 frontend RUM/recovery tests, 504 shared-config tests, and 110 startup/RUM route tests.
  • tsc --noEmit passed in packages/api, packages/data-provider, and client.
  • Affected ESLint, Prettier, import-order, dependency-cycle, and repository static checks passed against upstream dev.
  • E2E_BASE_URL=http://localhost:3098 npm run lighthouse passed: median LCP 3.47 s (4.5 s budget), CLS 0.018, and TBT 54 ms.

Separate local integration validation:

Screenshots / recordings

5140d1e265134f3bcd9046f59b4a5a76-useful.mp4

Risk / compatibility

  • Privacy-sensitive opt-in: masking text and inputs is not comprehensive data-loss prevention. URLs, DOM attributes, and assets may still contain sensitive information. Console and full network-body capture remain separate settings.
  • Server-side replay blocking applies to authenticated proxy mode. Direct public-token ingestion bypasses the LibreChat proxy and needs its own collector-side enforcement.
  • Existing environment-based RUM configuration and the legacy replay switch remain supported when higher-precedence settings are absent. An empty YAML replay block resolves to off, including before schema defaults are materialized.
  • Open tabs may keep an older startup configuration until refreshed; the proxy still enforces the current deployment replay policy on incoming records after configuration reload/restart.
  • No new dependencies, database migrations, or storage schema changes.

Checklist

  • Final author review
  • Relevant tests added or updated
  • Relevant automated tests and typechecks pass
  • Default-off behavior, legacy compatibility, and stale-client filtering covered
  • Configuration examples updated in .env.example and librechat.example.yaml
  • Attach the session replay video before submitting
  • Follow up with the documentation-site update for the new settings

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant