Skip to main content

Security

This page outlines what TraceLog protects automatically, what it does not handle, and what you are responsible for as the integrator.

What TraceLog Guarantees

Input Value Protection

TraceLog never captures values from <input>, <textarea>, or <select> elements. Click events on form fields only capture element metadata (tag name, id, class) -- never the value attribute.

PII Sanitization

Sensitive data patterns in error messages and click text are automatically redacted:

PatternExampleResult
Email addressesuser@example.com[REDACTED]
Phone numbers (US)(555) 123-4567[REDACTED]
Credit card numbers4111 1111 1111 1111[REDACTED]
API keys / tokenssk_live_abc123...[REDACTED]
Bearer tokensBearer eyJhbG...[REDACTED]
IBAN numbersDE89 3704 0044 0532 0130 00[REDACTED]

This sanitization runs client-side before any data leaves the browser.

URL Parameter Filtering

TraceLog strips 14 sensitive query parameters from all tracked URLs by default:

token, auth, key, session, reset, password, api_key, apikey, secret, access_token, refresh_token, verification, code, otp

You can extend this list with custom parameters via sensitiveQueryParams in your configuration. Common parameters like email and user are not filtered by default because they have legitimate uses in confirmation links and attribution.

Client-Side Controls

All sampling, deduplication, and validation happen in the browser. Privacy controls work even without a backend connection. Rate limiting (200 events/sec) prevents abuse and accidental event floods.

XSS Protection

All string metadata is sanitized against common XSS patterns. HTML entities are encoded automatically before being included in event payloads.

Data Retention

Server-side analytics data is retained according to your subscription plan and automatically deleted after the retention period:

PlanRetention
Free30 days
Growth90 days
Pro180 days
Business365 days
Enterprise365 days

Client-side event data in the browser expires after 2 hours in localStorage regardless of plan.

What TraceLog Does NOT Do

  • No form submission tracking -- form data is never captured automatically. You must explicitly send form data via tracelog.event().
  • No fingerprinting -- no canvas fingerprinting, browser fingerprinting, or cross-site tracking. User IDs are optional and entirely under your control.
  • No long-term client storage -- events expire after 2 hours in localStorage. Session recovery windows are configurable (default: 2x session timeout).

Your Responsibilities

TraceLog is a tool, not a compliance solution. The following areas require your attention.

You must obtain user consent before calling tracelog.init(). See the Consent & GDPR page for implementation details and code examples.

Protecting Sensitive UI

Mark sensitive elements with data-tlog-ignore to exclude them from tracking entirely:

<div data-tlog-ignore>
<input type="text" name="card_number">
<input type="text" name="cvv">
</div>

This prevents TraceLog from capturing any interaction data -- including element metadata -- from the marked elements and their children.

Custom Event Data Sanitization

TraceLog automatically sanitizes error messages and click text, but you are responsible for sanitizing data passed to tracelog.event().

Do this:

// Hash sensitive IDs before sending
const hashedId = await hashUserId(user.id);

tracelog.event('purchase_completed', {
user_id: hashedId, // Hashed, not raw
amount: 99.99,
currency: 'USD'
});

Not this:

// DO NOT send PII in custom events
tracelog.event('user_registered', {
email: user.email, // PII leak
phone: user.phone, // PII leak
address: user.address, // PII leak
credit_card: user.card // Critical PII leak
});

URL Parameter Configuration

Extend the default sensitive parameter list with any application-specific parameters:

await tracelog.init({
sensitiveQueryParams: ['affiliate_id', 'promo_code', 'referral'],
integrations: {
tracelog: { projectId: 'your-project-id' }
}
});

Responsibility Matrix

AspectTraceLog handlesYou handle
Input value protectionNever captured automaticallyVerify in testing
PII in text and errorsAuto-redacted (email, phone, cards, tokens)Extend for domain-specific PII
URL parameters14 default parameters filteredAdd app-specific parameters
Consent managementNot handledImplement before init()
Sensitive UI elementsdata-tlog-ignore support providedMark all sensitive elements
Custom event dataNot sanitizedSanitize before sending
Data retentionClient: 2-hour auto-cleanup. Server: per planServer: configure per your policy

Advanced Security Patterns

User ID Anonymization with SHA-256

Instead of sending raw user IDs, hash them before passing to TraceLog:

import { tracelog } from '@tracelog/lib';

async function setAnonymousUser(userId: string) {
const encoder = new TextEncoder();
const data = encoder.encode(userId + 'your-secret-salt');
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashedId = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');

tracelog.identify(hashedId);
}

This uses the native Web Crypto API, available in all modern browsers. No additional dependencies are required.

Secure Custom Backend

When sending events to your own backend, enforce HTTPS and configure credentials carefully:

await tracelog.init({
integrations: {
custom: {
collectApiUrl: 'https://your-api.com/collect',
allowHttp: false, // Never enable in production
fetchCredentials: 'include' // Use 'omit' if cookies are not needed
}
}
});
warning

Setting allowHttp: true transmits analytics data over unencrypted connections. This should only be used for local development.

Transformer Security

Transformers let you modify events before they are sent to a custom backend. Use them for additional PII sanitization, but be careful not to introduce leaks.

Sanitize PII in transformers:

tracelog.setTransformer('beforeSend', (data) => {
if ('type' in data && data.custom_event?.metadata) {
const sanitized = { ...data.custom_event.metadata };
delete sanitized.email;
delete sanitized.phone;
delete sanitized.ssn;

return {
...data,
custom_event: { ...data.custom_event, metadata: sanitized }
};
}
return data;
});

Validate external input:

tracelog.setTransformer('beforeSend', (data) => {
if ('type' in data) {
// Validate and sanitize before merging
const validated = validateExternalData(window.externalData);
const sanitized = sanitizePII(validated);

return {
...data,
custom_event: {
...data.custom_event,
metadata: { ...data.custom_event?.metadata, ...sanitized }
}
};
}
return data;
});
Transformers are integration-specific

Transformers are applied for custom backend integrations and ignored for TraceLog SaaS (schema protection). In multi-integration setups, the SaaS integration receives the original event while the custom backend receives the transformed version.