Snowflake Column-Level Security

Prev Next

Column-level security (CLS) allows organizations to control access to specific Table columns.

In Snowflake, Column-level security is implemented using Masking Policies.

A Masking Policy in Snowflake is a schema-level object that dynamically masks the data returned in a column of a Snowflake object (such as a table or view) at query time. The masking behavior is determined by conditional expressions and context functions, such as CURRENT_ROLE(), SESSION_USER(), or other supported Snowflake identity functions.

Dynamic Data Masking

Snowflake supports two types of Masking Policies:

  • Tag-Based Masking Policy (recommended)

A Tag-based Masking Policy leverages Snowflake Tags to define reusable Masking rules. A tag is associated with one or more columns across different tables, and then a Masking Policy is applied to that tag. Any column with the tag automatically enforces the associated masking logic.

Best practice: Use for scalable governance where similar data types (e.g., PII, credit card numbers, emails) exist in multiple locations and need consistent masking behavior.

  • Column-Based Masking Policy

A Column-based Masking Policy is directly attached to a specific column in a Table or View. The Policy evaluates the user's context when the column is queried and returns masked or unmasked data accordingly. Use for targeted column protection when the masking logic is simple and specific to one use case.

Creating a Snowflake Masking Policy

Note

Ensure that your Snowflake Application in Orchestration is switched to Manage mode to start building your Masking Policy in the Policy catalog section. See Managing POPs for more information on how to change the POP Mode.

Masking Policies in PlainID can be created using the following methods:

  • Wizard
  • Code
  • Native

For more information, refer to Creating Policies.


To create a Masking Policy with the Policy Wizard:

  1. Input the Policy Details. For more information, refer to the Creating Policies article

  2. Input the Snowflake POP Details specific to the vendor Policy:

    • Under the Vendor Policy Kind dropdown, select Masking Policy. (Required)
    • Enter a Vendor Policy Name, a unique name for the Policy that will appear in the Snowflake vendor. (Required)
      • Note: The same name can be used across multiple PlainID Policies to define multiple logic statements within a single Snowflake Masking Policy.
    • Under the Vendor Policy ID, note that the ID is automatically generated. It is the ID used in Policy management operations like deploy, update, and override.
    • Define the Vendor Policy Order, which relates to the execution order for the logical case statement within the same Vendor Policy ID. (Required).
      • The Default value is 1. Use this field when enforcing multiple logic conditions for different Identity Groups within the same Policy.
    • Enter a Comment, add any additional information or clarifications about your Policy. (Optional)
    • Under Database, select the Snowflake database where the Policy will be deployed.
    • Under Schema, select the schema within the database where the Policy resides.
    • Input an Owner, provide the POP Snowflake role used to manage the Policy.
  3. Click Continue.

Who Section

In the Who section, you can assign Column-level access by creating a new Dynamic Group or selecting an existing one. A single Policy can evaluate multiple Dynamic Groups, giving you flexibility in defining access control logic.

Select Dynamic Groups associated with identity attributes defined in your POP.

Dynamic Groups are defined using Snowflake identity functions such as CURRENT_USER(), CURRENT_ROLE(), IS_ROLE_IN_SESSION(), and CURRENT_SECONDARY_ROLES(). You can use multiple Identity functions within the same group to refine access. If you want to apply your Policy logic to all users, you can still connect the default "All Users" Dynamic Group.
image.png

For additional information on how to create a Dynamic group, see Managing Dynamic Groups.

What Section

In the What section, you can define access through your Asset Types.

For more details on Asset Types, refer to Managing Asset Types.

To define access, you are required to define the following Asset Types:

  1. Click Add Asset Type (for Policy Signature). Ensure that your Asset Type meets the requirements listed below
    • From the dropdown, select an Asset Type that defines your Masking Policy logic (Policy Signature. See Policy Syntax Table for more information.)
      • Only one Asset Type can be selected in a single Masking Policy.
    • Select existing Rulesets for your policy logic or create a new one. A Policy can include multiple Rulesets, note all combined with logical OR.
    • Click Save.
  1. To add Snowflake Columns Or Tag Asset Types, click Add Asset Type.
    • From the dropdown, select Snowflake Columns Asset Type or Tags Asset Type. For more information, see Use Snowflake Columns Asset type and Use Snowflake Tags Asset type.
    • Select the Masking action, which defines how data will be masked. For more information, please refer to define Masking Instructions below.
    • Select the Assets to mask (column or tag, depending on your selection).
      • A single Masking Policy can be applied to one Asset column or to multiple Asset tags.
    • Click Save.

