# Snowflake Destination Config Reference

<p><a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/" >Snowflake</a> is a warehouse destination. RudderStack stages events as files in object storage, then loads them into a Snowflake database on a schedule.</p>
<p>In a Snowflake destination spec:</p>
<ul>
<li><code>type: snowflake</code></li>
<li><code>definition_version: 1</code></li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="sample-configuration">Sample configuration</h2><div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: destination
metadata:
  name: snowflake-prod
spec:
  id: snowflake-prod
  display_name: Snowflake Production
  type: snowflake
  definition_version: 1
  enabled: true
  config:
    account: xy12345.us-east-2.aws
    database: RUDDER_EVENTS
    warehouse: RUDDER_WAREHOUSE
    user: &#34;{{ .SNOWFLAKE_USER }}&#34;
    role: RUDDER_ROLE
    namespace: rudder_events

    use_key_pair_auth: true
    private_key: &#34;{{ .SNOWFLAKE_PRIVATE_KEY }}&#34;
    private_key_passphrase: &#34;{{ .SNOWFLAKE_PRIVATE_KEY_PASSPHRASE }}&#34;

    use_rudder_storage: false
    cloud_provider: AWS
    bucket_name: acme-snowflake-staging
    prefix: rudder
    storage_integration: RUDDER_S3_INTEGRATION
    s3:
      role_based_auth: true
      iam_role_arn: &#34;arn:aws:iam::123456789012:role/RudderStackS3&#34;
      enable_sse: false
    cleanup_object_storage_files: false

    sync_frequency: &#34;180&#34;
    sync_start_at: &#34;01:00&#34;
    exclude_window:
      start_time: &#34;02:00&#34;
      end_time: &#34;03:00&#34;

    prefer_append: true
    skip_users_table: true
    skip_tracks_table: false
    json_paths: context.traits,properties.metadata
    manual_sync: false

    underscore_divide_numbers: false
    allow_users_context_traits: false

    connection_mode:
      web: cloud
      cloud: cloud
    consent_management:
      web:
        - provider: oneTrust
          consents:
            - analytics</code></pre></div>
</div>
<p>The above example authenticates with an encrypted key pair and stages files in your own S3 bucket through an IAM role, so it carries no password or access keys. Which keys apply depends on several switches — see <a href="#key-dependencies" >Key dependencies</a>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="config-keys">Config keys</h2><p><code>config</code> accepts only the keys listed below. The <a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/destination-types/#config-key-rules" >shared config key rules</a> cover unknown keys, defaults, and immutability.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="key-dependencies">Key dependencies</h3><p><code>use_key_pair_auth</code>, <code>use_rudder_storage</code>, and <code>cloud_provider</code> decide which other keys apply. Rudder CLI enforces every requirement below; a key outside its branch is accepted and ignored.</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Required when</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>password</code></td>
<td><code>use_key_pair_auth</code> is <code>false</code></td>
</tr>
<tr>
<td><code>private_key</code></td>
<td><code>use_key_pair_auth</code> is <code>true</code></td>
</tr>
<tr>
<td><code>bucket_name</code></td>
<td><code>cloud_provider</code> is <code>AWS</code> or <code>GCP</code></td>
</tr>
<tr>
<td><code>storage_integration</code></td>
<td><code>cloud_provider</code> is <code>GCP</code> or <code>AZURE</code></td>
</tr>
<tr>
<td><code>s3.role_based_auth</code></td>
<td><code>cloud_provider</code> is <code>AWS</code></td>
</tr>
<tr>
<td><code>s3.iam_role_arn</code></td>
<td><code>cloud_provider</code> is <code>AWS</code> and <code>s3.role_based_auth</code> is <code>true</code></td>
</tr>
<tr>
<td><code>s3.access_key_id</code>, <code>s3.access_key</code></td>
<td><code>cloud_provider</code> is <code>AWS</code> and <code>s3.role_based_auth</code> is <code>false</code></td>
</tr>
<tr>
<td><code>gcp.credentials</code></td>
<td><code>cloud_provider</code> is <code>GCP</code></td>
</tr>
<tr>
<td><code>azure.container_name</code>, <code>azure.account_name</code></td>
<td><code>cloud_provider</code> is <code>AZURE</code></td>
</tr>
<tr>
<td><code>azure.account_key</code></td>
<td><code>cloud_provider</code> is <code>AZURE</code> and <code>azure.use_sas_tokens</code> is <code>false</code></td>
</tr>
<tr>
<td><code>azure.sas_token</code></td>
<td><code>cloud_provider</code> is <code>AZURE</code> and <code>azure.use_sas_tokens</code> is <code>true</code></td>
</tr>
</tbody>
</table>
<p>Every storage requirement also assumes <code>use_rudder_storage</code> is <code>false</code>.</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text"><p><code>validate</code> fills in defaults before it checks the spec, so an omitted key is checked as though you had written its default. Two keys are worth knowing about:</p>
<ul>
<li>Omitting <code>cloud_provider</code> selects <code>AWS</code>, which makes <code>bucket_name</code> and <code>s3.role_based_auth</code> required.</li>
<li>Omitting <code>azure.use_sas_tokens</code> selects account key authentication, which makes <code>azure.account_key</code> required.</li>
</ul>
</div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="connection">Connection</h3><div class="rs-ckeys">
<div class="rs-ckey" id="account">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">account</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Your Snowflake account identifier — the part of your Snowflake URL before <code>.snowflakecomputing.com</code>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/#snowflake-account-id-examples" >Snowflake account ID examples</a> for the format per cloud and region.
</div>

