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

# Snowflake

> Connect Datafold to Snowflake for data diffing, CI/CD testing, lineage, and migration validation. Includes setup instructions and required permissions.

**NOTE**: Datafold needs permissions in your Snowflake account to read your table data. You will need to be a Snowflake *Admin* in order to create the user and grant the required permissions.

> [!NOTE]
>
> If your Snowflake account is only reachable via Azure Private Link, see [Securing Connections → Azure](https://docs.datafold.com/classic/security/securing-connections.md#azure-private-link). Snowflake routes large query results through an internal stage rather than the account endpoint, which typically requires a second private endpoint in addition to the account one.

> [!WARNING]
>
> Snowflake is retiring password sign-ins for non-human users: new service users must be created with `TYPE = SERVICE`, which cannot have a password, and between August and October 2026 Snowflake blocks password authentication for all existing service users. The steps below therefore create the Datafold user as a `SERVICE` user with key-pair authentication. If you already have a Datafold connection that uses a password, see [Snowflake key-pair authentication](https://docs.datafold.com/classic/integrations/databases/snowflake-key-pair-authentication.md).

**Steps to complete:**

* [Generate a key pair in Datafold](https://docs.datafold.com/classic/integrations/databases/snowflake.md#generate-a-key-pair-in-datafold)
* [Create a service user and role for Datafold](https://docs.datafold.com/classic/integrations/databases/snowflake.md#create-a-service-user-and-role-for-datafold)
* [Create a temporary schema](https://docs.datafold.com/classic/integrations/databases/snowflake.md#create-schema-for-datafold)
* [Give the Datafold role access to your warehouse](https://docs.datafold.com/classic/integrations/databases/snowflake.md#give-the-datafold-role-access)
* [Configure your data connection in Datafold](https://docs.datafold.com/classic/integrations/databases/snowflake.md#configure-in-datafold)

## Generate a key pair in Datafold

Datafold generates the key pair and keeps the private key encrypted inside Datafold. You only handle the public key, which you register on the Snowflake user.

1. In Datafold, go to **Settings** → **Data Connections**, add a new data connection and choose **Snowflake**.
2. Under **Authentication method**, select **Key pair**.
3. Next to **Key pair file**, click **Generate**, then **Download**. The downloaded `datafold.pub` is the public key.
4. Leave the form open; you will complete it after running the SQL below.

> [!NOTE]
>
> Snowflake expects the key without the `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines and without line breaks, for example:
>
> ```bash theme={null}
> grep -v -- '-----' datafold.pub | tr -d '\n'
> ```
>
> Use the result wherever the scripts below say `<public_key>`. If you close the form before saving, click **Generate** again and register the new key instead.

## Create a service user and role for Datafold

> A [full script](https://docs.datafold.com/classic/integrations/databases/snowflake.md#full-script) can be found at the bottom of this page.

It is best practice to create a separate role for the Datafold integration (e.g., `DATAFOLDROLE`) and a dedicated service user that authenticates with the public key:

```sql theme={null}
CREATE ROLE DATAFOLDROLE;

CREATE USER DATAFOLD
  TYPE = SERVICE
  DEFAULT_ROLE = DATAFOLDROLE
  RSA_PUBLIC_KEY = '<public_key>';

GRANT ROLE DATAFOLDROLE TO USER DATAFOLD;
```

> [!NOTE]
>
> Do not add `PASSWORD` or `MUST_CHANGE_PASSWORD`: Snowflake does not allow them on `SERVICE` users. Use `TYPE = SERVICE`, not the deprecated `LEGACY_SERVICE`.

To provide column-level lineage, Datafold needs to read & parse all SQL statements executed in your Snowflake account:

```sql theme={null}
GRANT MONITOR EXECUTION ON ACCOUNT TO ROLE DATAFOLDROLE;
GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE DATAFOLDROLE;
```

## Create schema for Datafold

Datafold utilizes a temporary dataset to materialize scratch work and keep data processing in your warehouse.

```sql theme={null}
CREATE SCHEMA <database_name>.DATAFOLD_TMP;
GRANT ALL ON SCHEMA <database_name>.DATAFOLD_TMP TO DATAFOLDROLE;
```

## Give the Datafold role access

Datafold will only scan the tables that it has access to. The snippet below will give Datafold read access to a database. If you have more than one database that you want to use in Datafold, rerun the script below for each one.

```sql theme={null}
/* Repeat for every DATABASE to be usable in Datafold. This allows Datafold to
correctly discover, profile & diff each table */
GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE DATAFOLDROLE;
GRANT USAGE ON DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT USAGE ON ALL SCHEMAS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT USAGE ON FUTURE SCHEMAS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL MATERIALIZED VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE MATERIALIZED VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT ALL PRIVILEGES ON ALL DYNAMIC TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE DYNAMIC TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
```

## Full Script

```sql theme={null}
--Step 1: Create a role and a SERVICE user for Datafold.
--        <public_key> is the body of datafold.pub, downloaded from Datafold,
--        without the BEGIN/END lines and without line breaks.
CREATE ROLE DATAFOLDROLE;

CREATE USER DATAFOLD
  TYPE = SERVICE
  DEFAULT_ROLE = DATAFOLDROLE
  RSA_PUBLIC_KEY = '<public_key>';

GRANT ROLE DATAFOLDROLE TO USER DATAFOLD;

GRANT MONITOR EXECUTION ON ACCOUNT TO ROLE DATAFOLDROLE;
GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE DATAFOLDROLE;

--Step 2: Create schema for Datafold
CREATE SCHEMA <database_name>.DATAFOLD_TMP;
GRANT ALL ON SCHEMA <database_name>.DATAFOLD_TMP TO DATAFOLDROLE;

--Step 3: Give the Datafold role access to your data connection
/*
  Repeat for every DATABASE to be usable in Datafold. This allows Datafold to
  correctly discover, profile & diff each table
*/
GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE DATAFOLDROLE;
GRANT USAGE ON DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT USAGE ON ALL SCHEMAS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT USAGE ON FUTURE SCHEMAS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT SELECT ON ALL MATERIALIZED VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE MATERIALIZED VIEWS IN DATABASE <database_name> TO ROLE DATAFOLDROLE;

GRANT ALL PRIVILEGES ON ALL DYNAMIC TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE DYNAMIC TABLES IN DATABASE <database_name> TO ROLE DATAFOLDROLE;
```

## Validate Snowflake Grants for Datafold

Run these queries to validate that the grants have been set up correctly:

> Note: More results may be returned than shown in the screenshots below if you have granted access to multiple roles/users

Example Placeholders:

* `<database_name>` = `DEV`
* `<warehouse_name>` = `DEMO`

```sql theme={null}
-- Validate database usage for the DATAFOLDROLE
SHOW GRANTS ON DATABASE <database_name>;
```

![](https://mintcdn.com/datafold/BHI8Zy_v4DyXlmzL/images/grants_on_database-cbcb5fd91f9d1ba6a680641fd1ed2cde.png?fit=max\&auto=format\&n=BHI8Zy_v4DyXlmzL\&q=85\&s=242ae31d65b18810648b26d7124c8161)

```sql theme={null}
-- Validate warehouse usage for the DATAFOLDROLE
SHOW GRANTS ON WAREHOUSE <warehouse_name>;
```

![](https://mintcdn.com/datafold/BHI8Zy_v4DyXlmzL/images/grants_on_warehouse-45351631336f32ccbeeaa6646a1a9199.png?fit=max\&auto=format\&n=BHI8Zy_v4DyXlmzL\&q=85\&s=5e98412c95861ed744dcfd60275a5b6d)

```sql theme={null}
-- Validate schema permissions for the DATAFOLDROLE
SHOW GRANTS ON SCHEMA <database_name>.DATAFOLD_TMP;
```

![](https://mintcdn.com/datafold/BHI8Zy_v4DyXlmzL/images/grants_on_schema-6955ab0c695f05ab0fd245a231a20837.png?fit=max\&auto=format\&n=BHI8Zy_v4DyXlmzL\&q=85\&s=5513f6f7210fcf3ead5b3c2049da36a4)

## A note on future grants

The above database grants will be insufficient if any future grants have been defined at the schema level, because [schema-level grants will override database-level grants](https://docs.snowflake.com/en/sql-reference/sql/grant-privilege#considerations). In that case, you will need to execute future grants for every existing *schema* that Datafold will operate on.

```sql theme={null}
GRANT SELECT ON FUTURE TABLES IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON FUTURE MATERIALIZED VIEWS IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON ALL TABLES IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
GRANT SELECT ON ALL MATERIALIZED VIEWS IN SCHEMA <database_name>.<schema_name> TO ROLE DATAFOLDROLE;
```

## Configure in Datafold

Return to the form you left open and fill in the remaining fields:

| Field Name | Description |
| - | - |
| Connection name | A name given to the data connection within Datafold |
| Account identifier | The Org name-Account name pair for your Snowflake account. This can be found in the browser address string. It may look like [https://orgname-accountname.snowflakecomputing.com](https://orgname-accountname.snowflakecomputing.com) or [https://app.snowflake.com/orgname/accountname](https://app.snowflake.com/orgname/accountname). In the setup form, enter \<orgname>-\<accountname>. |
| Username | The service user created above, `DATAFOLD` |
| Authentication method | **Key pair**. *Password* is deprecated by Snowflake for service users; *Azure Entra ID (External OAuth)* is available for accounts federated with Entra ID. |
| Key pair file | The key pair generated in [Generate a key pair in Datafold](https://docs.datafold.com/classic/integrations/databases/snowflake.md#generate-a-key-pair-in-datafold). **Regenerate** creates a new key pair, which you must register on the Snowflake user again. |
| Warehouse | The Snowflake warehouse name |
| Schema path for temporary tables | The schema you created with the script, as `<database_name>.DATAFOLD_TMP` |
| Role | The role you created for Datafold (typically `DATAFOLDROLE`) |
| Default database | A database the role above can access. If more than one database was added, whichever you prefer to be the default |
| Default schema | Schema prefixed to bare table names; defaults to `PUBLIC` |

> Note: Please review the documentation for the account name. Datafold uses Format 1 (Preferred): [https://docs.snowflake.com/en/user-guide/admin-account-identifier#format-1-preferred-account-name-in-your-organization](https://docs.snowflake.com/en/user-guide/admin-account-identifier#format-1-preferred-account-name-in-your-organization)

Click **Test connection**. Once it succeeds, click **Save**. Your data connection is ready!


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.