Skip to content
1 change: 1 addition & 0 deletions apps/docs/content/docs/en/integrations/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
"smartlead",
"smtp",
"snowflake",
"snowflake-service-account",
"sportmonks",
"sqs",
"square",
Expand Down
120 changes: 120 additions & 0 deletions apps/docs/content/docs/en/integrations/snowflake-service-account.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: Snowflake Programmatic Access Tokens
description: Create a Snowflake programmatic access token and connect it to Sim so workflows can query your account
---

import { Callout } from 'fumadocs-ui/components/callout'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { FAQ } from '@/components/ui/faq'

A Snowflake programmatic access token (PAT) lets a workflow authenticate to your account over the Snowflake SQL API without a password or a key pair. The token belongs to one Snowflake user. Left unrestricted it can act as any role that user holds; with `ROLE_RESTRICTION` set it is pinned to exactly one.

Sim stores the token alongside your account host as one credential. Once it is added, every Snowflake block picks it from a dropdown — and the block's database, schema, table, warehouse, role, file-format, and procedure fields become pickers that list what the token can actually see.

## Prerequisites

- A Snowflake user you can generate a token for. Generating a token for another user requires the ability to run `ALTER USER` on them.
- Your account host — the `<account_identifier>.snowflakecomputing.com` hostname, for example `myorg-myaccount.snowflakecomputing.com`. Snowsight shows it under **Account details**.
- A network policy covering the user, or an authentication policy that waives the requirement (see below).

<Callout type="warn">
Snowflake's **network policy** requirement varies by user type, and getting it wrong is the most common reason a token is rejected:

- `TYPE = PERSON` — you can generate a token without a network policy, but the user **must** be covered by one to authenticate with it.
- `TYPE = SERVICE` and `TYPE = LEGACY_SERVICE` — a network policy is required to generate **and** to use a token.
- `TYPE = SERVICE_AGENT` — exempt; generate and use freely.