</div>

<div class="rs-ckey" id="database">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">database</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Name of the Snowflake database RudderStack loads data into.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="warehouse">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">warehouse</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Name of the Snowflake virtual warehouse that runs the loads.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="user">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">user</p>RequiredSecret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Snowflake user RudderStack connects as.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/#create-a-user" >Create a user</a>.
</div>

</div>

<div class="rs-ckey" id="role">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">role</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Role RudderStack assumes. When omitted, the user&rsquo;s default role is used. The role needs permission to load data into <code>database</code>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 100 characters, and must not contain line breaks.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="namespace">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">namespace</p>Immutable</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Schema RudderStack creates its tables in. Defaults to the source name when omitted.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>At most 64 characters, and must not start with <code>pg_</code> in any capitalization.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
<li>Can&rsquo;t be changed once the destination exists — the API rejects the update. Create a new destination instead.</li>
</ul>

</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="authentication">Authentication</h3><div class="rs-ckeys">
<div class="rs-ckey" id="use_key_pair_auth">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">use_key_pair_auth</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Authenticate with a <a href="https://docs.snowflake.com/en/user-guide/key-pair-auth" >key pair</a> instead of a password. Key pair authentication is the recommended method.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>The dashboard defaults this field to <code>false</code>. Rudder CLI requires it explicitly.</li>
<li>A spec that omits this key fails validation.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/#key-pair-authentication" >Key pair authentication</a>.
</div>

</div>

<div class="rs-ckey" id="password">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">password</p>RequiredSecret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Password for <code>user</code>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_key_pair_auth</code> is <code>false</code>. Leave it unset otherwise.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="private_key">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">private_key</p>RequiredSecret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  PEM-encoded private key whose public half is assigned to <code>user</code> in Snowflake.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_key_pair_auth</code> is <code>true</code>. Leave it unset otherwise.</li>
<li>Must include the delimiters: <code>-----BEGIN PRIVATE KEY-----</code> … <code>-----END PRIVATE KEY-----</code>, or the <code>ENCRYPTED PRIVATE KEY</code> equivalents. A bare base64 key body is rejected.</li>
<li>Templates aren&rsquo;t accepted. <code>{{ .VAR }}</code> references are resolved before validation, so the resolved value is what must be PEM-shaped.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <p>Load the key from a file rather than pasting it into YAML:</p>
<div class="rs-code">
  <div class="rs-code__head">bash<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">export RUDDER_SNOWFLAKE_PRIVATE_KEY=&#34;$(cat rsa_key.p8)&#34;</code></pre></div>
</div>

</div>

</div>

<div class="rs-ckey" id="private_key_passphrase">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">private_key_passphrase</p>Secret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Passphrase you set when encrypting <code>private_key</code>. Leave it out for an unencrypted key.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies when <code>use_key_pair_auth</code> is <code>true</code>. Leave it unset otherwise.</li>
<li>At most 100 characters, and must not contain line breaks.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Authentication fails if the key is encrypted and this passphrase is missing — Rudder CLI can&rsquo;t tell whether a key is encrypted, so <code>validate</code> doesn&rsquo;t catch it.</div>
  </div>
</blockquote>

</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="object-storage">Object storage</h3><p><code>use_rudder_storage</code> decides whether RudderStack stages files in its own storage or in yours. With your own, <code>cloud_provider</code> picks the provider, and only that provider&rsquo;s block applies.</p>
<div class="rs-ckeys">
<div class="rs-ckey" id="use_rudder_storage">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">use_rudder_storage</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Stage files in RudderStack-managed object storage instead of your own.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Available only on RudderStack-hosted data planes. Self-hosted data planes must set <code>false</code> and configure a provider.</li>
<li>The dashboard defaults this field to <code>false</code>. Rudder CLI requires it explicitly.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="cloud_provider">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">cloud_provider</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>AWS</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Cloud that hosts your staging storage — normally the one your Snowflake account runs on.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies when <code>use_rudder_storage</code> is <code>false</code>.</li>
<li>One of <code>AWS</code>, <code>GCP</code>, or <code>AZURE</code>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="#key-dependencies" >Key dependencies</a> for what omitting it makes required.
</div>

