Advanced
Privacy & Scrubbing
What Reliable does to keep PII out of your event payloads — and what you should do on top of those defaults.
Built-in scrubbing#
Several layers of automatic PII protection are wired in by default. None of them are perfect — they're heuristics — but they remove the most common leaks before payloads ever leave the browser.
String scrubbing#
Any string that the SDK serializes (URLs, breadcrumb messages, error messages, browser_state values) is run through a regex scrubber. The scrubber masks:
- Email addresses →
[email] - Credit-card-shaped numbers (13–19 consecutive digits) →
[card] - JWT tokens (3 dot-separated base64 segments) →
[token] - API keys in URLs (
?api_key=...,?token=...) →[redacted]
Cookies & localStorage#
When an error fires, Reliable snapshots document.cookie and localStorage as part of the error's browser_state. Before sending:
- Keys matching
/token|secret|password|auth(?!or)/iare fully redacted (value replaced with[REDACTED]). - Other values are truncated to 200 characters and run through the string scrubber above.
Session replay#
rrweb is the most invasive piece of the SDK. By default, Reliable enables aggressive defaults so PII doesn't end up in replays:
- All
<input>values are masked (rendered as ▪▪▪▪). - Password fields, credit card inputs, and SSN fields are fully blocked — not even the input shape is recorded.
- iframe contents are not recorded.
See Session Replay for the full opt-in/opt-out attribute model (data-rr-allow, data-rr-block).
Adding your own scrubbing#
For app-specific PII patterns (internal IDs, custom token formats, anything the defaults miss), use beforeSend:
init({
publicKey: 'pk_live_rl_...',
beforeSend(event) {
// Strip our internal customer IDs from URLs
if (typeof event.url === 'string') {
event.url = event.url.replace(/cust_[a-zA-Z0-9]+/g, 'cust_[id]');
}
return event;
},
});What every event payload contains#
Even with all scrubbing in place, every event includes:
- The current path (URL pathname + search, query params scrubbed)
- User agent string
- Viewport dimensions
- The session UUID (random per session, no PII)
- If
identify()was called: theexternalId,email,name, andtraitsyou provided
This is the data you control. Reliable doesn't fingerprint, doesn't read storage you didn't authorize, doesn't make third-party requests.
GDPR / consent flows#
For GDPR-compliant apps, gate the entire SDK behind consent. The simplest pattern:
async function bootstrap() {
const consent = await waitForConsent();
if (consent.analytics) {
init({ publicKey: 'pk_live_rl_...' });
}
}Once init() has been called, you cannot un-init it. Reload the page to fully tear down the SDK. (For SPAs that need conditional behavior at runtime, prefer dropping events in beforeSend based on a global consent flag.)
No automatic system is bulletproof
beforeSend rules before going to production.