Column masks
In Data Access, a column mask is a type of access control that masks sensitive data in specific columns from everyone except those who are explicitly authorized (called beneficiaries). The beneficiaries see unmasked data in those columns.
You can use column masks to restrict data visibility within columns. Column masks ensure that even if users have access on a data object, they cannot see sensitive data in a column unless they are authorized. With columns masks, you can control data visibility at the column level, define who can bypass the mask, and maintain a secondary layer of security that overrides roles.
Components of a column mask
A column mask is defined by the following components:
- What: Specifies the columns whose data needs to be masked for everyone, and the masking method applied to the columns, for example, redacted, hashed, or null values.
- Who: Specifies the beneficiaries who are granted an exception, meaning that they can bypass the mask. The beneficiaries are authorized to see the original, unmasked data in the columns, provided that they have access on the tables to which the columns belong. Everyone else sees masked data in those columns, even if they have Read access on the columns through a role.
How a column mask works
Suppose that you have a column mask for the Salary column with the Redacted masking method. The following scenarios explain how the column mask affects data visibility for a user named Cammy, who has Read access on the linked table through a role.
| Scenario | Result |
|---|---|
|
Cammy is not added as a beneficiary in the column mask. |
Cammy can see the table, but with redacted data in the Salary column. |
| Cammy is added as a beneficiary in the column mask. | Cammy can see unmasked data in the Salary column. |
| Cammy is added as a beneficiary in the column mask, but her Read access on the table is revoked. | Cammy cannot see the table itself. |
| Two column masks exist for the same Salary column, and Cammy is added as a beneficiary in only one of them. | Cammy can still see unmasked data in the Salary column. |
Masking methods
The masking method in a column mask defines how sensitive data within a column is masked. The available masking methods vary by data source. NULL is a common masking method.
If multiple column masks with different masking methods are applied to the same column, Data Access enforces the most restrictive masking method.
Custom masking methods for Snowflake
Custom masking functions allow you to use your organization's own data masking logic in Data Access, for example, masking an email address while preserving the domain for business analytics.
If your Snowflake Enterprise Edition account contains user-defined functions (UDFs), you can specify them in the Custom Masking Functions field when you configure Snowflake in Data Access.
DATABASE.SCHEMA.FUNCTION_NAMEThe specified custom masking functions appear as selectable masking methods in column masks, alongside the built-in options such as Hash (SHA-256), Email mask, Show first four characters, and Show last four characters. By default, a custom masking function uses its fully qualified name in column masks, for example, MARKETING_DB.HELPERS.MASK_EMAIL_DOMAIN. To show a user-friendly name instead, such as Email Domain Mask, add a display_name tag to the function in Snowflake. The function then uses the tag value as the display name in column masks.
Before Data Access makes a custom masking function available as a masking method, it verifies that the function meets all of the following criteria:
- The function exists in Snowflake.
- The sync role used for Data Access in Snowflake has the
USAGEpermission on the function. - The function accepts exactly one input parameter.
- The function returns the same data type that it receives. For example, a function applied to a
VARCHARcolumn must return aVARCHAR.
If a function fails the validation, Data Access skips the function, logs a warning, and continues the synchronization.
Who can bypass the mask (exceptions)
Beneficiaries are the specific identities, groups, or roles that are authorized to bypass a column mask. When defining these beneficiaries, your selection determines whether they are granted a global exception or a local exception.
Global exception
If you want to unmask all the columns that you select in a column mask for an identity or a group, apply a global exception by adding the identity or group directly to the Authorized identities section. This unmasks all the columns that are within the data objects on which the identity or group has access, through any role.
Because of such broad access, we recommend that you reserve global exceptions for super users and administrators who need full visibility across all datasets associated with the columns.
Local exception
If you do not want to unmask all the columns that you select in a column mask, apply a local exception by adding a role to the Authorized identities section. This unmasks only those columns that are within the data objects on which the role you selected grants access, for the beneficiaries of the role.
Because of such scoped access, we recommend local exceptions for maintaining the principle of least privilege.
How global and local exceptions work
You do not have to apply a single column mask to only one table. When you create a column mask, you can select multiple columns from completely different tables across your data sources. For example, you can create a single column mask named Address Mask, and apply it to the following columns:
- The Home Address column in the CUSTOMER table.
- The Home Address column in the EMPLOYEE table.
- The Billing Address column in the INVOICE table.
Implications of granting global exception
You grant a global exception in a column mask by adding an identity or a group to the Authorized identities section.
Suppose that an identity, Ayesha, has access on the CUSTOMER, EMPLOYEE, and INVOICE tables. If you add Ayesha as a beneficiary to Address Mask, she can see unmasked addresses in all the three tables.
Implications of granting local exception
You grant a local exception in a column mask by adding a role to the Authorized identities section, instead of adding an identity or a group.
Suppose that Ayesha is a beneficiary of a role named Sales Role, which grants her access only on the CUSTOMER table. Instead of adding Ayesha as a beneficiary to Address Mask, if you add Sales Role, Ayesha can see unmasked addresses only in the CUSTOMER table. If she happens to have another role that grants her access on the EMPLOYEE table, the addresses in the EMPLOYEE table still remain completely masked for her, because Sales Role does not cover the EMPLOYEE table.
Because a local exception restricts unmasked data access only to the specific tables that a user is already authorized to work in, we recommend it for maintaining the principle of least privilege.
Dynamic rules in column masks
With dynamic rules, you can define conditions that automatically determine which columns are masked and which identities can see unmasked data, without having to select each entity individually.
Suppose that you have a database structure where a database (HR_Database) contains a table (Employees_Table), and the table contains a column (Salary_Column).
HR_Database → Employees_Table → Salary_Column
You are configuring a column mask with a dynamic rule that is scoped to HR_Database and defined by the tag Sensitivity:PII. The behavior of your column mask changes depending on which tag operator you select.
"Has tag" operator
With the Has tag operator, the dynamic rule is activated only if the tag is directly on the target column.
If the Sensitivity:PII tag is on Salary_Column, Data Access masks the data in Salary_Column. If, however, the Sensitivity:PII tag is not on Salary_Column but is instead on Employees_Table or HR_Database, Data Access ignores the column mask, which means that the data in Salary_Column remains unmasked.
"Inherits tag" operator
With the Inherits tag operator, the dynamic rule is activated only if the tag is directly on the target column, or if the tag is inherited from any of its ancestors.
If the Sensitivity:PII tag is on Salary_Column, Data Access masks the data in Salary_Column. If, however, the Sensitivity:PII tag is not on Salary_Column but is instead on HR_Database, Data Access still masks the data in Salary_Column.