</div>

<div class="rs-ckey" id="bucket_name">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">bucket_name</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Name of the staging S3 or GCS bucket. The bucket must already exist. Azure uses <code>azure.container_name</code> instead.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_rudder_storage</code> is <code>false</code> and <code>cloud_provider</code> is <code>AWS</code> or <code>GCP</code>. Leave it unset otherwise.</li>
<li>For <code>AWS</code>: lowercase letters, digits, dots, and hyphens; not starting with <code>xn--</code>, no consecutive dots, not an IP address.</li>
<li>For <code>GCP</code>: lowercase letters, digits, dots, hyphens, and underscores; not starting with <code>goog</code>, not containing <code>google</code>, no consecutive dots, not an IP address.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="prefix">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">prefix</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Folder prefix inside the staging bucket or container.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies when <code>use_rudder_storage</code> is <code>false</code>.</li>
<li>At most 100 characters, and must not contain line breaks.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="storage_integration">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">storage_integration</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Name of the Snowflake storage integration RudderStack uses to run <code>COPY</code> from the staging storage.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_rudder_storage</code> is <code>false</code> and <code>cloud_provider</code> is <code>GCP</code> or <code>AZURE</code>. Optional for <code>AWS</code>.</li>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/#configure-cloud-storage-integration-with-snowflake" >Configure cloud storage integration with Snowflake</a>.
</div>

</div>

<div class="rs-ckey" id="cleanup_object_storage_files">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">cleanup_object_storage_files</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Delete staged files after a sync completes successfully.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies when <code>use_rudder_storage</code> is <code>false</code>.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="s3">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">s3</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Amazon S3 settings.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_rudder_storage</code> is <code>false</code> and <code>cloud_provider</code> is <code>AWS</code>. Leave it unset otherwise.</li>
<li><code>role_based_auth</code> — boolean. <code>true</code> to use <code>iam_role_arn</code>, <code>false</code> to use the access key pair. Required — the dashboard&rsquo;s default doesn&rsquo;t apply.</li>
<li><code>iam_role_arn</code> — ARN of the IAM role RudderStack assumes. Required when <code>role_based_auth</code> is <code>true</code>. At most 100 characters.</li>
<li><code>access_key_id</code>, <code>access_key</code> — AWS access key pair. Required when <code>role_based_auth</code> is <code>false</code>. At most 100 characters each. <strong>Secret</strong>.</li>
<li><code>enable_sse</code> — boolean, default <code>false</code>. Enable server-side encryption on the bucket.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">cloud_provider: AWS
bucket_name: acme-snowflake-staging
s3:
  role_based_auth: true
  iam_role_arn: &#34;arn:aws:iam::123456789012:role/RudderStackS3&#34;</code></pre></div>
</div>

</div>

</div>

<div class="rs-ckey" id="gcp">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">gcp</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Google Cloud Storage settings.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_rudder_storage</code> is <code>false</code> and <code>cloud_provider</code> is <code>GCP</code>. Leave it unset otherwise.</li>
<li><code>credentials</code> — contents of the JSON key file for a service account with <code>storage.objectCreator</code> access to the bucket. Required. <strong>Secret</strong>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">cloud_provider: GCP
bucket_name: acme-snowflake-staging
storage_integration: RUDDER_GCS_INTEGRATION
gcp:
  credentials: &#34;{{ .SNOWFLAKE_GCS_CREDENTIALS }}&#34;</code></pre></div>
</div>

</div>

</div>

<div class="rs-ckey" id="azure">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">azure</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Azure Blob Storage settings.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when <code>use_rudder_storage</code> is <code>false</code> and <code>cloud_provider</code> is <code>AZURE</code>. Leave it unset otherwise.</li>
<li><code>container_name</code> — staging container, which must already exist. Required. 3 to 63 characters of lowercase letters, digits, and single hyphens.</li>
<li><code>account_name</code> — storage account name. Required. At most 100 characters.</li>
<li><code>use_sas_tokens</code> — boolean, default <code>false</code>. <code>true</code> to authenticate with <code>sas_token</code>; omitted or <code>false</code> to use <code>account_key</code>.</li>
<li><code>account_key</code> — storage account key. Required when <code>use_sas_tokens</code> is <code>false</code>. At most 100 characters. <strong>Secret</strong>.</li>
<li><code>sas_token</code> — shared access signature token. Required when <code>use_sas_tokens</code> is <code>true</code>. <strong>Secret</strong>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">cloud_provider: AZURE
storage_integration: RUDDER_AZURE_INTEGRATION
azure:
  container_name: rudder-staging
  account_name: acmestorage
  use_sas_tokens: false
  account_key: &#34;{{ .SNOWFLAKE_AZURE_ACCOUNT_KEY }}&#34;</code></pre></div>