If your account has no network policy, either create one (allowing Sim's egress) or set `NETWORK_POLICY_EVALUATION = ENFORCED_NOT_REQUIRED` on an authentication policy applied to the user.
</Callout>

## Creating the Token

### Option 1 — Snowsight

<Steps>
<Step>
Open **Governance & security** → **Users & roles** and select the user the workflow should run as
</Step>
<Step>
Under **Programmatic access tokens**, click **Generate new token**
</Step>
<Step>
Give it a name, optionally restrict it to a single role, and set the expiry in days
</Step>
<Step>
Copy the token secret. Snowflake shows it **once**, at creation
</Step>
</Steps>

### Option 2 — SQL

```sql
ALTER USER my_service_user ADD PROGRAMMATIC ACCESS TOKEN sim_workflows
ROLE_RESTRICTION = 'SIM_WORKFLOW_ROLE'
DAYS_TO_EXPIRY = 90;
```

`DAYS_TO_EXPIRY` defaults to 15 days and cannot exceed 365 — an authentication policy can lower that ceiling further via `PROGRAMMATIC_ACCESS_TOKEN_MAX_EXPIRY_IN_DAYS`. **A token can never be non-expiring**, and the value cannot be changed after creation — to extend it, generate a new token and swap the credential in Sim. Plan the rotation when you create it.

Service users (`TYPE = SERVICE`, `LEGACY_SERVICE`, or `SERVICE_AGENT`) **must** set `ROLE_RESTRICTION`, unless an authentication policy exempts them. For person users it is optional but recommended: a restricted token can only ever act as that one role.

<Callout type="info">
If an authentication policy applies to the user, `'PROGRAMMATIC_ACCESS_TOKEN'` must appear in its `AUTHENTICATION_METHODS` list, otherwise the token is refused.
</Callout>

## Adding the Credential to Sim

<Steps>
<Step>
Add a **Snowflake** block to a workflow, open the credential dropdown, and choose to add a programmatic access token
</Step>
<Step>
Enter the **account host** (`myorg-myaccount.snowflakecomputing.com`) and paste the **token**
</Step>
<Step>
Save. Sim verifies the credential by running `SELECT CURRENT_USER(), CURRENT_ACCOUNT(), CURRENT_ROLE()` over the SQL API — a metadata-only statement that needs no warehouse and consumes no credits. A rejected token, an unreachable host, or a blocking network policy each produce a specific error rather than a generic failure.
</Step>
</Steps>

The host and the token are encrypted before being stored, and the token is never returned to the browser — the block sends a credential id and Sim resolves it server-side.

## Using the Credential in Workflows

Select the credential on any Snowflake block. You never enter the host again: every tool derives its endpoint from the host stored on the credential.

With a credential selected, these fields become pickers backed by metadata-only statements:

| Field | Lists | Needs |
| --- | --- | --- |
| Database | `SHOW DATABASES` | credential |
| Schema | `SHOW SCHEMAS IN DATABASE` | database |
| Table | `SHOW TABLES IN SCHEMA` | database, schema |
| Warehouse | `SHOW WAREHOUSES` | credential |
| Execution role | `CURRENT_AVAILABLE_ROLES()` | credential |
| Named file format | `SHOW FILE FORMATS IN SCHEMA` | database, schema |
| Procedure | `SHOW PROCEDURES IN SCHEMA` | database, schema |

Each picker runs as the token's user under its **default** role — not the execution role set on the block — so an empty list is usually a privilege gap rather than an empty account. Switch any field to advanced mode to type a name directly or reference an upstream block's output instead.

<Callout type="info">
**Unload Data exports a table, not a query.** The COPY INTO grammar places the
source immediately before its options, so an inline query would sit one
parenthesis away from being able to rewrite them. To export a query result,
materialize it first — a view, or `CREATE TABLE AS SELECT` via Execute SQL —
then unload that object.
</Callout>

## Rotating and Revoking

A token's expiry is fixed at creation. To rotate, generate a new token on the same user and update the credential in Sim — the old one stays valid until you remove it. `ALTER USER ... REMOVE PROGRAMMATIC ACCESS TOKEN <name>` revokes immediately and cannot be undone.

<FAQ items={[
{ question: "Why a programmatic access token instead of a password?", answer: "The token is scoped to one user, can be restricted to a single role, expires on a schedule you choose, and can be revoked on its own without changing anyone's password or breaking other integrations." },
{ question: "Does the token expire?", answer: "Yes. DAYS_TO_EXPIRY defaults to 15 days and can be set up to 365 at creation. It cannot be changed afterwards, so pick the value you want up front and plan a rotation." },
{ question: "I lost the token — can I see it again?", answer: "No. Snowflake shows the secret only at creation. Generate a new token and update the credential in Sim." },
{ question: "Why does adding the credential fail with an authentication error?", answer: "The three common causes are a token that has expired or been revoked, a user with no network policy (required to authenticate for every type except SERVICE_AGENT, unless an authentication policy waives it), and an authentication policy that omits PROGRAMMATIC_ACCESS_TOKEN from its AUTHENTICATION_METHODS. A wrong account host is reported separately — Snowflake resolves any *.snowflakecomputing.com name, so Sim identifies a mistyped host by the 404 it answers with." },
{ question: "Why is a picker empty?", answer: "The pickers run SHOW statements as the token's user under its default role — the block's execution role is not applied to them. If the objects you expect are visible only to another role, grant the default role usage on them, restrict the token to the role that has access, or type the name in advanced mode." },
{ question: "Does listing objects cost credits?", answer: "No. Every picker and the credential check run metadata-only statements, which Snowflake serves without a running warehouse." },
{ question: "Can one credential reach two Snowflake accounts?", answer: "No. A token is bound to the user in one account, and the credential stores that account's host. Add one credential per account." },
{ question: "How many tokens can a user have?", answer: "Snowflake allows up to 15 active programmatic access tokens per user." },
]} />
Loading
Loading