Skip to content

Masking Policies

Masking policies define what a column’s data looks like to roles that do not have visibility. Under Rime’s masked-by-default model, every column has a masking policy applied through Snowflake’s tag-based masking. The policy determines whether a role without access sees ****, NULL, a partial value, a hash, or a truncated date.

This page covers the available masking types, how policies are bound to tags and columns in Snowflake, how to create and customise policies, and how role-based visibility works.

Masking types

Rime provides five built-in masking types. Each serves a different purpose depending on the data type and how much information should be preserved for users without full access.

Full mask

Replaces the entire value with a fixed string.

Data typeMasked output
VARCHAR****
NUMBER0
BOOLEANFALSE

Full masking is the default for most string columns and for any column where no information should leak. It is the safest option and is applied to all unclassified columns.

Null mask

Replaces the value with NULL. This is the default for numeric and date columns where a placeholder value like 0 could be misleading (e.g., a balance column showing 0 instead of the actual value might be misinterpreted as a real zero balance).

Partial mask

Preserves part of the value while masking the rest. Partial masking is useful when some portion of the data is needed for identification or verification without exposing the full value.

PII typePartial mask outputExample
PhoneLast 4 digits visible***-***-7890
EmailFirst character + domainj***@example.com
Bank accountLast 3 digits visible**-****-*******-789
IRD numberLast 3 digits visible***-***-789

Partial masking is the default policy for phone numbers and email addresses at the Confidential privacy level. For Restricted-level data (IRD numbers, bank accounts), full masking is the default and partial masking must be explicitly configured.

Hash

Replaces the value with a deterministic SHA-256 hash. The same input always produces the same hash, which preserves referential integrity across tables.

Hash masking is useful when:

  • Analysts need to join tables on a masked column without seeing the actual values
  • You want to count distinct values in a masked column
  • Data scientists need to track entities across datasets without accessing PII

The hash output is a 64-character hexadecimal string (e.g., a3f2b8c1d4e5f6...).

Date truncation

Replaces a date or timestamp with a truncated version that preserves the year but removes the month, day, and time.

Original valueTruncated output
2024-07-15 14:30:002024-01-01 00:00:00
1985-03-221985-01-01

Date truncation is the default for date-of-birth columns at the Confidential level. It allows age-range analysis without exposing exact birth dates.

How masking works in Snowflake

Rime uses Snowflake’s tag-based masking policy feature. The architecture has three layers:

  1. Tags — Rime creates Snowflake tags for each privacy level and PII type (e.g., RIME_PRIVACY_LEVEL, RIME_PII_TYPE). When you classify a column, Rime sets the appropriate tag values on that column.

  2. Masking policies — Rime creates Snowflake masking policies and binds them to tags. A masking policy is a SQL function that takes the column value and returns either the original value (for authorised roles) or the masked version. The policy checks the querying role against a list of authorised roles at execution time.

  3. Role authorisation — Rime maintains a mapping of which roles can see unmasked data for each privacy level and PII type. This mapping is encoded in the masking policy’s conditional logic.

When a query executes, Snowflake:

  1. Checks the column’s tags
  2. Finds the masking policy bound to those tags
  3. Evaluates the policy: if the current role is authorised, return the real value; otherwise, return the masked value

This happens entirely within the Snowflake engine. Rime is not in the query path.

Creating a masking policy

Rime ships with default masking policies for each privacy level and PII type combination. You can customise these or create new policies.

To create a custom masking policy:

  1. Navigate to Governance > Masking Policies
  2. Select Create Policy
  3. Configure the policy:
    • Name — a descriptive identifier (e.g., “Partial email - domain visible”)
    • Data type — the Snowflake data type this policy applies to (VARCHAR, NUMBER, DATE, TIMESTAMP, BOOLEAN)
    • Masking type — select from full mask, null mask, partial mask, hash, or date truncation
    • Partial mask configuration (if applicable) — specify which characters to preserve and the mask character
  4. Select Save

To assign a custom policy to a privacy level or PII type:

  1. Open the policy list in Governance > Masking Policies
  2. Select the policy
  3. Under Assignments, choose which privacy level or PII type combinations should use this policy
  4. Select Apply

Changes to masking policies take effect immediately in Snowflake. Any subsequent query against an affected column will use the new masking behaviour.

Default policies

Rime automatically applies these default policies when columns are classified:

Privacy levelPII typeDefault masking
PublicAnyNo masking (visible to all roles with query access)
InternalAnyFull mask
ConfidentialNameFull mask
ConfidentialEmailPartial mask (first character + domain)
ConfidentialPhonePartial mask (last 4 digits)
ConfidentialDate of birthDate truncation (year only)
ConfidentialAddressFull mask
ConfidentialOtherFull mask
RestrictedAnyFull mask

You can override any default by creating a custom policy and assigning it to the relevant combination.

Role-based visibility

Masking policies are only useful if the right roles can see through them. Rime manages role-based visibility through the Access Matrix in the governance UI.

To grant a role visibility:

  1. Navigate to Governance > Masking Policies > Access Matrix
  2. The matrix shows roles as rows and privacy levels as columns
  3. Check the box at the intersection of a role and privacy level to grant that role visibility for columns at that level
  4. Select Apply Changes

You can also grant visibility at the PII type level for finer control. For example, you might allow ANALYST_ROLE to see Confidential columns generally but not Confidential columns tagged as phone numbers.

Preview

Before applying access changes, select Preview to see exactly what a specific role will see for a sample of affected columns. The preview shows the column name, the current masked output, and what the role would see after the change. This helps verify that you are not inadvertently exposing data.

Custom masking expressions

For advanced use cases, Rime supports custom masking expressions written in Snowflake SQL. This allows you to implement masking logic that goes beyond the built-in types.

To create a custom expression:

  1. Navigate to Governance > Masking Policies > Create Policy
  2. Select Custom Expression as the masking type
  3. Write a SQL expression that takes the column value as input and returns the masked value. The expression uses masked_value as the input variable
  4. Test the expression against sample data
  5. Save and assign the policy

Example custom expressions:

-- Show first 3 characters of a string
LEFT(masked_value, 3) || '***'
-- Mask email but preserve domain length
REPEAT('*', CHARINDEX('@', masked_value) - 1) || SUBSTR(masked_value, CHARINDEX('@', masked_value))
-- Round a numeric value to the nearest thousand
ROUND(masked_value, -3)

Custom expressions must return the same data type as the input column. Rime validates the expression before saving.

Tier availability

Masking policies are available at Business tier and above. Lower tiers do not include tag-based masking or custom masking policies. See Masked by Default for full tier details.

Next steps