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

# Snowflake Target

The Snowflake Target Connector is a robust tool designed to facilitate the seamless integration of Change Data Capture (CDC) updates into Snowflake data warehouses. Leveraging Snowpipe streaming functionality, this connector efficiently streams CDC updates into Snowflake, where they are written as inserts. Subsequently, a dynamic table is employed to construct a copy of the source table, ensuring real-time data replication.

## Compatible versions

| | |
| - | - |
| **Snowflake** | Managed service — Standard edition or higher |
| **Required features** | Snowpipe Streaming and dynamic tables |
| **Authentication** | Key-pair (RSA 2048) — password authentication is not supported |
| **Driver** | Snowflake JDBC 4.3, Snowpipe Streaming SDK 1.7 |

<Note>Dynamic tables require a running warehouse for their refresh; size it for your change volume.</Note>

## Key Features

* **CDC Streaming:** utilizes Snowpipe streaming to deliver real-time changes from the source system.
* **Insert Operation:** writes CDC updates as inserts into the target Snowflake database, preserving the full change history.
* **Dynamic Table:** constructs a dynamic table to mirror the source table, enabling easy access to replicated data.
* **Time Travel Support:** retains historical data for time travel queries, facilitating data analysis and auditing.
* **Key-Pair Authentication:** relies on Snowflake's key-pair authentication mechanism — no passwords.
* **Schema evolution:** new columns are added automatically as the source schema evolves.

## Prerequisites

* A Snowflake account where you wish to sync your data.
* A **role** with the privileges listed under [Role privileges](#role-privileges) below.
* A **key pair** (no passphrase) for authentication. To set it up:

  1. Generate the key pair:
     ```bash theme={null}
     openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
     openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
     ```
  2. Register the public key on the Snowflake user:
     ```sql theme={null}
     ALTER USER <your_user> SET RSA_PUBLIC_KEY='<public_key_body>';
     ```
  3. Copy the private key **without** the header and footer lines:
     ```
     -----BEGIN PRIVATE KEY-----
     -----END PRIVATE KEY-----
     ```

### Role privileges

Run these as a role that can grant on the target database — `ACCOUNTADMIN`, or the
owner of the database and schema:

```sql theme={null}
GRANT USAGE ON DATABASE <database> TO ROLE <role>;
GRANT USAGE ON SCHEMA <database>.<schema> TO ROLE <role>;
GRANT USAGE ON WAREHOUSE <warehouse> TO ROLE <role>;
GRANT CREATE TABLE ON SCHEMA <database>.<schema> TO ROLE <role>;
GRANT CREATE PIPE ON SCHEMA <database>.<schema> TO ROLE <role>;
GRANT CREATE DYNAMIC TABLE ON SCHEMA <database>.<schema> TO ROLE <role>;
```

`USAGE` on the database and schema makes them visible to the role. `USAGE` on the
warehouse is what lets it create the dynamic table and run that table's refreshes —
the only part of provisioning that needs a running warehouse; the rest is
cloud-services DDL. `CREATE TABLE` covers the append-only changelog table the
connector creates per subscription. `CREATE PIPE` covers the Snowpipe Streaming
pipe it creates alongside each of those tables (`<table>_STREAMING`), which is the
object streamed rows actually arrive through — without it, provisioning fails
before the first row lands. `CREATE DYNAMIC TABLE` covers the current-state table
built over the changelog.

No `INSERT`, `UPDATE` or `DELETE` grant is needed: the connector creates the tables
it writes to and therefore owns them, and rows reach them through the pipe rather
than through SQL DML. If instead you point the connector at a schema whose tables
already exist and are owned by another role, that owner has to grant write and
schema-evolution rights on each one, or new source columns will fail to land:

```sql theme={null}
GRANT INSERT, EVOLVE SCHEMA ON TABLE <database>.<schema>.<table> TO ROLE <role>;
```

<Note>If a subscription writes its dynamic table to a different schema than the
connector's, repeat the `USAGE` and `CREATE DYNAMIC TABLE` grants on that schema
too.</Note>

## Configuration

| Field | Required | Description |
| - | - | - |
| **Account** | Yes | Snowflake account identifier (e.g. `myorg-myaccount` or `account.region.cloud`) |
| **User** | Yes | Username configured with key-pair authentication |
| **Database** | Yes | Database where tables will be created (e.g. `ANALYTICS_DB`) |
| **Schema** | Yes | Schema within the database (e.g. `PUBLIC`) |
| **Role** | Yes | Role to use for the session — must have write access to the target schema |
| **Private Key** | Yes | The private key body, without headers |
| **Enable Before/After** | Yes | When enabled, stores both the **before** and **after** images of each change event, allowing field-level change tracking in the target |

## How It Works

For each subscription, Popsink creates tables in the target schema and applies CDC events to keep Snowflake in sync with the source. Updates are streamed as inserts via Snowpipe streaming, and a dynamic table exposes the latest state of each table. Schema evolution is handled automatically — new columns are added as the source schema evolves.


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