Replay privacy
Updated Oct 21, 2026 · today
Browser replay records DOM structure and changes. Non-input text is recorded by default. Input masking is not a guarantee that a page contains no personal data: review the actual pages and uploaded chunks before enabling replay for your users.
Default masking and its limits
The shipped recorder uses maskAllInputs: true. It masks ordinary text, password, and credit-card-shaped text input values, including populated autofill values, as well as textarea and select values. It does not detect payment data wherever it appears. File inputs are an exception: a selected filename can be recorded. Button labels and checkbox or radio state are not covered by the ordinary input-value masking guarantee.
Contenteditable text, open shadow-DOM text, accessible same-origin iframe text, SVG text, document titles, CSS content rules, data-* attributes, aria-label and placeholder values can be recorded. Put sensitive values behind explicit masking or blocking; do not assume that moving them out of an input makes them private. Closed shadow roots and inaccessible frames are not a privacy boundary to rely on across browser integrations.
URL redaction removes query values and fragments and scrubs sensitive or dynamic path segments. Shared text redaction also handles recognized secret patterns, but neither is a general detector for personal information in arbitrary text or attributes.
Mask text or block sensitive regions
<p data-private>Sensitive text: masked, element still recorded</p>
<p class="epok-mask">Sensitive text: masked</p>
<section class="epok-block">
Sensitive contents: omitted, a sized placeholder remains
<input type="file">
</section>[data-private] and .epok-mask mask descendant text; they do not remove the element or guarantee attribute redaction. .epok-blockomits the element's contents and preserves a placeholder with layout dimensions. Use blocking for sensitive regions, including file pickers, and keep secrets out of class names. Apply these markers before recording starts; adding them later cannot recall earlier chunks. Changing recorder options changes this posture and needs its own validation.
What replay does not capture by default
The default browser recorder does not capture canvas pixels or drawing commands (recordCanvas is off), file contents, microphone or camera recordings, or cross-origin iframe contents. It is a DOM replay, not a video of the screen. Same-origin iframe content can be captured. Canvas fallback DOM and media element attributes can still appear in the DOM snapshot.
Replay activity captures console warnings and errors after text redaction, plus fetch method, scrubbed URL, status and timing. It does not collect request or response bodies or headers through that network hook. A console message can still contain unrecognized sensitive text; disable console capture or avoid logging such values.
Consent and session erasure
Consent defaults to denied. Withdrawing shared consent stops capture, clears client queues, and sends no replay tail. It does not delete chunks already delivered. Stop capture for the session before erasing stored data; erasure does not ban future uploads under that session ID.
# Use your own app API origin and a server-side key with read + write scopes.
# Never put this privileged key in the browser capture snippet.
curl --fail-with-body -i -X DELETE \
"$EPOK_API_ORIGIN/api/v1/tenants/$TENANT_ID/rum/sessions/$SESSION_ID" \
-H "Authorization: Bearer $EPOK_WRITE_KEY"DELETE /api/v1/tenants/{tenant_id}/rum/sessions/{session_id} accepts an authenticated app session or an API key with read and write scopes. The authenticated tenant must match the path; the credential's project also scopes the operation. Successful erasure returns 204 and removes replay blobs, staged chunks, chunk indexes and session metadata, including coalesced chunks and sessions marked to keep. A missing or already erased session also returns 204, subject to the same rate limit.
The destructive limiter permits one erasure per second per tenant in each API worker; 429 includes Retry-After. Storage unavailability returns 503. A blob deletion failure returns 502 and preserves database references for retry; some blobs may already be gone. A shared or out-of-session object returns 409 without deleting it. Erasure remains available when capture is disabled. This endpoint erases replay data only; it does not erase separate RUM spans, logs, traces, downloaded copies, or backups.
User identity on RUM spans
When your app calls rum.setUser({ id }), that id is stored as user_idon the browser spans of the session so you can find one user's sessions. Spans are kept for the log retention period (seven days by default) and are not erased by the session erasure endpoint above. Pass an opaque internal id, not an email address or another direct identifier. If you do not call setUser, no user id is stored.
Retention depends on deployment settings
Automatic replay retention is disabled by default. When enabled, an hourly sweep selects expired sessions by last event time, using the configured retention window (default seven days; Growth and Enterprise tier windows are 30 days). Sessions marked to keep are skipped. For other expired sessions, it deletes payloads and retains session metadata with a purged marker. The sweep is batched, so expiry is not an exact deletion deadline.
Retention blob deletion is best effort. Failed deletions and orphaned objects require an object-store lifecycle policy configured by the operator; the application does not install that policy. Do not assume automatic expiry is active without checking the deployment. Explicit session erasure removes metadata too and reports storage failures for retry.
What the local privacy corpus verifies
The SDK corpus records a sentinel fixture through the built snippet and its bundled recorder, serializes the events into the stored gzip chunk form, and checks both masked-value absence and real DOM and mutation capture. Turning input masking off makes the same leak assertion fail. It also checks that unprotected channels remain visible, including filenames.
These are local DOM tests, not a browser compatibility certification: autofill and file selection are simulated, the iframe is same-origin, and the test environment cannot render canvas pixels. Test your own pages and browsers as well. See the browser installation guide and authentication guide.