Skip to content

Dynamic Masking

Satori provides you with the ability to perform real-time masking of sensitive data. Configuring dynamic masking involves several key components:

Data Classification – Satori automatically classifies data in the data inventory. You can also configure custom classifiers or manually classify data. To enable dynamic masking, ensure the relevant fields are correctly classified in the data inventory.

For more information on data classification, refer to the Data Inventory chapter.

Security Policies – Security policies contain dynamic masking rules, specifying which masking profile to apply based on user roles and conditions. For example, apply the Customer Success masking profile when the user is a member of the Customer Success group and the customer's country is United States.

For more information on security policies, refer to the Security Policies chapter.

Masking Profiles – Masking profiles determine how data is transformed when a masking policy is enforced. For instance, when querying email addresses, a masking profile can obscure the username portion while keeping the domain visible.

For more information on masking profiles, continue reading below.

Masking Profiles

Satori uses masking profiles to simplify the configuration of dynamic masking. Masking profiles define the set of transformations to apply to each data type. Multiple rules can reuse the same profile.

Screenshot

Data Transformations

Satori supports two types of data transformations:

  • Generic Data Transformations - These transformations can be applied to any data type. For example, by replacing data fields with predefined strings, hashing the data or removing it completely from the result set.
  • Specific Data Transformations - Tailor-made transformations for common data types that provide a better user experience for users when masking data. For example, anonymizing an email address by replacing the address prefix with * or retaining only the year for a date of birth field.

To see the full list of transformations, refer to the link here Transformations List.

Screenshot

Masking Profile Templates

Satori provides three pre-configured profile templates for common masking use-cases.

  1. Permissive Masking Profile - This masking profile is suited for roles that require some access to PII.
  2. Restrictive Masking Profile - This masking profile is suited for any role that does not require access to PII.
  3. Analytics Masking Profile - This masking profile is suited for analytics teams that need to retain statistical data characteristics while protecting PII.

Masking Profile Attributes

Masking profiles are comprised of the following attributes:

  • Name - a unique name of the profile.
  • Description - a short description of the profile.
  • Masking Conditions - a list of masking conditions.

Masking conditions define which transformation to apply for every classifier. Only one condition can be set for each classifier, such as EMAIL, PII or a custom classifier.

Creating a Dynamic Masking Rule

Masking profiles are used by security policies when defining dynamic masking rules. To create a dynamic masking rule, create a masking policy or edit an existing one. There are two modes for configuring dynamic masking rules, simple and advanced.

Simple Dynamic Masking Rule

When using the simple masking rule mode, only one dynamic masking rule can be defined in the security policy, which will apply the same masking profile for all users. To use the simple dynamic masking mode, perform the following steps:

  1. Open your security policy.
  2. Select the Dynamic Masking tab.
  3. Select the masking profile to enforce.
  4. Click Save.

Screenshot

Advanced Dynamic Masking Rule

In the advanced dynamic masking rule mode, multiple masking rules can be defined. For each rule, a different masking profile can be applied, and masking rules can match user queries based on various attributes. To use the advanced dynamic masking rule mode, perform the following steps:

  1. Open your security policy.
  2. Select the Dynamic Masking tab.
  3. Click on the Advanced button to configure the first rule.
  4. Select to which users the rule should be match.
  5. Select the masking profile to apply.
  6. Click on the plus or minus buttons to add or remove rules.
  7. Click Save.

Note: You can toggle on or off individual masking rules.

Screenshot

Select Users to Match to a Masking Rule

You can use several options to select which users match a masking rule.

The user is / is not

The dynamic masking rule should match a specific identity or all other users except a specific identity. There are multiple options for this identity:

  1. User - a user that is defined in the User Management page. For example: john.smith@acme.com.
  2. Datastore Username - a user that is defined locally in the data store. For example: JSMITH on a Snowflake account.
The user is a member / is not a member of

