Enable privacy protection in the Connect Flutter SDK

When capturing user behavior data, you must take measures to exclude personally identifiable information (PII) such as credit card numbers or home addresses.

Before you begin

You must assign unique semantics labels to all widgets that require privacy protection. For implementation details, we recommend this article - Semantics flutter.

📘

Note

Using the same accessibility labels across the iOS and Android versions of an app creates consistency and is considered an industry standard. For more information, see Mobile Accessibility at W3C

The following code snippets demonstrate the different ways you can define accessibility labels in Flutter.

Using Semantics Widget:

Semantics(
  label: 'Submit button',
  child: ElevatedButton(
    onPressed: () {
      // Your button logic here
    },
    child: Text('Submit'),
  ),
)

Accessibility properties:

Text(
  'Your Text',
  semanticsLabel: 'Custom label for Text widget',
)

Annotations

import 'package:flutter/material.dart';

@SemanticsHint('This is a custom hint')
@SemanticsLabel('Custom label for this widget')
class CustomWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      // Your widget content
    );
  }
}

Instructions

  1. Open ConnectConfig.json. In the masking object, set HasMasking to true.
  2. Add the MaskAccessibilityLabelList parameter and populate it with the accessibility labels of the widgets that require privacy protection.
{
  "Masking": {
    "HasMasking": true,
    "HasCustomMask": true,
    "Sensitive": {
      "capitalCaseAlphabet": "X",
      "number": "9",
      "smallCaseAlphabet": "x",
      "symbol": "#"
    },
    "MaskAccessibilityLabelList": [
      "privacyTest"
    ]
  }
}
  1. (recommended) Run the file through a JSON validator.

How it works

The masking object in ConnectConfig.json contains all properties related to PII protection.

PropertyValuesDescription
HasMaskingHasMaskingSet the value to true to allow masking.
HasCustomMasktrueProtected text is replaced with a fixed string ( xxxxx ).
MaskAccessibilityLabelListArray of stringThe label property assigned to the widget

You can create a general privacy rule that applies to all screens of your app. In that case, use the AutoLayout.GlobalScreenSettings object. To create a rule for a particular screen, add the AutoLayout.ScreenName object where ScreenName is the name of the screen. Feel free to combine general and screen-specific rules within the same configuration file.

{
  "AutoLayout": {
    "GlobalScreenSettings": {
      "Masking": {
        "HasMasking": true,
        "HasCustomMask": true,
        "Sensitive": {
          "capitalCaseAlphabet": "X",
          "number": "9",
          "smallCaseAlphabet": "x",
          "symbol": "#"
        },
        "MaskAccessibilityLabelList": [
          "Health conditions",
          "Medications taken"
        ]
      }
    }
  },
  "PaymentViewController": {
    "Masking": {
      "HasMasking": true,
      "HasCustomMask": true,
      "Sensitive": {
        "capitalCaseAlphabet": "X",
        "number": "9",
        "smallCaseAlphabet": "x",
        "symbol": "#"
      },
      "MaskAccessibilityLabelList": [
        "Card Number",
        "Billing Address"
      ]
    }
  }
}

Test the settings

To make sure your new rule is working correctly, run the app and enter something into the fields you have masked. Then find the session in Connect and check how the input is displayed.

Masked input example

Protected text input in session replay