Rulesets and Actions are currently not supported for Snowflake Column or Tag Asset Types.

Asset Types for Column-Level Requirements

Ensure that your Asset Type/s meet the following requirements:
*Table Mapping:
To set Table Mapping:

  1. Ensure that "Is used for data filtering?" is enabled.
  2. Select Set Table Mapping to link your logical Asset Type with one or more physical Tables or Views in Snowflake, where the Masking Policy should apply.
    • The mapping must include the fully qualified path to the table or view, following the format: DB_NAME.SCHEMA_NAME.TABLE_NAME.

image.png

For more information about Table Mapping, refer to Dynamic Data Mapping.

Attribute Mapping

To set Attribute Mapping:

  1. Choose an existing Attribute or create a new one to use in your Masking logic.
  2. Define the data type (for example, String, Numeric).
  3. Enable Available for Policies = Yes. These attributes act as placeholders for filtering conditions.
  4. Click Set Data Column Mapping to map the logical Attributes to one or more physical Snowflake column/s.
    • Note: ensure the physical columns you wish to map are marked as "Use in masking = On" in the relevant Table/View under the Objects side panel. For more information, refer to Managing Columns for Masking.
      image.png

image.png

To connect an Asset Type with the Snowflake Application:

  1. Once the Asset Type is created, open the Snowflake Application in your Orchestration Workspace.
  2. Navigate to the Asset Types tab.
  3. Click Edit.
  4. Select the relevant Asset Types you want to associate with the Snowflake application.
    image.png

Defining a Ruleset for Masking Policies

To define a Ruleset:

  1. In the Asset type within the Ruleset tab, define the Masking logic using the Asset Attributes you created (for example, Account_Level = 'Premium').

You can use Snowflake tables as an external Identity Source for contextual or dynamic rules (for example, Department = user.department). See our article Managing Identity Source for more information.

  1. Use PlainID's flexible logic to combine operators (=, !=, >, IN, etc.) with complex AND/OR relationships.

image.png

Snowflake Column Asset Types

The Snowflake Columns Asset Type is automatically generated when the Policy Orchestration Point (POP) is created. It represents a logical component that holds the available Snowflake columns for masking.

Snowflake Columns Assets

All those columns appear in the Assets section, and are either generated automatically from the Masking Policy in the discovery process or created by the user. For more information on how to create new Assets, please refer to Managing Columns for Masking.

In order to use the columns' assets within a Masking Policy, the Signature Asset Type's table Mapping needs to be predefined correctly. See Requirements above.

Snowflake Columns Actions

The Actions tab is used to define how the data should be masked. For more information, refer to Define Masking Instructions.

image.png

Snowflake Tags Asset type

Tag-based Masking Policies in Snowflake can be centrally managed through PlainID using the Snowflake Tags Asset Type. These Policies enable you to apply masking logic based on Snowflake tags rather than on individual columns, supporting scalable and consistent data protection across multiple tables.

Snowflake Tags Assets

Snowflake Available Tags to use in policy appear in the Assets section. PlainID discovers all available tags during the discovery process and displays them in the Object Side Panel within the Orchestration Workspace.

Note: PlainID does not create or manage Snowflake objects. Tags must be defined and applied to columns within the Snowflake environment.

Snowflake Tags Actions

The Actions tab is used to define how the data should be masked. For more information, refer to define Masking Instructions below.

image.png

Defining Masking Instructions

In the Snowflake Columns or Tags Asset Type, the Actions tab is used to define how the data should be masked. The masking instructions are applied to the selected Assets in your Policy.

You can either use a default masking instruction (e.g., Default for Varchar, Default for NUMBER) or create a custom masking instruction by specifying:

  • Input an Action ID: The display name of the action.
  • Input a Value: The actual masking logic (e.g., 'MASKED').
  • Choose a Type: The returned Masked Value's data type. This must match the RETURNS type declared in the Masking Policy (e.g., VARCHAR, NUMBER).

image.png

When Section

In the When section, you define the Conditions that provide contextual identity data for your Policy, which determine when the Policy applies.