The dynamic masking rule matches if the user is or is not a member of a group. Several types of groups are supported:

  1. Group - refers to a Satori directory group. This option is only available for data stores that use the proxy-based integration.
  2. IdP Group - refers to a group that is managed by the organization’s identity provider and that is synchronized to Satori using the SCIM integration or SAML attributes. This option is only available for data stores that use the proxy-based integration.
  3. Databricks Group - refers to a group in a Databricks account
Custom Expression

Use this option to match users using a custom expression in a CEL (Common Expression Language) format. This enables you to create Attribute-Based Access Control (ABAC) masking rules, reducing the number of rules you need to manage.

You can either synchronize user attributes from your identity provider using the SCIM integration or manage them directly on Satori in the User Management view.

Satori provides the following built-in functions to create CEL expressions:

userMemberOfGroup - checks if a user is a member of the specified group. For example: userMemberOfGroup('groupA').

userHasAttr - checks if a user has an attribute with the specified name. For example: userHasAttr('attribute_name').

userAttr - returns the value of the user attribute with the specified name, or null if no such attribute exists. For example: userAttr('country') == 'value_of_attribute_name'.

You can also create nested logic rules using parenthesis, boolean OR (||) and boolean AND (&&). For example: userAttr('country') == 'US' && userAttr('team') = 'Customer Success'.

Screenshot

Conditional Masking

Conditional masking (sometimes referred to as cell-level security) enables you to apply masking profiles to specific rows of the result set.

To define a conditional masking rule add the SQL expression to determine whether or not to filter a specific cell in the Where section of the rule.

NOTE: Conditional masking is only available in the Databricks and Snowflake Native integrations.

Conditional Masking Examples

To apply a masking profile to rows where the region field is Europe, use the following SQL expression: region = 'Europe'.

To apply a masking profile to rows where the created_at field is before a certain date, use the following SQL expression: created_at < '2025-01-01'.

To apply a masking profile to rows where the team field does not equal a user’s team, assuming another table in the database contains that information, use the following SQL expression: team != (SELECT team FROM teams WHERE user = CURRENT_USER()).

NOTE: Satori validates that the SQL expression is syntactically correct, however, the SQL expression must match the data store type the policy is used for.

Masking Semi-Structured Data

For semi-structured data granularity (e.g. a specific location inside a JSON), masking is applied to specific fields without affecting other JSON locations. To mask information inside of a JSON field in your data source, you must first ensure that the semi-structured fields are created and classified in the Data Inventory.

For example, assume you have a JSON field named attrs with the following content:

{
    "customer": "John Doe",
    "items": {
        "SSN": "123-45-6789",
        "exp": "10/01/2025",
        "moresubnesting": {
            "SSN": "123-45-6789",
            "address": "123 Main Street"
        }
    }
}

If you want to mask the two SSN fields, you need to create two new entries in the data inventory under the attrs column, For example:

Screenshot

Satori uses JSONPath to reference field in semi-structured data types:

  • The root object is denoted as $.
  • Fields can be referenced using the dot notation. For example: $.property_name.
  • Fields that contain special characters or spaces should be referenced using the bracket notation. For example: $['property name'].
  • To reference object fields that are located in arrays, use the bracket notation with a wildcard. For example: $.array_name[*].property_name.

Once these new entries are created, you can classify them with Satori or custom taxonomy classifiers, just like any other field. From that point forward, Security Policies and Masking Profiles will be applied automatically as defined.

For example, nested masking might work as follows:

{
    "customer": "John Doe",
    "items": {
        "SSN": "******-6789",
        "exp":"10/01/2025",
        "moresubnesting": {
            "SSN": "******-6789",
            "address":"****treet"
        }
    }
}

Transformations

Generic Data Transformations

Name Example Definition
Hash data => 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Use this transformation to obfuscate the data completely while retaining its statistical properties for counting, aggregating, etc. note: hash transformations on numeric values result in changed/different numeric values.
Replace characters with 12345678 => aaaaaaaa Use this transformation to preserve the length of the original data
Replace entire string 12345678 => REDACTED Use this transformation to make it clear the data has been masked
Mask everything except last 12345678 => ******78 Use this transformation to retain a hint of the original data