</div>

</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="sync-scheduling">Sync scheduling</h3><div class="rs-ckeys">
<div class="rs-ckey" id="sync_frequency">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">sync_frequency</p>Required</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  How often RudderStack syncs staged events into Snowflake, in minutes. Written as a string, not a number.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>One of <code>5</code>, <code>10</code>, <code>15</code>, <code>30</code>, <code>60</code>, <code>180</code>, <code>360</code>, <code>720</code>, or <code>1440</code>.</li>
<li>The dashboard defaults this field to <code>180</code>. Rudder CLI requires it explicitly.</li>
<li>A spec that omits this key fails validation.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="sync_start_at">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">sync_start_at</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Time of day, in UTC, that anchors the sync schedule. Subsequent syncs are computed from it at <code>sync_frequency</code> intervals. Written as <code>HH:MM</code>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Not validated locally: any string is accepted, and a value the scheduler can&rsquo;t parse silently yields no scheduled times.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="exclude_window">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">exclude_window</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Daily window, in UTC, during which RudderStack doesn&rsquo;t sync. Omit the block entirely to sync around the clock.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>When present, both fields are required: <code>start_time</code> and <code>end_time</code>, each <code>HH:MM</code>.</li>
<li>Neither field&rsquo;s format is validated locally.</li>
</ul>

</div>

</div>

<div class="rs-ckey" id="manual_sync">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">manual_sync</p>Internal</div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Enable manual sync mode.
</p>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="table-behavior">Table behavior</h3><div class="rs-ckeys">
<div class="rs-ckey" id="prefer_append">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">prefer_append</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>true</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Append incoming events to existing tables. Set it to <code>false</code> to merge instead, which guarantees no duplicates at the cost of noticeably longer syncs. This is what the dashboard calls <strong>Warehouse Append</strong>.
</p>

</div>

<div class="rs-ckey" id="skip_users_table">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">skip_users_table</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>true</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Send <code>identify</code> events only to the <code>identifies</code> table, skipping the <code>users</code> table. The <code>users</code> table holds one row per unique user and is maintained with a merge, which can add significant time to each sync.
</p>

</div>

<div class="rs-ckey" id="skip_tracks_table">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">skip_tracks_table</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Skip sending events to the <code>tracks</code> table. Per-event tables are unaffected.
</p>

</div>

<div class="rs-ckey" id="json_paths">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">json_paths</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Comma-separated dot-notation paths whose values are stored as JSON columns instead of being flattened. Applies to every <code>track</code> event sent to this destination.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Not validated locally.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/json-column-support/" >JSON Column Support</a>.
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="legacy-column-naming">Legacy column naming</h3><p>Both keys below preserve the column naming of destinations created before the behavior changed. Leave them at their defaults on a new destination. Neither can be changed once the destination exists — the API rejects the update.</p>
<div class="rs-ckeys">
<div class="rs-ckey" id="underscore_divide_numbers">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">underscore_divide_numbers</p>ImmutableInternal</div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  When <code>false</code>, numeric suffixes in column names are preserved: <code>v3</code> stays <code>v3</code> rather than being split into <code>v_3</code>.
</p>

</div>

<div class="rs-ckey" id="allow_users_context_traits">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">allow_users_context_traits</p>ImmutableInternal</div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  When <code>false</code>, <code>context.traits.*</code> fields aren&rsquo;t promoted to top-level traits and are stored only as <code>context_traits_*</code> columns.
</p>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="per-source-keys">Per-source keys</h3><p>Both keys are objects keyed by the local source type — the tokens listed under <a href="#source-types" >Source types</a>. A key naming a source type this destination doesn&rsquo;t support fails validation.</p>
<div class="rs-ckeys">
<div class="rs-ckey" id="connection_mode">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">connection_mode</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Maps each source type you connect to the mode its events reach Snowflake in, using the modes in <a href="#source-types" >Source types</a>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>An entry is required for each source type you connect — see <a href="#connect-a-source" >Connect a source</a>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">connection_mode:
  web: cloud
  cloud: cloud</code></pre></div>
