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

# Snowflake

> Give Thread read-only access to your warehouse so agents can ground their work in real usage data, with a least-privilege setup script you run yourself.

Your warehouse knows things your CRM doesn't: who actually logs in, which features get used, whether the seats you sold are active. Connecting Snowflake lets Thread's agents read that — and nothing else. Access is read-only by construction, authenticated with a key pair (no passwords), and limited to the databases and schemas you choose to grant.

## What it powers

* **Warehouse reads for agents** — a read-only query tool (single `SELECT` statements against the granted schemas), plus discovery tools that list databases, schemas, and tables and describe a table's columns with a few sample rows.
* **Account-scoped metric tools** — once you set up the curated views and account mapping below, agents get per-account metrics (traits, usage trends, seat utilization) where the agent supplies **no SQL, no object names, and no account key**. Thread resolves the account's warehouse key server-side and queries the curated views directly.
* **Milestone verification** — Motion milestone checks can consult any connected connector's read-only tools, so a fresh warehouse read can serve as the evidence that closes a milestone. See [Milestones and verification](/motions/milestones-and-verification).

<Note>
  Snowflake is not yet available as a guide tool row — guides currently verify outcomes through
  HubSpot, Slack, Jira, DocuSign, and Gong reads. See
  [Outcomes and verification](/guides/outcomes-and-verification).
</Note>

## Connect Snowflake

Setup is a two-step wizard on **Connectors → Snowflake**. Thread generates a least-privilege SQL script; you run it once in Snowsight. Thread never asks for a password, and your private key's public half is the only credential the script installs.

<Steps>
  <Step title="Configure the connection">
    In the wizard, enter:

    * **Account identifier** — your Snowflake account (from Snowsight's account details).
    * **Warehouse** — let Thread create a dedicated `THREAD_WH_...` X-Small warehouse (recommended), or reuse one of yours.
    * **Spend cap (optional)** — a monthly credit ceiling for the Thread-created warehouse. At 100% the warehouse suspends. Caps are only available on warehouses Thread creates, since Thread never suspends a warehouse it can't prove it created.
    * **Databases and schemas to grant** — exactly what Thread should be able to read. Nothing outside these grants is visible.
  </Step>

  <Step title="Run the setup script">
    Thread generates a key pair and a setup script. Copy the script into a Snowsight worksheet and run it as `ACCOUNTADMIN`.

    The script is a single atomic block — it either applies completely or not at all — and it creates a per-tenant service role, service user (key-pair auth, no password), warehouse, and resource monitor, all suffixed with a random six-character tag. The grants are read-only: `USAGE` on the warehouse and granted databases/schemas, `SELECT` on their tables. No `CREATE`, no account-level privileges.

    <Note>
      The generated script is held in memory only. If you reload before running it, use **Start
      over** — Thread regenerates the key and script safely (the script always converges the key).
    </Note>
  </Step>

  <Step title="Test the connection">
    The wizard runs a live test and flips to Connected when the service user can authenticate and read. From the connected page you can re-test, rotate the key pair, adjust grants, or disconnect — disconnecting shows a teardown script that drops everything the setup created.
  </Step>
</Steps>

## Curated THREAD\_CS views

Free-form warehouse queries are useful, but per-account metrics deserve a stable contract. The connector page offers a copy-and-edit template that creates a `THREAD_CS` schema with three required views:

| View            | Contract                                                                                         |
| --------------- | ------------------------------------------------------------------------------------------------ |
| `ACCOUNTS_V`    | One row per customer account — your account key mapped to a name, plus any trait columns you add |
| `USAGE_DAILY_V` | Daily metric rows: account key, date, metric name, metric value                                  |
| `SEATS_V`       | Per-account seats licensed and seats active in the last 30 days                                  |

Optional companions (`FEATURE_ADOPTION_V`, `SUPPORT_TICKETS_V`) follow the same pattern.

<Warning>
  The templates are **edit-then-run**, not paste-and-run: you rewire each `SELECT` to your own
  tables. The column names and the `account_external_id` join column are the contract Thread binds
  to — keep those as-is. After creating the views, grant `SELECT` on the schema to your Thread
  role.
</Warning>

## Account-key mapping

Your warehouse keys accounts by your identifiers; Thread needs to translate a Thread account to that key. The mapping is a one-time, org-level decision you confirm — never something an agent guesses.

<Steps>
  <Step title="Propose">
    In the mapping dialog, enter your accounts view (e.g. `ANALYTICS.THREAD_CS.ACCOUNTS_V`). Thread
    probes it: for each candidate column it counts strict-equality matches against a sample of your
    CRM account IDs — no name-based guessing — and recommends the best column.
  </Step>

  <Step title="Confirm">
    Review the per-column overlap (e.g. "matched 47/50 sampled CRM IDs"), pick the strategy, and
    save:

    * **CRM account ID** — your warehouse keys on the Salesforce/HubSpot account ID Thread already holds.
    * **CRM field** — a custom field on the synced CRM record holds the warehouse key.
    * **Explicit** — a per-account link you set manually; the escape hatch for non-CRM accounts.
  </Step>
</Steps>

Once confirmed, the account-scoped metric tools light up. An account the mapping can't resolve gets a precise, typed message ("this account has no CRM account ID") rather than a wrong-account query.

## Security posture

* **Key-pair auth only** — Thread authenticates with short-lived JWTs signed by a private key that never leaves Thread and is stored encrypted.
* **Read-only, scoped grants** — the service role can read exactly the databases and schemas you granted, nothing else.
* **Cost guardrails** — dedicated X-Small warehouse with auto-suspend, plus the optional spend cap that suspends at 100% of quota.
* **Injection-safe by design** — the metric tools accept no SQL or identifiers from the agent; every identifier is validated and the account key is always bound as a parameter, never interpolated.
* **Clean teardown** — disconnect produces a script that drops the role, user, warehouse, and monitor.

## Related

<CardGroup cols={2}>
  <Card title="Connectors overview" icon="plug" href="/integrations/overview">
    How connectors scope what agents can see and do.
  </Card>

  <Card title="Milestones and verification" icon="badge-check" href="/motions/milestones-and-verification">
    How reads from connected sources close milestones.
  </Card>
</CardGroup>