Specific Data Transformations

In addition to the generic transformation, for selected data types specific transformation are available.

Email

Name Example Definition
Hash while preserving format user@company.net => 1234@567890a.bcd Generates a hashed version of the original email address. Use this transformation to preserve the original format of the data
Mask while preserving format user@company.net => ****@*******.*** Use this transformation to obfuscate the data completely while preserving its original format
Mask username user@company.net => ****@company.net Use this transformation to retain information about the domain name of the email address
Mask domain user@company.net => user@*******.*** Use this transformation to retain information about the username of the email address

Credit Card

Name Example Definition
Hash while preserving format 1234-5678-9012-3456 => abcd-ef12-3456-7890 Generates a hashed version of the original credit card. Use this transformation to preserve the original format of the data
Mask while preserving format 1234-5678-9012-3456 => ****-****-****-**** Use this transformation to obfuscate the data completely while preserving its original format
Show only last 4 digits 1234-5678-9012-3456 => ****-****-****-3456 Shows only last 4 digits

Date of Birth

Name Example Definition
Show only the year abcd 2/6/1975 abcd => *********1975***** Use this transformation to retain information about the year only

Public IP Address

Name Example Definition
Anonymize IP address 11.20.30.1 => 11.20.0.0 Use this transformation to retain /16 of an IPv4 address and /64 of an IPv6 address
Hash while preserving format 11.20.30.1 => ab.cd.ef.1 Generates a hashed version of the original IP address. Use this transformation to preserve the original format of the data
Mask while preserving format 11.20.30.1 => **.**.**.* Use this transformation to obfuscate the data completely while preserving its original format

Considerations and Known Limitations

The following section provides you with the relevant considerations and known limitations of the dynamic masking functionality.

Supported Data Stores

Dynamic masking is not supported in AWS S3, Elasticsearch, Microsoft Fabric, MongoDB and OpenSearch.

Matching Multiple Dynamic Masking Rules

  1. When more than one dynamic masking rule matches a user’s query, all masking profiles are logically merged into a single profile, this is the profile that is enforced. For example, if one profile masks emails and another masks person names and the user queries both emails and person names, both will be masked.

  2. When more than one data transformation matches a user’s query, the more specific transformation will be selected. For example, if a profile transforms both PII and Email and the user queries both emails and person names, then the PII transformation is used for a persons names and the email transformation will be used for emails.

  3. When multiple masking profiles match a user’s query, more than one data transformation of the same specificity can match a user’s query. In this case, Satori orders the profiles alphanumerically by their names in ascending order and selects the first one.

Dynamic Masking for Semi-structured Data

Dynamic masking for semi-structured data is only available for data stores that use the proxy-based integration.

Conditional Masking

  1. Conditional masking is only available in the Databricks and Snowflake Native integrations.

  2. When specifying an SQL expression for conditional masking, Satori expects the columns that are used for calculating the condition to have the same data types in all relevant tables. For example, when using the condition country is not NULL, Satori expects that the country column in all the tables that are included in the dataset to have the same data type (in the case of this example, it can be either a numeric or a textual data type).

  3. The SQL expression used for conditional masking cannot reference the column being masked, only other columns in the table. For example, when masking the country column, you cannot use the following SQL expression: country != 'US'.

  4. Some changes to the SQL expression for conditoinal masking may result in a short period of time where masking is not applied.

  5. Satori considers all non-qualified columns in the SQL expression for conditional masking as columns that are used for calculating the masking condition. For example, consider the following SQL expression used to mask PII in an employees table only for rows representing employees who earn more than their department's avergae. The salary and department_id columns are unqualified (i.e. no schema or database specified) therefore, they are expected to exist in the employees table.

salary > (
    SELECT departments.average_salary
    FROM departments
    WHERE department_id != departments.id
)