To define a Condition:

  1. Select an existing Condition or create a new one.
    • A Policy can include multiple Conditions, combined with logical AND meaning all Conditions must be met for the Policy to grant access. Ensure that you select Conditions from Identity Attributes linked to the POP's Identity Source.
    • See Managing Conditions to learn how to create a new one Identity Attribute Condition.
    • Ensure that the Condition meets the Conditions for Masking Policy Requirements.
  2. Click Save.

Conditions for Masking Policy Requirements

  • Only Conditions based on Identity Attributes are supported for use in Masking Policies.
  • Ensure that an Identity Source table is defined within your Policy Orchestration Point (POP).
  • Use an Identity Attribute that is mapped to one of the additional Identity Sources associated with the selected POP. For more details, refer to our Managing Identity Source article.
  • Within a single Condition, you can only use Attributes from one Source.

Deploying the Policy

Once complete, navigate to the Orchestration Workspace and deploy the Policy to Snowflake.
Snowflake enforces the access decision based on the Masking logic you've defined in the PlainID platform.
Column-Based Masking Policy Deployment:
image.png

Tag-Based Masking Policy Deployment:
image.png

Snowflake Masking Policy SQL Structure

This table explains the components of a Snowflake Masking Policy in SQL and compares them to their equivalents in PlainID, helping you translate and build your Policies more easily within the PlainID platform.

Policy Syntax Table

Snowflake terminology Snowflake Syntax Description PlainID terminology
Policy Declaration CREATE OR REPLACE MASKING POLICY <policy_name> Defines the Policy name and type (Masking Policy). Used to declare or replace an existing Masking Policy. Vendor Policy Name, Vendor Policy Kind
Policy Signature AS (VAL1 VARCHAR, VAL2 NUMBER..) RETURNS VARCHAR Declares the Policy's input arguments and return type. Arguments are used in the Policy masking logic. The return type of the Masking Policy must match the data type of its first argument. The first argument is the masked value. Policy Signature mapped to Asset Type. Each argument that is used within the policy logic is created as an Asset Attribute.
Policy Logic WHEN... Incorporates Snowflake identity functions: CURRENT_ROLE(), CURRENT_USER(), IS_ROLE_IN_SESSION(), CURRENT_SECONDARY_ROLES() to determine who should receive access in a given context. Dynamic group
CASE... Use SQL expressions such as CASE statements to define the masking logic. Policy logic uses the policy arguments mapped into Rulesets, which can be dynamic (based on external identity data) or static (using fixed values).
EXISTS (SELECT... FROM... WHERE...) Use SQL subqueries with EXISTS SELECT for dynamic, context-based filtering. Policy logic uses an external table mapped into conditions, where expressions typically compare attributes to static values. Please note that a correlation must be defined using one of the Snowflake identity functions (e.g., CURRENT_ROLE(), CURRENT_USER(), IS_ROLE_IN_SESSION()).
Policy Output THEN 'MASK' ELSE VAL1 Defines the instructions used for masking data. Based on the policy logic, the output can be the original column value, a partially masked version, or a fully masked. The masking instructions are applied to the first argument. Action in the Snowflake Tags/Columns Asset type.
Policy Application Apply to a column: ALTER TABLE <table> MODIFY COLUMN <column> SET MASKING POLICY <policy> USING (<args>); Apply to a tag: ALTER TAG <tag> SET MASKING POLICY <policy>; Applies the Masking Policy to a specific column or tags. The same Policy can be reused across multiple columns, tables, or tags for consistent masking behavior. The Column-based masking is defined in the Signature Asset Type Data Settings. The first column is the masked value, mapped as an Asset in the Columns Asset Type. The Tags-based masking is reflected as Assets in the Tags-Asset Type.

Masking Policy Example

The following example demonstrates a Masking Policy that returns a 'MASKED' value for the Analyst role when the account_level is 'Premium'.

CREATE OR REPLACE MASKING POLICY MaskSSNForAnalystsOnPremium
AS (val STRING, val2 STRING)
RETURNS STRING ->
CASE
  WHEN CURRENT_ROLE() = 'ANALYST' AND val2 = 'Premium'
  THEN 'MASKED'
  ELSE val
END;

ALTER TABLE Accounts_table
MODIFY COLUMN SSN
SET MASKING POLICY MaskSSNForAnalystsOnPremium
USING (SSN, Account_Level);

image.png

For the current role Analyst, the policy masks SSN values only for the Premium account level