Snowflake connector
For Studio users who administer a Snowflake account and can create a service user, a network policy and either a programmatic access token or an RSA key pair for it.
Before you start: note the account identifier as Snowsight shows it (orgname-account_name or a legacy locator; the host is always <identifier>.snowflakecomputing.com) and grant the service user's role exactly what agents should read. There is no discovery step: "You write the guide; agents get the SQL API and your role's grants, nothing more."
Steps
-
Open Data Connectors, click Create Connector, choose Snowflake and fill Connector Name, Description and Connector Guide.
-
In Connection Configuration: Account identifier (letters, digits,
_,.and-; 1 to 63 characters; the helper shows the host); Warehouse (case-sensitive; placeholderCOMPUTE_WH); Database (required; placeholderANALYTICS); Schema (Optional) (placeholderPUBLIC); Role (Optional) ("Leave blank for the token user's default role"); Query timeout (seconds), 1 to 60, default 60. -
Read the setup facts under the fields ("Loading setup facts..." while they arrive), each with Copy: Deployment egress IP (add to the token user's network policy); Token type, the header sent on every SQL API call (
X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN, orKEYPAIR_JWTfor key pair); SQL API URL and Test statements once identifier, warehouse and database are filled; and Network policy SQL (allows the egress IP above for the token user), shown only when the deployment reports its egress IP. On a deployment whose outbound traffic goes through your Transit Gateway, the egress IP is the first of your firewall's public egress IP addresses. Run the steps that apply in Snowflake as ACCOUNTADMIN, or a role that can create network rules and policies, owns the ones you change and can set a network policy on the token user, replacing<token_user>and the other placeholders. Step 1 shows the policy that applies to the user. If one applies, step 2 adds the address to it and keeps everything it already allows. Step 3 creates a policy only for a user that has none. The form fills in the real address:-- Run as ACCOUNTADMIN, or a role that can create network rules and policies, owns the-- ones you change and can set a network policy on the token user.-- Replace <token_user> with the Snowflake user that owns the token or key pair.-- 1. See which network policy applies to the user: the one the first line names, if-- any, otherwise the one the second line names. The value column names the policy.-- No value on either line means none applies. A policy the second line names is the-- account's, whichever line you read it from.SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN USER <token_user>;SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT;-- 2. If a policy applies, allow <deployment-egress-ip> for the token user and keep everything it allows.-- Do not set a policy on the user that leaves out what its current policy allows: a-- user has one network policy, so setting one replaces the policy that applies to it.-- If step 1's second line names the policy, it is the account's and applies to every-- user without a policy of its own: an address added to it is allowed for all of them.DESCRIBE NETWORK POLICY <policy_name>;-- Snowflake applies the blocked lists first: a blocked entry that covers the address-- keeps it refused whatever you add to an allowed list. A rule blocking 0.0.0.0/0 on a-- policy whose allowed rules are all private endpoint rules is handled below. For any-- other blocked entry that covers it, DESCRIBE NETWORK RULE shows the rule's values;-- whether to narrow it is your decision, and other policies may use the same rule.-- If ALLOWED_NETWORK_RULE_LIST names a rule whose type is IPV4, add the address to-- that rule (DESCRIBE NETWORK RULE shows its type; name it as database.schema.rule).-- SET replaces the whole list, so repeat every value_list entry it shows, each in quotes.DESCRIBE NETWORK RULE <rule_name>;ALTER NETWORK RULE <rule_name> SET VALUE_LIST = (<existing values>, '<deployment-egress-ip>/32');-- If it names rules but none of type IPV4 (for example only private endpoint rules),-- those rules do not limit public addresses, so the policy refuses this one through a-- blocked rule. Look at each rule BLOCKED_NETWORK_RULE_LIST names:DESCRIBE NETWORK RULE <blocked_rule_name>;-- A rule holding 0.0.0.0/0 blocks every public address. Put a new IPV4 rule that-- allows only this address in its place: an IPV4 rule in the allowed list refuses every-- other public address, and private endpoint rules still decide private traffic. Leave-- the rule holding 0.0.0.0/0 as it is: other policies may use it. In the lists below,-- name every rule ALLOWED_NETWORK_RULE_LIST shows plus the new one, and every blocked-- rule except the one holding 0.0.0.0/0, each in quotes.-- If step 1's second line names the policy, leave it as it is: changing the account's-- policy would let this address in for every user under it. Give the token user a-- policy of its own instead. A user's policy overrides the account's, so the token-- user keeps what the account's policy allowed it, plus this address, and no other-- user changes. Later changes to the account's policy do not reach this user. If no-- other blocked rule remains, end the CREATE NETWORK POLICY statement after the-- allowed list.CREATE NETWORK RULE <database>.<schema>.<new_egress_rule_name>TYPE = IPV4 MODE = INGRESS VALUE_LIST = ('<deployment-egress-ip>/32');CREATE NETWORK POLICY <new_user_policy_name>ALLOWED_NETWORK_RULE_LIST = (<existing rules>, '<database>.<schema>.<new_egress_rule_name>')BLOCKED_NETWORK_RULE_LIST = (<other blocked rules>);ALTER USER <token_user> SET NETWORK_POLICY = <new_user_policy_name>;-- Otherwise the policy is set on the user: swap the rules in one statement, so there is-- no moment when every public address is let in. The policy then admits what it did-- before plus this address, for every user it is set on. If no other blocked rule-- remains, set BLOCKED_NETWORK_RULE_LIST = ().CREATE NETWORK RULE <database>.<schema>.<new_egress_rule_name>TYPE = IPV4 MODE = INGRESS VALUE_LIST = ('<deployment-egress-ip>/32');ALTER NETWORK POLICY <policy_name> SETALLOWED_NETWORK_RULE_LIST = (<existing rules>, '<database>.<schema>.<new_egress_rule_name>')BLOCKED_NETWORK_RULE_LIST = (<other blocked rules>);-- If it names no rule, the policy lists its addresses in ALLOWED_IP_LIST. Add it there-- the same way: SET replaces that list too.ALTER NETWORK POLICY <policy_name> SET ALLOWED_IP_LIST = (<existing addresses>, '<deployment-egress-ip>/32');-- That is enough for a key pair. A programmatic access token also needs the policy to-- name a network rule, and Snowflake reads ALLOWED_IP_LIST and BLOCKED_IP_LIST only-- while the policy names none. So move both lists into IPV4 rules, each address in-- quotes: one with every address ALLOWED_IP_LIST shows and this one, one with every-- address BLOCKED_IP_LIST shows. Then set both rule lists in one statement, so the-- blocked addresses are never let in. If BLOCKED_IP_LIST is empty, skip the second-- CREATE and set BLOCKED_NETWORK_RULE_LIST = ().CREATE NETWORK RULE <database>.<schema>.<new_allowed_rule_name>TYPE = IPV4 MODE = INGRESS VALUE_LIST = (<existing addresses>, '<deployment-egress-ip>/32');CREATE NETWORK RULE <database>.<schema>.<new_blocked_rule_name>TYPE = IPV4 MODE = INGRESS VALUE_LIST = (<blocked addresses>);ALTER NETWORK POLICY <policy_name> SETALLOWED_NETWORK_RULE_LIST = ('<database>.<schema>.<new_allowed_rule_name>')BLOCKED_NETWORK_RULE_LIST = ('<database>.<schema>.<new_blocked_rule_name>');-- 3. If no policy applies, create one that allows <deployment-egress-ip> and set it on the user.-- Run it with a database and schema selected: a network rule belongs to a schema.-- If the alphaagent_studio policy already exists (set up for another Studio), skip-- both CREATE lines: add the address to that policy's rule as in step 2, then run-- the ALTER USER line. If only alphaagent_studio_egress exists, add the address to it-- as in step 2 and skip its CREATE line.CREATE NETWORK RULE alphaagent_studio_egressTYPE = IPV4 MODE = INGRESS VALUE_LIST = ('<deployment-egress-ip>/32');CREATE NETWORK POLICY alphaagent_studioALLOWED_NETWORK_RULE_LIST = ('alphaagent_studio_egress');ALTER USER <token_user> SET NETWORK_POLICY = alphaagent_studio; -
In Snowflake, mint a programmatic access token for the service user, or generate an RSA key pair and register the public key on the user (private key in Privacy-Enhanced Mail (PEM) format; an encrypted key needs its passphrase).
-
Under Authentication, enter the Username (the service user's login name; agents connect as this user) with either the Programmatic access token (recommended) or, for Key pair (RSA private key), the whole Private key (PEM) from
-----BEGIN PRIVATE KEY-----and Private key passphrase (Optional) ("Only if the key is encrypted"). The note: "Stored in AWS Secrets Manager and never shown again. Agents connect from their sandbox as this user".
-
Click Test Connection, enabled once the identifier is valid, warehouse and database are filled, the timeout is in range and the username plus token or private key are entered. For a key pair Studio signs a short-lived JSON Web Token (JWT) with your key. It runs three statements that need no warehouse, so the test never resumes yours:
SELECT CURRENT_VERSION(), CURRENT_USER(), CURRENT_ROLE()SHOW WAREHOUSES LIKE '<warehouse>'SHOW DATABASES LIKE '<database>'A pass reads "Connected to
<host>as<user>(<role>). Warehouse<warehouse>:<state>. Database<database>: found."
- Click Create Connector (v1), enabled only after a passing test.
- Open the agent, choose Configure, and add the connector (Agents: configure and activate).
What you should see
The list shows Snowflake "(v1)", Active. Configuration shows account, host, warehouse, database, schema, role, authentication method and query timeout. Credentials shows only the Username with "Stored in AWS Secrets Manager as a programmatic access token" (or "as a key pair"). "The secret is never shown here; use Update to rotate it."; tokens, keys and passphrases never appear on any screen.
Rotate the token or key
Mint the new token or register the new public key in Snowflake, open the connector, click Update and under Credentials enter the Username with the new token or Private key (PEM) and passphrase ("Re-enter a token or key pair to rotate the stored credential; leave blank to keep it."). Optionally Test Connection, then Update Connector (v2) ("Saving creates v2", one higher than the version you opened). Blank keeps the stored credential; username and secret go together, both or neither; switching method needs the new method's complete credentials; credentials are stored per connector, not per version, so every version uses the new one.
In chat
The agent's code connects with the Snowflake Python connector as the service user, using the token or the private key Studio delivers to that run at invocation (never written into the environment's configuration), and reads results into a data frame or saves them as Parquet in the workspace. Every statement carries a query tag naming the connector, visible in Snowflake's query history. The role's grants decide what it can read; the guide decides what it looks for.
Notes
- Limits: identifier 1 to 63 characters; query timeout 1 to 60 seconds; 1,000 rows per statement from Studio's own calls; key-pair JWTs for Studio's own calls last 59 minutes (Snowflake caps them at one hour) and are re-minted within 5 minutes of expiry.
- "Failed to load Snowflake setup": reload; your fields are kept. Egress IP "Not available on this deployment yet - ask your administrator for the deployment's NAT gateway address.": the network policy SQL stays hidden until the deployment records its address (your administrator reads it from the installation's network outputs).
- "Connected to ..., but warehouse
<name>was not found (or the role cannot see it)." (or the database): sign-in worked; fix the case-sensitive name or the grant. A failure before "Connected" is Snowflake's message: check the network policy is on the user, the token is unexpired or the public key matches, and the identifier is exactly as Snowsight shows it. - Test Connection disabled: a field is missing or out of range, or username and secret are not both entered (a passphrase alone is not a credential). Update Connector disabled after pasting a key: enter the username too, or clear both. "No username stored. Add one via Update": enter the Username alone and save; the stored token is kept.