Skip to main content

Data Privacy

By default, Reports collects data about user interactions and network requests for debugging issues. Depending on your application, some of this data may contain confidential information that you do not want to log.

Some types of data are never collected:

  • Authentication tokens and cookies in network requests
  • Information entered into forms

Note that the information on this page applies only to captured events and logs. Visual information in screenshots and screen recordings is not removed automatically.


Overview

By default, user interactions, network requests, and page state are captured automatically. However, some data requires special protection:

  • Passwords and authentication data
  • Personal data (email, phone, tax ID)
  • Payment information (card numbers, CVV)
  • API keys and tokens
  • Other confidential information

Tuna Reports provides several levels of data protection that you can combine depending on your application's security requirements.


Automatic protection

By default, the following data is masked automatically:

Input fields

The following field values are masked automatically:

  • <input type="password">, <input type="email">, <input type="tel"> — by type
  • Fields whose name or id attribute contains keywords:
    • Authentication: password, passwd, pwd, secret, pin, otp
    • Contact data: email, phone, tel, mobile
    • Identification: ssn, passport, license, national_id, tax_id, inn, snils
    • Payment data: card, credit, debit, payment, billing, visa, mastercard, amex, discover, maestro, mir
    • Card details: cvv, cvc, cvn, expir
    • Bank details: iban, swift, bic, routing, account
    • Tokens and keys: token, apikey, api_key, auth, private
  • Fields with classes: password, passwd, email, phone, ssn, credit, card, payment, sensitive, private, secret, masked, hidden, secure, confidential
Substring matching

Keyword matching uses substrings. For example, card matches cardnumber, card_number, creditcard. And expir matches expiry, expiration.

<!-- These fields will be masked automatically -->
<input type="password" name="user_password">
<input type="email" name="user_email">
<input type="tel" name="phone_number">
<input class="credit-card-input" name="card">

URL parameters

Query parameters in URLs containing the following are masked automatically:

  • Authentication: password, passwd, pwd
  • Tokens and keys: token, key, secret, apikey, api_key
  • Sessions: auth, credential, session, access
  • OAuth/OIDC: code, nonce
Before: https://example.com/api?token=abc123&user=john
After: https://example.com/api?token=***&user=john

Adding your own parameters (sensitiveUrlParams)

You can extend the list of masked URL parameters via the sensitiveUrlParams option:

window.reportOptions = {
captureKey: 'YOUR_CAPTURE_KEY',
sensitiveUrlParams: ['my_secret_param', 'internal_id', 'ref_code']
};

These parameters will be added to the standard list, not replace it.

HTTP headers

The following HTTP headers in network requests are masked automatically:

  • Standard: authorization, www-authenticate, cookie
  • Tokens and keys: token, secret, apikey, api-key, api_key
  • Sessions and signatures: signature, credential, session
  • Service: idempotency-key, idempotence-key
  • Cloud providers: x-amz-* (AWS), x-goog-* (Google Cloud), x-ms-* (Azure), cf-access-* (Cloudflare), ocp-apim-* (Azure API Management)

Headers with values starting with Bearer or Basic are also masked.

Adding your own headers (sensitiveHeaders)

You can extend the list of masked HTTP headers via the sensitiveHeaders option:

window.reportOptions = {
captureKey: 'YOUR_CAPTURE_KEY',
sensitiveHeaders: ['x-my-custom-header', 'x-internal-token']
};

These headers will be added to the standard list, not replace it.


HTML attributes for masking

You can explicitly mark elements that should be masked or hidden using data attributes.

data-capture-mask

Masks the element's content, replacing the text with ***.

<!-- Text will be replaced with *** -->
<span data-capture-mask>Secret text</span>

<!-- Field value will be masked -->
<input data-capture-mask type="text" value="secret123">

<!-- The entire block will be masked -->
<div data-capture-mask>
<p>Confidential information</p>
<p>Contract number: 12345</p>
</div>
Inheritance

Instead of adding the attribute to each element, you can add it to a parent container:

<!-- Instead of this (on each input) -->
<input data-capture-mask>
<input data-capture-mask>
<input data-capture-mask>

<!-- You can do this (once on the container) -->
<div data-capture-mask>
<input>
<input>
<input>
</div>

data-capture-hide

Completely hides the element from the report.

<!-- Element will not appear in the report -->
<div data-capture-hide>
<p>This information will not be captured</p>
</div>

<!-- Hide an image -->
<img data-capture-hide src="private-photo.jpg">

<!-- Hide a section with payment data -->
<section data-capture-hide class="payment-form">
<input type="text" name="card_number">
<input type="text" name="cvv">
</section>

Difference between mask and hide

AttributeResultWhen to use
data-capture-maskElement is visible, content replaced with ***When it is important to show that data exists
data-capture-hideElement is completely absentWhen the element should not be visible at all

Usage examples

Example 1: Login form

<form id="login-form">
<div>
<label>Email</label>
<!-- Masked automatically (type="email") -->
<input type="email" name="email">
</div>

<div>
<label>Password</label>
<!-- Masked automatically (type="password") -->
<input type="password" name="password">
</div>

<div>
<label>2FA code</label>
<!-- Explicit masking -->
<input data-capture-mask type="text" name="otp_code">
</div>

<button type="submit">Sign in</button>
</form>

Example 2: Payment form

<!-- Hide the entire payment section -->
<section data-capture-hide class="payment-section">
<h3>Payment data</h3>

<input type="text" name="card_number" placeholder="Card number">
<input type="text" name="expiry" placeholder="MM/YY">
<input type="text" name="cvv" placeholder="CVV">
</section>

<!-- Or mask individual fields -->
<section class="payment-section">
<h3>Payment data</h3>

<input data-capture-mask type="text" name="card_number">
<input data-capture-mask type="text" name="expiry">
<input data-capture-mask type="text" name="cvv">
</section>

Example 3: User profile

<div class="user-profile">
<h2>Profile</h2>

<!-- Name can be shown -->
<p>Name: <span>John Doe</span></p>

<!-- Mask the phone number -->
<p>Phone: <span data-capture-mask>+1 555 123-4567</span></p>

<!-- Hide passport data completely -->
<div data-capture-hide class="passport-data">
<p>Series and number: 1234 567890</p>
<p>Issue date: 01.01.2020</p>
</div>
</div>

Security recommendations

  1. Use the principle of least privilege — mask anything that may be sensitive, even if you are not sure.

  2. Test in a dev environment — before deploying, verify that all sensitive data is actually masked.

  3. Combine methods — use both automatic protection and explicit data attributes.

  4. Review reports regularly — ensure reports do not leak confidential data.

  5. Document for your team — create internal guidelines for using masking data attributes.


Compatibility

Privacy features work in all supported browsers:

  • Chrome 80+
  • Firefox 75+
  • Safari 14+
  • Edge 80+