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

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.omni.co/feedback

```json
{
  "path": "/connect-data/setup/snowflake",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Connecting Snowflake to Omni

> Learn how to create a database user, grant permissions, and connect your Snowflake data warehouse to Omni.

export const BaseAccess = () => {
  return <span>
      <ParamField path="Base Access" required>
        Select the <a href="/administration/users/permissions">minimum level of access</a> users should have to models in the connection.
      </ParamField>
    </span>;
};

export const AlwaysScopeViewNames = () => {
  return <span>
      <ParamField path="Always Scope View Names" default="enabled">
        When enabled, Omni will prefix generated view names with schema and catalog, e.g. <code>my_catalog_public__orders</code> instead of <code>orders</code>. Defaults to enabled. See <a href="/connect-data/view-name-generation">View name generation</a> for more information.
      </ParamField>
    </span>;
};

export const AutoGenerateRelationshipsAllModes = () => {
  return <span>
      <ParamField path="Auto-generate relationships" default="Both">
        Controls how Omni infers relationships during schema refreshes. Select from four modes:

        <ul>
        <li><strong>Both</strong> - Infer from foreign key constraints and column name matching</li>
        <li><strong>Foreign keys only</strong> - Foreign key constraints only</li>
        <li><strong>Column names only</strong> - Column name matching only</li>
        <li><strong>None</strong> - Skip auto-generation entirely</li>
        </ul>
      </ParamField>
    </span>;
};

export const QueryTimeout = ({defaultValue}) => {
  return <span>
      <ParamField path="Query Timeout" default={defaultValue}>
        Maximum time in seconds before a query times out.
      </ParamField>
    </span>;
};

export const AllowUserSpecificTimezones = () => {
  return <span>
      <ParamField path="Allow User-Specific Timezones">
        When enabled, users can override the connection timezone with their own when querying.
      </ParamField>
    </span>;
};

export const QueryTimezone = () => {
  return <span>
      <ParamField path="Query Timezone" required>
        The timezone to use for Omni queries. If a timezone is specified, data will be converted from the <strong>Database Timezone</strong> to the selected timezone.
      </ParamField>
    </span>;
};

export const DatabaseTimezone = () => {
  return <span>
      <ParamField path="Database Timezone" required>
        The timezone used by the database.
      </ParamField>
    </span>;
};

export const TableUploads = ({label = "Schema for Table Uploads", term = "schema"}) => {
  return <span>
      <ParamField path={label}>
        The name of the {term} to use for table (CSV) uploads. If left blank, you can upload tables but they won't be pushed to the database or be available for use in joins.
      </ParamField>
    </span>;
};

export const Offloaded = ({term = "Schemas"}) => {
  const lower = term.toLowerCase();
  return <span>
      <ParamField path={`Offloaded ${term}`}>
        A comma-separated list of {lower} to include in the connection, which will only load on demand. This setting is good for large {lower} or dbt dev {lower}.
      </ParamField>
    </span>;
};

export const Include = ({term = "Schemas"}) => {
  const lower = term.toLowerCase();
  return <span>
      <ParamField path={`Include ${term}`}>
        A comma-separated list of {lower} to include in the connection.
      </ParamField>
    </span>;
};

export const IncludeOther = ({term = "Schemas"}) => {
  const lower = term.toLowerCase();
  return <span>
      <ParamField path={`Include Other ${term}`}>
        A comma-separated list of other {lower} to include in the connection.
      </ParamField>
    </span>;
};

export const Database = () => {
  return <span>
      <ParamField path="Database" required>
        The database to connect to.
      </ParamField>
    </span>;
};

export const Port = ({defaultValue}) => {
  return <span>
      <ParamField path="Port" required default={defaultValue}>
        The port number for the database connection.
      </ParamField>
    </span>;
};

export const DisplayName = () => {
  return <span>
      <ParamField path="Display Name" required>
        A user-friendly name for the connection, which will be used throughout Omni.
      </ParamField>
    </span>;
};

## Requirements

To follow the steps in this guide, you'll need:

* **Organization Admin permissions in Omni**
* **Permissions in Snowflake** that allow you to:
  * Create database users and grant permissions
  * Allowlist IP addresses
  * Set up key-pair authentication

## Setup

<Steps>
  <Step title="Create a database user for Omni" titleSize="h3">
    1. Sign in to your Snowflake account.
    2. Create a new worksheet.
    3. Run the following to create a role and user for Omni, and grant privileges:

       ```sql title="Create Omni role & user and grant privileges" theme={null}
       use role ACCOUNTADMIN;
       create role if not exists omni_role;
       create user if not exists omni_user;
       grant role omni_role to user omni_user;
       alter user omni_user set default_role = omni_role;
       alter user omni_user set type = service;
       alter user omni_user set default_warehouse = '<warehouse>';

       -- grant read only database access - repeat for all database/schemas:
       grant usage, monitor on database <database> to role omni_role;
       grant usage, monitor on schema <database>.<schema> to role omni_role;
       grant usage, monitor on warehouse <warehouse> to role omni_role;

       -- alternatively, grant read only database access across all schemas:
       grant usage, monitor on database <database> to role omni_role;
       grant usage, monitor on all schemas IN DATABASE <database> to role omni_role;
       grant usage, monitor on future schemas IN DATABASE <database> to role omni_role;
       grant usage, monitor on warehouse <warehouse> to role omni_role;

       -- grant access to all tables in the schema to omni_role:
       grant select on all tables in schema <database>.<schema> to role omni_role;
       grant select on future tables in schema <database>.<schema> to role omni_role;

       -- grant access to all views in the schema to omni_role:
       grant select on all views in schema <database>.<schema> to role omni_role;
       grant select on future views in schema <database>.<schema> to role omni_role;

       -- (optional) grant access to dynamic tables in the schema to omni_role:
       grant select on all dynamic tables in schema <database>.<schema> to role omni_role;
       grant select on future dynamic tables in schema <database>.<schema> to role omni_role;

       -- (optional) required to use the Model Assistant's "Suggest model from query history" skill
       grant imported privileges on database SNOWFLAKE TO ROLE omni_role;

       -- grant ownership of omni_role to omni_user:
       grant role omni_role to user omni_user;
       ```

    <Note>
      Omni supports [Snowflake semantic views](/connect-data/snowflake-semantic-views), but they require additional connection settings to enable. If you use semantic views, refer to the setup guide after completing your connection.
    </Note>
  </Step>

  <Step title="Set up a table upload schema" titleSize="h3">
    <Callout icon="hand-point-up" color="#ff4179">
      **This step is optional.** However, we recommend completing it as part of the initial set up or you won't be able to use uploaded files like CSVs in joins.
    </Callout>

    In this step, you'll create a dedicated schema to use for [table uploads](/analyze-explore/data-input-csvs). This schema can't be used for other modeled tables.

    1. Create the schema in Snowflake. This can be in its own database or the same database as other schemas to be used in modeling.
    2. Run the following commands to grant the Omni user the required privileges:

       ```sql title="Grant Omni user permissions to upload schema" theme={null}
       grant usage on database <upload_database> to role omni_role;
       grant usage, create table on schema <upload_database>.<csv_schema> to role omni_role;
       ```
  </Step>

  <Step title="Allowlist Omni's IP addresses" titleSize="h3">
    If access to the Snowflake database is [limited by IP address](https://docs.snowflake.com/en/user-guide/network-policies), you'll need to add Omni's IPs to the allowlist before you create the database connection.

    Omni's IP addresses can be found on an individual connection's page, accessed by navigating to **Settings > Connections** and clicking a connection.
  </Step>

  <Step title="Retrieve your Snowflake account identifier" titleSize="h3">
    1. In Snowflake, click your user icon in the bottom left corner of the page and then hover over **Account**.
    2. In the account selector, click the **View account details** link under the account:

           <img src="https://mintcdn.com/omni-e7402367/XZwrvFN-b2pRXANo/connect-data/images/snowflake-account-identifier.png?fit=max&auto=format&n=XZwrvFN-b2pRXANo&q=85&s=962e419e5e810c0cb50f76d9315b0aa2" alt="Account identifier" width="800" height="762" data-path="connect-data/images/snowflake-account-identifier.png" />
    3. In the **Account Details** dialog, locate and copy the **Account Identifier**.

    Refer to the [Snowflake documentation](https://docs.snowflake.com/user-guide/admin-account-identifier#finding-the-organization-and-account-name-for-an-account) for information about Snowflake account identifiers.
  </Step>

  <Step title="Create the connection in Omni" titleSize="h3">
    <Note>
      Snowflake connection parameters can be case sensitive and are often capitalized. If you see errors on connection, confirm your connection parameters match your Snowflake environment exactly.
    </Note>

    1. In Omni, click **Settings > Connections**.

    2. Click the **Snowflake** option.

    3. On the connection setup page, fill in the connection details:

           <DisplayName />

           <ParamField path="Host Type" required>
             Controls how you provide warehouse information to Omni. Supported options are an **Account Identifier** or a **Host and Port**.

             <Expandable title="Account Identifier" defaultOpen>
               <ParamField path="Account Identifier">
                 Your Snowflake account identifier. Required if **Host Type** is **Account Identifier**.
               </ParamField>
             </Expandable>

             <Expandable title="Host and Port" defaultOpen>
               <ParamField path="Host Override" required>
                 The full hostname for your Snowflake instance (e.g., `youraccount.snowflakecomputing.com`). Required if **Host Type** is **Host and Port**.
               </ParamField>

               <Port />
             </Expandable>
           </ParamField>

           <ParamField path="Warehouse" required>
             The Snowflake warehouse to use for queries.
           </ParamField>

           <Database />

           <Include term="Schemas" />

           <IncludeOther term="Databases" />

           <Offloaded />

           <TableUploads />

           <DatabaseTimezone />

           <QueryTimezone />

           <AllowUserSpecificTimezones />

           <QueryTimeout defaultValue="900" />

           <AutoGenerateRelationshipsAllModes />

           <AlwaysScopeViewNames />

           <ParamField path="Authentication Type" required>
             The type of authentication to use.

             <AccordionGroup>
               <Accordion title="Programmatic access token (PAT)" icon="ticket">
                 Snowflake [programmatic access tokens](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) (PATs) provide a secure, non-interactive way to authenticate to Snowflake without a traditional password.

                 To use a PAT, select **Password** as the authentication type and enter:

                 * **Username** - The Omni database user you created in step 1.
                 * **Password** - Paste the Snowflake PAT value.

                 No additional configuration is needed — PATs work out of the box in the password field.
               </Accordion>

               <Accordion title="Key-pair authentication" icon="key">
                 To use this authentication type, you'll need to specify a **Username** and set up a key-pair:

                 * **Username** - This is the Omni database user you created in step 1.
                 * **Key-pair configuration** - Click the link to set up keys for the connection. Refer to step 6 for more information.
               </Accordion>

               <Accordion title="Password authentication" icon="passport">
                 Password authentication uses a **username** and **password** to authenticate to Snowflake.

                 <Warning>
                   Snowflake is [phasing out single-factor password authentication](https://docs.snowflake.com/en/user-guide/security-mfa-rollout), with full enforcement expected by October 2026. Use a programmatic access token or key-pair authentication instead to meet their enforcement deadlines.
                 </Warning>
               </Accordion>
             </AccordionGroup>
           </ParamField>

           <BaseAccess />

    4. When finished, click **Create connection**.
  </Step>

  <Step title="Set up Snowflake key-pair authentication" titleSize="h3">
    <Warning>
      If you have multiple Snowflake connections, each connection must use a different key-pair. We recommend using a different Snowflake user for each connection, but these users can use the same Snowflake role to simplify permissions administration.
    </Warning>

    If you selected **Keypair authentication** as the [**Authentication type**](#param-authentication-type), you'll need to configure keys before you can save the connection.

    Omni can generate the keypair for you, or you can provide an existing [private key](https://docs.snowflake.com/en/user-guide/key-pair-auth#generate-the-private-key).

    <AccordionGroup>
      <Accordion title="Omni-generated key-pair" icon="o" description="Let Omni generate the key-pair on your behalf">
        1. In the **Keypairs** tab, click **Generate key-pair**.

        2. Click **Copy** next to the public key.

        3. Navigate back to your Snowflake account and run the following:

           ```sql theme={null}
           alter user omni_user set RSA_PUBLIC_KEY='COPIED_PUBLIC_KEY';
           ```

        4. In the **Keypair** tab in Omni, click the toggle in the **Active** column to enable the keypair.
      </Accordion>

      <Accordion title="Existing private key" icon="key" description="Provide an existing private key">
        <Tip>
          Omni only supports RSA private keys without passphrases.
        </Tip>

        1. In the **Keypairs** tab, click **Add existing key**.

        2. Paste the private key into the dialog. For example:

           ```shell theme={null}
           -----BEGIN PRIVATE KEY-----
           MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXHK07oaqx8fnY
           r3UbfUS6HRXQFRvQ0J8qqzgq+UH4ZqtgxV44ciSOwzL65E2aZrixXxB+s7Kbbw1q
           ...
           ...
           fAPCZRg8vdG8Hp26PwXxybZ/M9u7NaKJ0BT4AwKKtZTUxZVxz/kPhdHT+MpoQqJf
           JuzuwXVAAcl1GME2OiqkZhww
           -----END PRIVATE KEY-----
           ```

           **Note**: Omni will automatically add `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` if the key doesn't have them.

        3. Click **Add keypair**. Omni will automatically generate the public key and redirect you back to the **Keypairs** tab.

        4. Click **Copy** next to the newly-generated public key.

        5. Navigate back to your Snowflake account and run the following:

           ```sql title="Set key for the Omni user" theme={null}
           alter user omni_user set RSA_PUBLIC_KEY='COPIED_PUBLIC_KEY';
           ```

        6. In the **Keypair** tab in Omni, click the toggle in the **Active** column to enable the keypair.
      </Accordion>
    </AccordionGroup>
  </Step>
</Steps>

## What's next?

Now that your database is set up, you can:

* Use the Omni Agent's [quickstart skill](/modeling/topics/quickstart) to create your first topic from business questions
* Configure user permissions, [schema refreshes](/modeling/develop/schema-refreshes), [environments](/connect-data/dynamic-environments) and [timezone settings](/connect-data/timezones)
* Learn how Omni [generates the model](/modeling/develop/model-generation) associated with the connection

- If you use Snowflake semantic views, refer to [Snowflake semantic views](/connect-data/snowflake-semantic-views) for additional setup steps to import and query them in Omni.
- Use the Model Assistant's [Suggest model from query history skill](/ai/model-assistant#suggest-model-from-query-history) to generate semantic models based on actual SQL query patterns run against the database
