> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/build/stage-2-productize/connect-to-engine/snowflake.md).

# Snowflake

Snowflake is a scalable cloud data warehouse for enterprise analytics and data sharing. Vulcan integrates seamlessly with Snowflake to manage your data transformations with version control and safe deployments.

***

### Engine adapter type

For Snowflake, you configure a gateway with the following adapter type:

```yaml
type: snowflake
```

This engine can be used with Vulcan’s local or built-in scheduler for running model jobs.

### Before you start

Make sure you have:

* A Snowflake account with valid credentials
* A warehouse available for running computations

***

### Access model overview

Snowflake access in DataOS is split into two distinct areas:

| Area                                  | Purpose                                                                                                           |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Source schema (read-only)**         | Dataset discovery, profiling, data quality checks, semantic querying, reading upstream tables during model builds |
| **Target schema (managed by Vulcan)** | Tables and views created and updated by Vulcan during model materialization                                       |

***

### Source schema access (read-only)

Grant these permissions on every source schema Vulcan reads from:

```sql
GRANT USAGE ON WAREHOUSE <WAREHOUSE_NAME> TO ROLE <DATAOS_ROLE>;
GRANT USAGE ON DATABASE <DATABASE_NAME> TO ROLE <DATAOS_ROLE>;
GRANT USAGE ON SCHEMA <DATABASE_NAME>.<SOURCE_SCHEMA> TO ROLE <DATAOS_ROLE>;

GRANT SELECT ON ALL TABLES IN SCHEMA <DATABASE_NAME>.<SOURCE_SCHEMA> TO ROLE <DATAOS_ROLE>;
GRANT SELECT ON FUTURE TABLES IN SCHEMA <DATABASE_NAME>.<SOURCE_SCHEMA> TO ROLE <DATAOS_ROLE>;

GRANT SELECT ON ALL VIEWS IN SCHEMA <DATABASE_NAME>.<SOURCE_SCHEMA> TO ROLE <DATAOS_ROLE>;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA <DATABASE_NAME>.<SOURCE_SCHEMA> TO ROLE <DATAOS_ROLE>;
```

***

### Target schema access (managed by Vulcan)

Grant these permissions on the schema where Vulcan materializes model output:

```sql
GRANT CREATE SCHEMA ON DATABASE <DATABASE_NAME> TO ROLE <DATAOS_ROLE>;

GRANT USAGE ON SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA> TO ROLE <DATAOS_ROLE>;
GRANT CREATE TABLE ON SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA> TO ROLE <DATAOS_ROLE>;
GRANT CREATE VIEW ON SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA> TO ROLE <DATAOS_ROLE>;

GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE
  ON ALL TABLES IN SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA>
  TO ROLE <DATAOS_ROLE>;

GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE
  ON FUTURE TABLES IN SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA>
  TO ROLE <DATAOS_ROLE>;

GRANT SELECT ON ALL VIEWS IN SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA> TO ROLE <DATAOS_ROLE>;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA> TO ROLE <DATAOS_ROLE>;
```

**Why `DELETE` is required:** Vulcan uses `DELETE` for incremental model rebuilds. When reprocessing a partition or time range, Vulcan deletes existing rows for that slice, then inserts refreshed rows. This prevents duplicate and stale records. `DELETE` is only needed on Vulcan-managed target tables, not on source schemas.

**Why `TRUNCATE` is required:** Vulcan uses `TRUNCATE` for full refreshes and overwrite-style rebuilds where the entire table is regenerated.

**When `OWNERSHIP` is required:** `OWNERSHIP` is needed only if DataOS must fully manage the target schema lifecycle (`ALTER`, `REPLACE`, `DROP`):

```sql
CREATE SCHEMA IF NOT EXISTS <DATABASE_NAME>.<TARGET_SCHEMA>;

GRANT OWNERSHIP ON SCHEMA <DATABASE_NAME>.<TARGET_SCHEMA>
  TO ROLE <DATAOS_ROLE>
  COPY CURRENT GRANTS;
```

***

### Required connection options

Use these fields when setting up a Snowflake gateway:

