---
title: "Snowflake Column-Level Security"
slug: "snowflake-column-level-security"
updated: 2026-05-24T15:47:27Z
published: 2026-05-24T15:47:27Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plainid.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Snowflake Column-Level Security

**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

A **Column-based Masking Policy** is attached directly to a specific column in a table or view. The Masking Policy defines how specific column values should be transformed or hidden for certain users or under certain conditions. Column-based masking policies support highly specific business logic per column or table and provide tight localized control without changing global behavior.

- **Use Case Example**  

Only `credit_card_number` in the `payments` table has the rule:
  - Support role sees the **last 4 digits**
  - Fraud role sees the **full value**
  - All other users see `*****`

## 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](/v1/docs/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](/v1/docs/creating-policies).

---

**To create a Masking Policy with the Policy Wizard**:

1. **Input the Policy Details.** For more information, refer to the [Creating Policies](/v1/docs/creating-policies) article
2. Select **Use Policy For SaaS Applications** and select the Snowflake application.
3. **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.
4. 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** (OR relationship between them), 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](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28322%29.png)

For additional information on how to create a Dynamic group, see [Managing Dynamic Groups](/v1/docs/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](/v1/docs/managing-asset-types).

**To define access, you are required to connect the following Asset Types to a policy**:

1. Click **Add Asset Type**. Ensure that your Asset Type meets the [Signature Asset Types Prerequisites](/v1/docs/snowflake-column-level-security#signature-asset-type-prerequisites)
  - From the dropdown, select the **Asset Type** that represents the protected column where you want to apply masking logic.
    - 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 a single Ruleset that supports OR and AND relationships, as well as advanced logic operators ( =, !=,>,<, and more).
    - See [Defining a Ruleset for Masking Policies](/v1/docs/snowflake-column-level-security#defining-a-ruleset-for-masking-policies) to learn how to create a new ruleset.
  - Click **Save**.

1. Click **Add Asset Type**. Add **Snowflake Columns**.
  - From the dropdown, select **Snowflake Columns Asset Type**. For more information, see [Use Snowflake Columns Asset Types](/v1/docs/snowflake-column-level-security#snowflake-columns-assets).
  - Select the **Masking action**, which defines how data is masked. For more information, refer to [Actions as Masking Instructions](/snowflake-column-level-security#actions-as-masking-instructions) below.
  - Select the **Asset column** to apply masking to.  

Only one asset column from the same table can be selected per policy.
  - Click **Save**.

Iceberg Tables are also supported as part of the Table and View Assets. Ensure that you have the correct permissions by referring to the [Snowflake Setup](/v1/docs/snowflake-setup) article.

**In case you want to address any of the following scenarios:**

1. You want to apply different masking rules to the same column for different user groups.
2. You want to protect multiple columns across different tables within a single policy logic

Use the same Vendor Policy ID across multiple PlainID Masking Policies on the same Signature Asset Type.

Within that shared Asset Type, each ruleset may use different Asset Attributes as needed for its specific logic.

#### Defining a Ruleset for Masking Policies

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 documentation on [Managing Identity Source Tables](/docs/object-side-panel#managing-identity-source-tables) for more information.

1. Use PlainID's logic to combine operators (`=`, `!=`, `&gt;`, `IN`, etc.) with complex AND/OR relationships.

![image.png](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28327%29.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.

1. Select an existing **Condition** or create a new one.
  - A Policy can include multiple Conditions (AND relationship between them), meaning all Conditions must be met in the Policy to grant user access. Ensure that you select Conditions from Identity Attributes linked to the POP's Identity Source.
  - See [Managing Conditions](/v1/docs/managing-conditions) to learn how to create a new Identity Attribute Condition.
  - Ensure that the Condition meets the [Conditions for Masking Policy Requirements](/v1/docs/snowflake-column-level-access#conditions-for-masking-policy-requirements).
2. Click **Save**.

#### Defining a Condition for Masking Policies

- 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 documentation on [Managing Identity Source Tables](/docs/object-side-panel#managing-identity-source-tables).
- 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 defined in the PlainID platform. **Column-Based Masking Policy Deployment**: ![image.png](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28331%29.png)

## Signature Asset Type Prerequisites

To create a Masking policy, ensure the following requirements are configured at the Asset Type level.

#### Table Mapping

The Asset Type defines the protected column and contains the masking policy logic. It must be mapped to the relevant physical table or view as described below:

**To set Table Mapping**:

1. Within the Asset type details, 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](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28323%29.png)

For more information about Table Mapping, refer to [Dynamic Data Mapping](/v1/docs/dynamic-data-mapping).

#### Attribute Mapping

Each Asset Type includes attributes that represent:

1. The specific columns to be masked.
2. The columns used to define the policy Ruleset that determines when masking is applied.

Each of these columns must be mapped to the appropriate table as described below.

**To set Attribute Mapping**:

1. Choose an **existing Attribute** or create a new one to use in your Masking logic.
  - Refer to [Managing Asset Attributes](/v1/docs/managing-asset-attributes) for more details.
2. Define the **data type** (for example, String, Numeric).
3. Enable **Available for Policies = Yes**. These attributes are used to define the masking logic and can be used in policies.
4. Click **Set Data Column Mapping** to map the logical Attributes to one or more physical Snowflake column/s. Select the mapping table defined earlier, then enter the column name exactly as it appears in the vendor.
  - **Note:** Ensure the physical columns you wish to map are marked as **"Use in masking = On"** in the relevant Table or View in the Objects side panel within the Orchestration workspace. For more information, refer to [Asset Types for Column Level Requirements](/docs/snowflake-column-level-security#asset-types-for-columnlevel-requirements).  

![image.png](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28324%29.png)

![image.png](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28325%29.png)

#### Link Asset Type to Application:

To use an Asset Type in a policy:

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](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28326%29.png)

### Column Asset Types Prerequisites

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, refer to [Asset Types for Column Level Requirements](/docs/snowflake-column-level-security#asset-types-for-columnlevel-requirements).

In order to use Column Assets within a Masking Policy, the Signature Asset Type's Table Mapping must be predefined correctly. Refer to the [Signature Asset Types for Column Level Requirements](/v1/docs/snowflake-column-level-access#signature-asset-types-for-columnlevel-requirements) section for more information. ![image.png](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28328%29.png)

### Actions as Masking Instructions

In the **Snowflake Columns / Tags** Asset Types, the **Actions** tab defines how data is masked when a policy is enforced.

Masking instructions are applied to the selected Assets in your policy.

You can define masking actions in two ways:

1. **General masking actions** – specify the masking value directly in PlainID
2. **Vendor function masking actions** – call an existing vendor-native masking function (for example, a Snowflake function)

#### **Masking Action Fields**

The following fields are used when defining masking actions:

| Field | Description |
| --- | --- |
| **Action ID** | The display name of the masking action |
| **Value** | The masking value or expression returned by the policy (for example, `'MASKED'` or a vendor function expression) |
| **Type** | The returned masked value data type. This must match the `RETURNS` type declared in the Snowflake Masking Policy (for example, `VARCHAR`, `NUMBER`) |

#### **General Masking Actions**

Masking actions define the masking logic directly within PlainID.

You can either:

- Use a **default masking instruction** (for example, `Default for Varchar`, `Default for NUMBER`), or
- Create a **custom masking instruction**

**Example**

| Field | Value |
| --- | --- |
| Action ID | Mask String |
| Value | `'MASKED'` |
| Type | `FUNCTION_VARCHAR` or `FUNCTION_NUMERIC` |

This configuration causes the masking policy to return the specified value when masking is applied.

#### **Action Type (Function-Based Masking)**

When using vendor functions, set the **Type** field to one of the following:

- `Function_Varchar` – use when the function returns a **VARCHAR** value
- `Function_Numeric` – use when the function returns a **numeric** value

Once the masking action is defined, it can be used in policies to enforce column-level masking.

> **Note:** When using function-based masking actions for **Columns**, ensure the function return type matches the protected column data type.

#### **Using Vendor Functions as Masking Actions**

PlainID also supports referencing **vendor-native masking functions** directly in masking actions.

This capability allows you to reuse existing masking logic defined in the data platform without requiring the function to be discovered or managed as an object within PlainID.

This is useful when:

- Masking logic already exists in the vendor platform
- The masking logic requires **complex expressions or reusable functions**
- Masking behavior depends on **tags or metadata**

**To define a vendor function masking action**

1. Open your **Authorization Workspace**
2. Select the relevant **Application**
3. Click **Asset Types**
4. Hover over the relevant **Columns** (Asset Types) and click **Manage**.
5. Click **Actions**
6. Create a new Action

**Example**

```
PRODUCT_DB.SCHEMA1.STR_MASK_FUNC(
  FIXED_FIRST_ARG,
  SYSTEM$GET_TAG_ON_CURRENT_COLUMN('PRODUCT_DB.SCHEMA1.STR_MASK_FUNC')
)
```

In this example, the masking policy calls the vendor function `STR_MASK_FUNC` and passes the required arguments to apply the masking logic.

## 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 easily within the PlainID platform.

### Policy Syntax Table

| **Snowflake terminology** | **Snowflake Syntax** | **Description** | **PlainID terminology** |
| --- | --- | --- | --- |
| **Policy Declaration** | `CREATE OR REPLACE MASKING POLICY &lt;policy_name&gt;` | 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. 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, or a partially masked or fully masked version. The masking instructions are applied to the first argument. | Action in the Snowflake Columns Asset type. |
| **Policy Application** | Apply to a column: `ALTER TABLE &lt;table&gt; MODIFY COLUMN &lt;column&gt; SET MASKING POLICY &lt;policy&gt; USING (&lt;args&gt;);` | Applies the Masking Policy to a specific column. The same Policy can be reused across multiple columns and tables 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. |

## 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](https://cdn.document360.io/726c7002-05a9-480e-b986-42c9e8824acd/Images/Documentation/image%28333%29.png)

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