Session Replay provides privacy controls to ensure organizations of any scale do not expose sensitive or personal data. Data is stored on Datadog-managed cloud instances and encrypted at rest.
Default privacy options for Session Replay protect end user privacy and prevent sensitive organizational information from being collected.
By enabling Mobile Session Replay, you can automatically mask sensitive elements from being recorded through the RUM Mobile SDK. When data is masked, that data is not collected in its original form by Datadog’s SDKs and thus is not sent to the backend.
Fine-grained masking
Using the masking modes below, you can override the default setup on a per-application basis. Masking is fine-grained, which means you can override masking for text and inputs, images, and touches individually to create a custom configuration that suits your needs.
Text and input masking
By default, the mask_all setting is enabled for all data. With this setting enabled, all text and input content on screen is masked, as shown below.
Mask sensitive inputs
With the mask_sensitive_inputs setting enabled, all text and inputs are shown except those considered sensitive, such as password fields.
To manage content masking while still showing system images, users can choose the following options:
On iOS, users can select the mask_non_bundled_only setting, which replaces any image that is not part of the system with a “Content Image” placeholder.
On Android, users can select the mask_large_only setting, which replaces images with dimensions that exceed 100x100dp with a “Content Image” placeholder.
Note: These dimensions refer to the drawable resource, not the view’s size.
The sections above describe the global masking levels that apply to the entire application. However, it is also possible to override these settings at the view level. The same privacy levels as above are available for text and inputs, images, touches, and an additional setting to completely hide a specific view.
To ensure overrides are recognized properly, they should be applied as early as possible in the view lifecycle. This prevents scenarios where Session Replay might process a view before applying the overrides.
Privacy overrides affect views and their descendants. This means that even if an override is applied to a view where it might have no immediate effect (for example, applying an image override to a text input), the override still applies to all child views.
Overrides operate using a “nearest parent” principle: if a view has an override, it uses that setting. Otherwise, it inherits the privacy level from the closest parent in the hierarchy with an override. If no parent has an override, the view defaults to the application’s general masking level.
Text and input override
To override text and input privacy, use setSessionReplayTextAndInputPrivacy on a view instance and pass a value from the TextAndInputPrivacy enum. Passing null removes the override.
build.gradle
// Set an text and input override on your view
myView.setSessionReplayTextAndInputPrivacy(TextAndInputPrivacy.MASK_SENSITIVE_INPUTS)// Remove an image override from your view
myView.setSessionReplayTextAndInputPrivacy(null)
To override text and input privacy, use dd.sessionReplayOverrides.textAndInputPrivacy on a view instance and set a value from the TextAndInputPrivacyLevel enum. Setting it to nil removes the override.
AppDelegate.swift
// Set an text and input override on your viewmyView.dd.sessionReplayOverrides.textAndInputPrivacy=.maskSensitiveInputs// Remove an image override from your viewmyView.dd.sessionReplayOverrides.textAndInputPrivacy=nil
Image override
To override image privacy, use setSessionReplayImagePrivacy on a view instance and pass a value from the ImagePrivacy enum. Passing null removes the override.
build.gradle
// Set an image override on your view
myView.setSessionReplayImagePrivacy(ImagePrivacy.MASK_ALL)// Remove an image override from your view
myView.setSessionReplayImagePrivacy(null)
To override image privacy, use dd.sessionReplayOverrides.imagePrivacy on a view instance and set a value from the ImagePrivacyLevel enum. Setting it to nil removes the override.
AppDelegate.swift
// Set an image override on your viewmyView.dd.sessionReplayOverrides.imagePrivacy=.maskAll// Remove an image override from your viewmyView.dd.sessionReplayOverrides.imagePrivacy=nil
Touch override
To override touch privacy, use setSessionReplayTouchPrivacy on a view instance and pass a value from the TouchPrivacy enum. Passing null removes the override.
build.gradle
// Set a touch override on your view
view.setSessionReplayTouchPrivacy(TouchPrivacy.HIDE)// Remove a touch override from your view
view.setSessionReplayTouchPrivacy(null)
To override touch privacy, use dd.sessionReplayOverrides.touchPrivacy on a view instance and set a value from the TouchPrivacyLevel enum. Setting it to nil removes the override.
AppDelegate.swift
// Set a touch override on your viewmyView.dd.sessionReplayOverrides.touchPrivacy=.hide// Remove a touch override from your viewmyView.dd.sessionReplayOverrides.touchPrivacy=nil
Hidden elements override
For sensitive elements that need to be completely hidden, use the hidden setting.
When an element is hidden, it is replaced by a placeholder labeled as “Hidden” in the replay, and its subviews are not recorded.
Note: Marking a view as hidden does not prevent touch interactions from being recorded on that element. To hide touch interactions as well, use the touch override in addition to marking the element as hidden.
Use setSessionReplayHidden(hide = true) to hide the element. Setting hide to false removes the override.
build.gradle
// Mark a view as hidden
myView.setSessionReplayHidden(hide=true)// Remove the override from the view
myView.setSessionReplayHidden(hide=false)
AppDelegate.swift
// Mark a view as hiddenmyView.dd.sessionReplayOverrides.hide=true// Remove the override from the viewmyView.dd.sessionReplayOverrides.hide=false
Note: Setting the hidden override to nil has the same effect as setting it to false—it disables the override.
Notes on WebViews
• Privacy overrides, aside from the hidden and touch options, are not supported for WebViews. You can primarily manage their privacy using the browser SDK privacy settings.
• When a WebView is marked as hidden, it is replaced by a placeholder in the replay. However, the WebView itself continues to collect and send data. To avoid this, it is recommended to use browser SDK privacy settings for managing WebView privacy, as they provide more targeted control.
How and what data is masked
This section describes how the Datadog recorder handles masking based on data type and how that data is defined.
Text masking strategies
Depending on how you’ve configured your privacy settings, the type of text, and sensitivity of data, Datadog’s masking rules apply different strategies to different types of text fields.
Text masking strategy
Description
Example
No mask
The text is revealed in the session replay
"Hello world" → "Hello world"
Space-preserving mask
Each visible character is replaced with a lowercase “x”
"Hello world" → "xxxxx xxxxx"
Fixed-length mask
The entire text field is replaced with a constant of three asterisks (***)
"Hello world" → "***"
With the above text strategies in mind, you have a few different options if you want to override the default privacy rule of mask in your configuration.
The following chart shows how Datadog applies different text masking strategies, using the rules you set up in your configuration, to the below text types.
Find below a description of how Datadog’s recorder treats each text type.
Sensitive text
Sensitive text includes passwords, e-mails, and phone numbers marked in a platform-specific way,
and other forms of sensitivity in text available to each platform.
This includes passwords, e-mails and phone numbers in:
Text Field (iOS)
Text View (iOS)
Edit Text (Android)
Address information (iOS + Android)
Credit card numbers (iOS)
One-time codes (iOS)
Input and option text
Input and option text is text entered by the user with a keyboard or other text-input device, or a custom (non-generic) value in selection elements.
This includes the below.
User-entered text in:
Text Field (iOS)
Text View (iOS)
Edit Text (Android)
User-selected options in:
Value Picker (iOS + Android)
Segment (iOS)
Drop Down List (Android)
Notable exclusions:
Placeholder (hint) texts in Text Field, Text View and Edit Text (not entered by the user)
Non-editable texts in Text View (iOS).
Month, day, and year labels in Date Picker (generic values)
Static text
Static text is any text that is not directly entered by the user. This includes the below.
All texts in:
Checkbox and Radio Button titles (Android)
Texts in non-editable Text View (iOS)
Month, day and year labels in the date and time picker
Values updated in response to gesture interaction with input elements, such as the current value of the Slider
Other controls, not considered as “user input elements”, such as Labels, Tab Bar, and Navigation Bar (iOS), or Tabs (Android)
Hint text
Hint text is static text in editable text elements or option selectors that is displayed when no value is given. This includes:
Placeholders in Text Field (iOS), Text View (iOS)
Hints in Edit Text (Android)
Prompts in Drop Down lists (Android)
Appearance masking
The following chart shows how we apply different appearance masking strategies, using the rules you set up in your configuration, to the below text types.
Revealing attributes are attributes that can reveal or suggest the value of input elements and can be used to infer a user’s input or selection.
This includes:
Shapes
Background of selected option in Segment (iOS)
Circle surrounding the selected date in a Date Picker (iOS)
Selection mark in Checkbox (Android)
Thumb of a Slider (iOS and Android)
Text attributes
The color of a label rendering the selected date in Date Picker (iOS)
The position of the first and last option in Value Picker (iOS and Android)
Touch interactions
The following chart shows how we apply different touch interaction strategies, using the rules you set up in your configuration, to the below text types. While any interaction that happens on an on-screen keyboard is masked, interactions with other elements are not masked.