---
updatedAt: 2026-10-09T12:11:00.000Z
agentTools:
  projectIndex: https://docs.siffletdata.com/llms.txt
---

# Snowflake

Sifflet [monitors](https://docs.siffletdata.com/docs/monitor-templates) the health and quality of your Snowflake data, from table updates down to individual field values and business metrics. When an issue occurs, lineage built from your Snowflake query and access history shows its root cause upstream and the downstream tables and dashboards it affects. Sifflet also catalogs your Snowflake tables and views, with their tags and usage, so you can find what to monitor.

See [Snowflake Collected Data](https://docs.siffletdata.com/docs/collected-data) for the full list of assets and metadata Sifflet imports.

## Permissions Required

Sifflet connects to Snowflake with a dedicated Snowflake user and a dedicated role that has **read-only** access to your data and to Snowflake's account usage views. Sifflet runs its queries on a warehouse that you choose (a dedicated warehouse is recommended).

| Permission                                                                                                  | Used for                                                                                                                 | Required                                     |
| :---------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :------------------------------------------- |
| `USAGE` on the warehouse                                                                                    | Run metadata queries and monitor queries                                                                                 | Yes                                          |
| `MONITOR` on the warehouse                                                                                  | Not used today. Lets Sifflet read the warehouse's query activity, for future features without asking you for a new grant | Optional (recommended)                       |
| `IMPORTED PRIVILEGES` on database `SNOWFLAKE`                                                               | Read the `SNOWFLAKE.ACCOUNT_USAGE` views listed below: lineage, data usage, asset update history, and tags               | Yes (checked by **Test Connection**)         |
| `USAGE` on each monitored database and schema                                                               | List schemas and assets, read table and column metadata                                                                  | Yes                                          |
| `SELECT` on all tables, external tables, views, streams, and dynamic tables of each monitored schema        | Run monitors, data preview, and AI suggestions                                                                           | Yes                                          |
| `SELECT` on **future** tables, external tables, views, streams, and dynamic tables of each monitored schema | Monitor objects created after the setup without new grants                                                               | Optional (recommended)                       |
| `VIEW LINEAGE` on the account                                                                               | Field-level lineage of dynamic tables, read with the `SNOWFLAKE.CORE.GET_LINEAGE` function                               | Optional (dynamic table field-level lineage) |

Sifflet reads the following Snowflake system views:

| View                                                                              | Used for                                                                                                                                          |
| :-------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY`                                           | Lineage, [data usage](https://docs.siffletdata.com/docs/asset-usage), and [asset update history](https://docs.siffletdata.com/docs/asset-history) |
| `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY` (Snowflake Enterprise Edition or higher) | Lineage, data usage, and asset update history                                                                                                     |
| `SNOWFLAKE.ACCOUNT_USAGE.OBJECT_DEPENDENCIES`                                     | Lineage of views, materialized views, streams, and external tables                                                                                |
| `SNOWFLAKE.ACCOUNT_USAGE.DYNAMIC_TABLE_REFRESH_HISTORY`                           | Lineage of dynamic tables                                                                                                                         |
| `SNOWFLAKE.ACCOUNT_USAGE.TABLES`                                                  | Data usage                                                                                                                                        |
| `SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES`                                          | Snowflake tags on tables and columns                                                                                                              |
| `<DATABASE>.INFORMATION_SCHEMA.TABLES`                                            | [Freshness](https://docs.siffletdata.com/docs/freshness-gap) of the tables in each monitored database                                             |

Sifflet doesn't need any write permission: it never creates, modifies, or deletes objects in your Snowflake account.

**Cost and load**: Sifflet consumes credits on the warehouse configured in the source, when it refreshes metadata and when it runs monitors. The script in step 1 creates an X-Small warehouse that suspends after 5 seconds of inactivity. Use a warehouse dedicated to Sifflet to track this cost separately. Every monitor query starts with a SQL comment that contains `"app": "Sifflet"`, so you can also identify Sifflet's queries in `QUERY_HISTORY`.

## Requirements

### Required Roles for Setup

* **In Snowflake**: the `ACCOUNTADMIN` role, to create the role, the warehouse, and the user, and to grant `IMPORTED PRIVILEGES` on the `SNOWFLAKE` database. For OAuth authentication, you also need an administrator of your Microsoft Entra ID tenant.
* **In Sifflet**: the Admin system role to create the credential, and the Admin or System Editor role to create the source. See [Access Control](https://docs.siffletdata.com/docs/access-control).

### Supported Versions and Editions

* Sifflet supports all Snowflake editions.
* `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY` is only populated on Snowflake **Enterprise Edition or higher**. On Standard Edition, Sifflet builds lineage from the query history only, and doesn't collect data usage or asset update history. See [Limitations](https://docs.siffletdata.com/docs/collected-data#limitations).
* Supported authentication methods: key pair (recommended), external OAuth with Microsoft Entra ID, and username/password (deprecated by Snowflake).

### Network Access

* **Default**: Sifflet connects to your Snowflake account over the internet, at `https://<ACCOUNT_IDENTIFIER>.snowflakecomputing.com`.
* **IP allowlisting**: if you restrict access to your account with [Snowflake network policies](https://docs.snowflake.com/en/user-guide/network-policies), allow the IP addresses of your Sifflet instance, listed in **Settings > Integration Preferences**.

### Other Prerequisites

* **OAuth authentication only**: two application registrations in Microsoft Entra ID (one for your Snowflake resources, one for Sifflet as an OAuth client) and a Snowflake security integration of type `external_oauth`. See [Alternative: External OAuth with Microsoft Entra ID](#alternative-external-oauth-with-microsoft-entra-id).

## Connect Sifflet to Snowflake

### Step 1: Create a Service User in Snowflake

In this step, you create a role, a warehouse, and a service user for Sifflet, and grant the role read access to the schemas you want to monitor. Run all the SQL scripts below in the same Snowflake worksheet session, since they share session variables (`$role_name`, `$warehouse_name`).

<Callout icon="❗" theme="error">
  ### Snowflake identifiers are case-sensitive

  * Use an uppercase role name, and make sure the role doesn't already exist.
  * Use the same case for the warehouse, database, and schema names as in your Snowflake account.
</Callout>

#### Create the Role and the Warehouse

```sql
-- Set the values for the role name and warehouse name variables
set role_name = 'SIFFLET_ROLE'; -- VALUE TO REPLACE, make sure this role doesn't already exist
set warehouse_name = 'SIFFLET_WAREHOUSE'; -- VALUE TO REPLACE

use role accountadmin; -- needed to create the role, the warehouse, and the user

-- Create the Sifflet role
create role if not exists identifier($role_name);
grant role identifier($role_name) to role SYSADMIN;

-- Create a dedicated warehouse
create warehouse if not exists identifier($warehouse_name)
warehouse_size = xsmall
warehouse_type = standard
auto_suspend = 5
auto_resume = true
initially_suspended = true;

-- Grant the role access to the warehouse
grant usage on warehouse identifier($warehouse_name) to role identifier($role_name);
-- Optional (recommended): not used today, avoids a new grant for future features
grant monitor on warehouse identifier($warehouse_name) to role identifier($role_name);

-- Grant access to the SNOWFLAKE.ACCOUNT_USAGE views (query history, access history, tags...)
grant imported privileges on database SNOWFLAKE to role identifier($role_name);

-- Optional: field-level lineage of dynamic tables (SNOWFLAKE.CORE.GET_LINEAGE)
grant view lineage on account to role identifier($role_name);
```

#### Grant Access to the Schemas to Monitor

Run this block once for every schema you want to monitor in Sifflet. The first part is required; the second part (future grants) is optional but recommended, so that tables and views created later are monitored without new grants.

```sql
-- Repeat for every schema to monitor
set database_name = 'DATABASE_NAME'; -- VALUE TO REPLACE
set schema_name = 'DATABASE_NAME.SCHEMA_NAME'; -- VALUE TO REPLACE

-- Required: read access to existing objects
grant usage on database identifier($database_name) to role identifier($role_name);
grant usage on schema identifier($schema_name) to role identifier($role_name);
grant select on all tables in schema identifier($schema_name) to role identifier($role_name);
grant select on all external tables in schema identifier($schema_name) to role identifier($role_name);
grant select on all views in schema identifier($schema_name) to role identifier($role_name);
grant select on all streams in schema identifier($schema_name) to role identifier($role_name);
grant select on all dynamic tables in schema identifier($schema_name) to role identifier($role_name);

-- Optional (recommended): read access to objects created later
grant select on future tables in schema identifier($schema_name) to role identifier($role_name);
grant select on future external tables in schema identifier($schema_name) to role identifier($role_name);
grant select on future views in schema identifier($schema_name) to role identifier($role_name);
grant select on future streams in schema identifier($schema_name) to role identifier($role_name);
grant select on future dynamic tables in schema identifier($schema_name) to role identifier($role_name);
```

#### Create the User with Key Pair Authentication (Recommended)

Key pair authentication is recommended: it doesn't depend on a password, and Snowflake is phasing out single-factor password authentication for service users.

1. Generate a key pair by following the [Snowflake key pair authentication documentation](https://docs.snowflake.com/en/user-guide/key-pair-auth). You can generate:
   * an **encrypted** private key (recommended, the default): you then provide its passphrase to Sifflet in step 2;
   * an **unencrypted** private key, with the `-nocrypt` option: no passphrase is needed.

2. Create the user with the public key:

   ```sql
   set user_name = 'SIFFLET_USER'; -- VALUE TO REPLACE, make sure this user doesn't already exist
   set user_public_key = 'MIIBIjANBgkqh...'; -- VALUE TO REPLACE with the public key you generated

   -- Create the Sifflet service user
   create user if not exists identifier($user_name)
   rsa_public_key = $user_public_key
   type = service
   default_role = $role_name
   default_warehouse = $warehouse_name;

   -- Grant the Sifflet role to the user
   grant role identifier($role_name) to user identifier($user_name);
   ```

3. Keep the user name, the private key, and its passphrase (if any) for step 2.

#### Alternative: External OAuth with Microsoft Entra ID

Sifflet supports [Snowflake external OAuth with Microsoft Entra ID](https://docs.snowflake.com/en/user-guide/oauth-azure) as the identity provider and authorization server. **Sifflet authenticates as itself (client credentials), not on behalf of a user.**

1. In Microsoft Entra ID, configure two application registrations, following the Snowflake documentation linked above:
   * one that represents your Snowflake resources;
   * one that represents Sifflet as an OAuth client. This application must be allowed to access the Snowflake resources with the role you created above.

2. In Snowflake, create a security integration with the values of the application that represents your Snowflake resources (issuer, JWS keys URL, audience). For example:

   ```sql
   create security integration external_oauth_azure_sifflet
       type = external_oauth
       enabled = true
       external_oauth_type = azure
       external_oauth_issuer = 'https://sts.windows.net/<TENANT_ID>/' -- VALUE TO REPLACE
       external_oauth_jws_keys_url = 'https://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys' -- VALUE TO REPLACE
       external_oauth_token_user_mapping_claim = 'appid'
       external_oauth_snowflake_user_mapping_attribute = 'login_name'
       external_oauth_audience_list = ('<SNOWFLAKE_APPLICATION_ID_URI>') -- VALUE TO REPLACE, such as api://siffletdata.com/snowflake/aa1acf44-1a99-4b68-97cb-d1753a8baae0
       external_oauth_any_role_mode = 'ENABLE';
   ```

3. Create the Sifflet user, with the application ID of the Sifflet client application as login name:

   ```sql
   set user_name = 'SIFFLET_USER'; -- VALUE TO REPLACE, make sure this user doesn't already exist
   set login_name = 'b772183e-bfd1-46cc-9cca-0e09f51123eb'; -- VALUE TO REPLACE with the Entra ID application ID of the Sifflet client

   create user identifier($user_name)
   type = service
   login_name = $login_name
   default_role = $role_name;

   grant role identifier($role_name) to user identifier($user_name);
   ```

4. Keep the following values of the Sifflet client application for step 2:
   * **Client ID**: a UUID, such as `b772183e-bfd1-46cc-9cca-0e09f51123eb`.
   * **Client secret**. Entra ID client secrets expire: create a new secret and update the Sifflet credential before the expiry date.
   * **Authority**: a URL such as `https://login.microsoftonline.com/<TENANT_ID>`. In the Azure portal, find it under **Endpoints** on the app registration page.
   * **Token scope**: the application ID URI of your Snowflake resources application followed by `/.default`, such as `api://siffletdata.com/snowflake/aa1acf44-1a99-4b68-97cb-d1753a8baae0/.default`. The `.default` scope is required, since Sifflet uses the permissions granted to the OAuth client, not those of a user.

#### Alternative: Username and Password (Deprecated)

<Callout icon="🚧" theme="warn">
  ### Username/password authentication is deprecated

  Snowflake is phasing out single-factor password authentication. From August to October 2026, Snowflake blocks password authentication for all service users and requires multi-factor authentication (MFA) for all human users that sign in with a password. Username/password authentication isn't compatible with this requirement: use key pair authentication instead.
</Callout>

```sql
set user_name = 'SIFFLET_USER'; -- VALUE TO REPLACE, make sure this user doesn't already exist
set user_password = 'PASSWORD_CHANGE_ME'; -- VALUE TO REPLACE

-- Create the Sifflet user
create user if not exists identifier($user_name)
password = $user_password
default_role = $role_name
default_warehouse = $warehouse_name;

-- Grant the Sifflet role to the user
grant role identifier($role_name) to user identifier($user_name);
```

### Step 2: Add the Snowflake Source in Sifflet

#### Create the Credential

Go to **Integrations > Credentials**, click **New credential**, and paste the JSON that matches your authentication method in the **Credential** field.

**Key pair, encrypted private key**:

```json
{
  "user": "<USER_NAME>",
  "private_key": "<PRIVATE_KEY>",
  "private_key_passphrase": "<PASSPHRASE>"
}
```

**Key pair, unencrypted private key**: omit `private_key_passphrase`.

```json
{
  "user": "<USER_NAME>",
  "private_key": "<PRIVATE_KEY>"
}
```

**External OAuth with Microsoft Entra ID**: `oauth_provider` must be exactly `Microsoft Entra ID`.

```json
{
  "oauth_provider": "Microsoft Entra ID",
  "client_id": "<CLIENT_ID>",
  "client_secret": "<CLIENT_SECRET>",
  "authority": "<AUTHORITY_URL>",
  "scopes": ["<TOKEN_SCOPE>"]
}
```

**Username and password (deprecated)**:

```json
{
  "user": "<USER_NAME>",
  "password": "<PASSWORD>"
}
```

#### Create the Source

Go to **Integrations > Sources**, click **New source**, select **Snowflake**, and fill in the form:

| Field                    | Description                                                                                                                                                                                          | Example                                  |
| :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------- |
| Name                     | The name of the source in Sifflet                                                                                                                                                                    | `Snowflake production`                   |
| Account Identifier       | Your Snowflake account identifier: the part of your account URL before `.snowflakecomputing.com`, without `https://` (see below)                                                                     | `abcd123.eu-west-2` or `myorg-myaccount` |
| Warehouse                | The warehouse created in step 1                                                                                                                                                                      | `SIFFLET_WAREHOUSE`                      |
| Use Snowflake Native App | Only visible when the Native App is enabled on your instance. Leave it unchecked unless you use the [Native App](https://docs.siffletdata.com/docs/sifflet-native-app-for-snowflake-private-preview) | Unchecked                                |
| Credential               | The credential created above                                                                                                                                                                         | `snowflake-sifflet-user`                 |

<Callout icon="📘" theme="info">
  ### Finding the Snowflake account identifier

  In Snowsight, open the account menu at the bottom left, hover over your account, and click the link icon: this copies your account URL to the clipboard.

  ![](https://files.readme.io/b2cd9b9-Capture_decran_2023-03-08_a_19.21.51.png)

  The account identifier is the part of the URL before `.snowflakecomputing.com`. For example:

  * `https://abcd123.eu-west-2.snowflakecomputing.com` → `abcd123.eu-west-2`
  * `https://acme-marketing_test_account.snowflakecomputing.com` → `acme-marketing_test_account`
  * `https://app.snowflake.com/eu-west-2.aws/abcd123` → `abcd123.eu-west-2`

  Your account can be reachable through [several account identifiers](https://docs.snowflake.com/en/user-guide/admin-account-identifier#where-are-account-identifiers-used), such as `<orgname>-<account_name>` and `<account_locator>.<region>.<cloud>`. Use the same identifier as in the other tools connected to Snowflake (such as your BI tools), so that Sifflet links their assets to your Snowflake tables in the lineage.
</Callout>

#### Select the Scope

Click **Load assets** to list the databases and schemas that the Sifflet role can access, then select the schemas to include in the Data Catalog. Turn on **Automatically include new schemas** so that Sifflet catalogs schemas created later (as long as the Sifflet role can access them). Create one source for your whole Snowflake account, not one per database or schema. See [Integrations Management](https://docs.siffletdata.com/docs/integration-management) for scope, refresh frequency, and scheduling options.

#### Test and Save

Click **Test Connection**. Sifflet checks that it can:

* use the warehouse, and the database and schema;
* read each `SNOWFLAKE.ACCOUNT_USAGE` view listed in [Permissions Required](#permissions-required) and `INFORMATION_SCHEMA.TABLES`;
* list schemas, and list columns, objects, and streams in the selected schemas.

Each check reports its own result, so you can fix the missing grant directly. If a check fails, see [Snowflake Troubleshooting](https://docs.siffletdata.com/docs/troubleshooting-connectivity).

Then click **Save**. Sifflet starts the first metadata refresh right away: you can follow its status and logs from the source details in **Integrations > Sources**. Assets appear in the Data Catalog once the refresh completes.

### Alternative: Use the Sifflet Native App for Snowflake

The [Sifflet Native App for Snowflake](https://docs.siffletdata.com/docs/sifflet-native-app-for-snowflake-private-preview) (private preview) is an alternative to steps 1 and 2: you install the app in your Snowflake account, grant it access to the schemas to monitor, and create the source with **Use Snowflake Native App** checked. No Snowflake credential is stored in Sifflet, and your account doesn't need to accept inbound connections from Sifflet. Lineage isn't available through the Native App. Follow the [Native App installation guide](https://docs.siffletdata.com/docs/sifflet-native-app-for-snowflake-private-preview#installation).

## Troubleshooting

See [Snowflake Troubleshooting](https://docs.siffletdata.com/docs/troubleshooting-connectivity) for connection, authentication, permission, and metadata latency issues.