</div>

</div>

</div>

<div class="rs-ckey" id="consent_management">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">consent_management</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Consent provider configuration per source type. The entry shape, accepted providers, and the rules on <code>resolution_strategy</code> and <code>consents</code> are shared across all destination types — see <a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/destination-types/#consent-management" >Consent management</a>.
</p>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="source-types">Source types</h2><p>Snowflake accepts events from these source types in the mentioned connection modes:</p>
<table>
<thead>
<tr>
<th>Source type</th>
<th>Connection mode</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>android</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>android_kotlin</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>ios</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>ios_swift</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>web</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>unity</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>react_native</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>flutter</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>cordova</code></td>
<td><code>cloud</code></td>
</tr>
<tr>
<td><code>cloud</code></td>
<td><code>cloud</code></td>
</tr>
</tbody>
</table>
<p>Every source type is <code>cloud</code> only — events reach the warehouse from RudderStack&rsquo;s servers, never in device mode.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The dashboard additionally offers Snowflake to AMP, Shopify, and cloud app sources. Rudder CLI doesn&rsquo;t manage those connections, so <code>amp</code>, <code>shopify</code>, and <code>cloud_source</code> are invalid here.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="connect-a-source">Connect a source</h2><p>An event stream connection to this destination is checked against two rules at <code>validate</code> time.</p>
<p><strong>The source&rsquo;s type must be supported.</strong> A source&rsquo;s type resolves to one of the tokens above before the check — a JavaScript source resolves to <code>web</code>, and webhook and server-side SDK sources resolve to <code>cloud</code>. An unsupported type reports:</p>
<div class="rs-code">
  <div class="rs-code__head"><button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-text" data-lang="text">destination &#39;snowflake-prod&#39; (type &#39;snowflake&#39;) does not support source &#39;my-source&#39;:
source type &#39;amp&#39; is not among supported source types: android, android_kotlin, ...</code></pre></div>
</div>
<p><strong>The destination config must carry a <code>connection_mode</code> entry for that source type.</strong> This lives on the destination spec, not on the <a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/yaml-connections/" >connection spec</a>. Without it:</p>
<div class="rs-code">
  <div class="rs-code__head"><button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-text" data-lang="text">destination &#39;snowflake-prod&#39; config has no &#39;connection_mode&#39; entry for source type &#39;web&#39;</code></pre></div>
</div>
<p>Snowflake needs no additional config keys to connect a source of any type.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="secrets">Secrets</h2><p>Rudder CLI treats nine keys as secrets: <code>user</code>, <code>password</code>, <code>private_key</code>, <code>private_key_passphrase</code>, <code>s3.access_key_id</code>, <code>s3.access_key</code>, <code>gcp.credentials</code>, <code>azure.account_key</code>, and <code>azure.sas_token</code>. Write each one you use as a <code>{{ .VAR }}</code> reference and supply the value at apply time:</p>
<div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">config:
  user: &#34;{{ .SNOWFLAKE_USER }}&#34;
  private_key: &#34;{{ .SNOWFLAKE_PRIVATE_KEY }}&#34;
  private_key_passphrase: &#34;{{ .SNOWFLAKE_PRIVATE_KEY_PASSPHRASE }}&#34;</code></pre></div>
</div>
<div class="rs-code">
  <div class="rs-code__head">bash<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">export RUDDER_SNOWFLAKE_USER=&#34;RUDDER_USER&#34;
export RUDDER_SNOWFLAKE_PRIVATE_KEY=&#34;$(cat rsa_key.p8)&#34;
export RUDDER_SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=&#34;...&#34;
rudder-cli apply

# or
rudder-cli apply --var-file secrets.vars.yaml</code></pre></div>
</div>
<p>Note that:</p>
<ul>
<li>The YAML that <code>rudder-cli import</code> writes may or may not include secret keys. Before you apply, make sure every secret key your configuration needs is present and populated through variable substitution.</li>
<li><code>s3.iam_role_arn</code> and <code>storage_integration</code> aren&rsquo;t secrets — neither grants access on its own.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/variable-substitution/" >How to Use Variable Substitution in Rudder CLI</a>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="see-more">See more</h2><ul>
<li><a href="https://www.rudderstack.com/docs/destinations/warehouse-destinations/snowflake/" >Snowflake Destination</a> for user and role setup, key pair authentication, and storage integrations</li>
<li><a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/destination-types/" >Destination Type Reference for Rudder CLI</a> for the rules shared across destination types</li>
<li><a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/yaml-destinations/" >Destination YAML Reference</a> for the spec envelope</li>
</ul>