<table><thead><tr><th width="235.2410888671875">Option</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>Engine type name - must be <code>snowflake</code></td></tr><tr><td><code>account</code></td><td>The Snowflake account identifier, for example, <code>org-name-account-name</code></td></tr><tr><td><code>user</code></td><td>The username to use for authentication with the Snowflake server</td></tr><tr><td><code>password</code></td><td>The password to use for authentication with the Snowflake server</td></tr><tr><td><code>warehouse</code></td><td>The name of the Snowflake warehouse to use for running computations</td></tr><tr><td><code>database</code></td><td>The name of the Snowflake database instance to connect to</td></tr></tbody></table>

***

### Optional connection options

Use these fields only if your Snowflake environment requires them:

| Option                   | Description                                                                   |
| ------------------------ | ----------------------------------------------------------------------------- |
| `role`                   | The role to use for authentication with the Snowflake server                  |
| `authenticator`          | The Snowflake authenticator method, for example, `externalbrowser` or `oauth` |
| `token`                  | The Snowflake OAuth 2.0 access token for authentication                       |
| `private_key_path`       | The path to the private key file to use for authentication                    |
| `private_key_passphrase` | The passphrase to decrypt the private key, if encrypted                       |

***

### Authentication methods

Snowflake supports the following authentication methods for this gateway:

| Method                           | How to configure                                    |
| -------------------------------- | --------------------------------------------------- |
| Username/password authentication | Use `user` and `password`                           |
| OAuth 2.0 token authentication   | Use `token`                                         |
| External browser authentication  | Use `authenticator: externalbrowser`                |
| Private key authentication       | Use `private_key_path` and `private_key_passphrase` |
| Role-based authentication        | Use `role`                                          |

***

### Example configuration

Add a Snowflake gateway to your Vulcan project configuration.

```yaml
gateways:
  snowflake:
    type: snowflake
    account: <org-name-account-name>
    user: <username>
    password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
    warehouse: <warehouse-name>
    database: <database-name>
    role: <role-name>
```

> The account identifier format is `<org-name>-<account-name>`, find it in your Snowflake URL.

> Always use environment variables for sensitive credentials:
>
> ```
> password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
> ```

***

### Materialization behavior

Snowflake uses the following materialization strategies depending on the model kind:

| Model kind                  | Strategy                                |
| --------------------------- | --------------------------------------- |
| `INCREMENTAL_BY_TIME_RANGE` | DELETE by time range, then INSERT       |
| `INCREMENTAL_BY_UNIQUE_KEY` | MERGE ON unique key                     |
| `INCREMENTAL_BY_PARTITION`  | DELETE by partitioning key, then INSERT |
| `FULL`                      | CREATE OR REPLACE TABLE                 |

For a quick start:

* Use `FULL` when you want to rebuild the output from scratch.
* Use incremental strategies when you want to update only the records that have changed, the time ranges, the unique keys, or the partitions.

***

### Identifier casing in semantics

Snowflake stores unquoted identifiers in uppercase by default. When Snowflake is the engine behind your semantic layer, the warehouse will only resolve column references that match its stored casing.

This means dimension lists, measure expressions, filters, and join clauses must all use uppercase column names.

Example:

```yaml
dimensions:
  - USER_ID
  - SIGNUP_DATE
  - PLAN_TYPE

measures:
  - name: active_users
    type: count
    filters:
      - "{users.STATUS} = 'active'"
```

***

### Import existing Snowflake Semantic Views

If you already have semantic views defined natively in Snowflake, you can bring them into your Vulcan project instead of authoring `kind: semantic` YAML by hand.

```bash
# 1. Import the semantic view definition
vulcan import_semantic_view MY_SEMANTIC_VIEW --connection default

# 2. Generate external table stubs
vulcan create_external_models

# 3. Fix inputs.yaml (remove extra quotes, add dialect and grain), then plan
vulcan plan
```

Vulcan translates the view definition into its semantic format and makes it queryable via REST, GraphQL, and MySQL wire protocol endpoints.

For the complete walkthrough and `inputs.yaml` fix details, see [Import Snowflake Semantic Views](/concepts/resources/vulcan/guides/import-snowflake-semantic-views.md).

***

### Next steps

After configuring Snowflake, continue with:

```
Connect to Engine → Define models and logic → Validate and test locally
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/build/stage-2-productize/connect-to-engine/snowflake.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
