Skip to content

Commit 5780b7d

Browse files
committed
feat(credentials): keyless Snowflake connections through workload identity federation
A Snowflake connection can now trust Sim's OIDC issuer instead of holding a programmatic access token. Sim signs a short-lived token (audience snowflakecomputing.com) for the credential's own random subject; the customer creates a SERVICE user with WORKLOAD_IDENTITY = (TYPE = OIDC ISSUER SUBJECT). - Save verifies by minting a token and running the identity statement at the pinned account host through the guarded egress path; Snowflake's refusals keep the shared codes (invalid_credentials, site_not_found, provider_unavailable). Subjects bind to their creator like AWS/Databricks. - Runtime: the resolver returns authStyle 'snowflake-workload-identity' for a keyless credential, and the tools and selectors send Bearer WIF.OIDC.<token> with the WORKLOAD_IDENTITY_FEDERATION token type. authStyle and domain are authoritative on every Snowflake tool, so a caller can no longer choose the token type or steer the account host of a saved credential. - PAT credentials resolve and verify exactly as before. - Connect dialog offers the keyless service user with the CREATE USER statement; it falls back to the token dialog where keyless is unavailable. - Docs: Snowflake connections page with keyless setup, troubleshooting, and the 60-minute Snowflake key cache on signing-key rotation.
1 parent 1a605bc commit 5780b7d

28 files changed

Lines changed: 1307 additions & 132 deletions

‎apps/docs/content/docs/integrations/aws-credentials.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ Generate a key with `openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:204
6565
To rotate the signing key without failed runs:
6666

6767
1. Set the new key as `WORKLOAD_IDENTITY_PREVIOUS_KEY` and redeploy (including any background workers that run workflows). Sim publishes it but keeps signing with the current key.
68-
2. Wait at least 5 minutes, so every cached copy of the published keys includes the new one.
68+
2. Wait at least 5 minutes, so every cached copy of the published keys includes the new one. If any keyless [Snowflake connection](/integrations/snowflake-service-account#keyless-service-user) exists, wait 60 minutes instead: Snowflake caches an issuer's keys for up to an hour.
6969
3. Swap them: set the new key as `WORKLOAD_IDENTITY_SIGNING_KEY` and the old key as `WORKLOAD_IDENTITY_PREVIOUS_KEY`, and redeploy everything that runs workflows.
70-
4. Once every instance signs with the new key, wait 5 more minutes, then remove `WORKLOAD_IDENTITY_PREVIOUS_KEY`.
70+
4. Once every instance signs with the new key, wait 5 more minutes (60 with keyless Snowflake connections), then remove `WORKLOAD_IDENTITY_PREVIOUS_KEY`.
7171

7272
Without a signing key, the keyless option is unavailable and access keys work as usual.
7373

‎apps/docs/content/docs/integrations/snowflake-service-account.mdx‎

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,60 @@
11
---
2-
title: Snowflake programmatic access tokens
3-
description: Create a Snowflake programmatic access token and connect it to Sim so workflows can query your account
2+
title: Snowflake connections
3+
description: Connect Snowflake to Sim with a keyless service user that trusts Sim through OpenID Connect, or with a programmatic access token
44
---
55

66
import { Callout } from '@/components/ui/callout'
77
import { Step, Steps } from '@/components/ui/steps'
88

9-
Connect Snowflake with a programmatic access token (PAT) and account host. The token belongs to one user; use `ROLE_RESTRICTION` to limit it to a role with the access your workflows need.
9+
A Snowflake connection holds your account host and how Sim signs in to it:
1010

11-
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.
11+
| Option | What Sim stores | When to use it |
12+
| --- | --- | --- |
13+
| **Service user (keyless, via Sim OIDC)** | Nothing secret: the account host only | Recommended where available. No token to rotate, expire, or leak. |
14+
| **Programmatic access token** | A programmatic access token (PAT) | Any account, and deployments without keyless support. The token belongs to one user; use `ROLE_RESTRICTION` to limit it to a role with the access your workflows need. |
15+
16+
Sim stores the connection 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.
17+
18+
## Set up a keyless service user [#keyless-service-user]
19+
20+
Snowflake's [workload identity federation](https://docs.snowflake.com/en/user-guide/workload-identity-federation) lets a service user trust an OpenID Connect issuer instead of holding a password or token. Sim signs a short-lived token for your connection on every run, and Snowflake accepts it only for the service user created with Sim's issuer and this connection's subject.
21+
22+
<Steps>
23+
<Step>
24+
In Sim, add a **Snowflake** connection, choose **Service user (keyless, via Sim OIDC)**, and enter the account host (`myorg-myaccount.snowflakecomputing.com`). The dialog shows the issuer, audience, and subject for this connection, and the statement to run.
25+
</Step>
26+
<Step>
27+
A user whose role can create users (and has `OWNERSHIP` or `MODIFY PROGRAMMATIC AUTHENTICATION METHODS` on the user) runs the statement from the dialog. It looks like this:
28+
29+
```sql
30+
CREATE USER SIM_WORKFLOWS
31+
WORKLOAD_IDENTITY = (
32+
TYPE = OIDC
33+
ISSUER = '<issuer from the dialog>'
34+
SUBJECT = '<subject from the dialog>'
35+
)
36+
TYPE = SERVICE;
37+
```
38+
39+
The audience is `snowflakecomputing.com`, Snowflake's default, so the statement needs no `OIDC_AUDIENCE_LIST`.
40+
</Step>
41+
<Step>
42+
Grant the user a role with the access your workflows need and make it the default, for example `GRANT ROLE SIM_WORKFLOW_ROLE TO USER SIM_WORKFLOWS;` and `ALTER USER SIM_WORKFLOWS SET DEFAULT_ROLE = SIM_WORKFLOW_ROLE;`. If a network policy or authentication policy applies to the user, it must allow Sim's egress and workload identity.
43+
</Step>
44+
<Step>
45+
Save. Sim signs a token, sends it to your account's SQL API, and runs the same identity statement as for a token. Nothing is saved unless Snowflake accepts it.
46+
</Step>
47+
</Steps>
48+
49+
Snowflake requires each issuer and subject pair to be unique in an account, and matches the subject exactly, so the service user trusts this connection and no other Sim credential. Reconnecting a keyless connection keeps its subject by default, so the service user keeps working; if you choose **Issue a new subject**, update the user with the new one before saving.
50+
51+
### Self-hosted deployments
52+
53+
Keyless connections need `WORKLOAD_IDENTITY_SIGNING_KEY` set and an `https` issuer Snowflake can reach over the public internet. See [AWS credentials](/integrations/aws-credentials#self-hosted-deployments) for the settings. Snowflake caches an issuer's signing keys for up to **60 minutes**, so when rotating the signing key, keep the old key published (`WORKLOAD_IDENTITY_PREVIOUS_KEY`) for at least 60 minutes after the new key is published, and wait another 60 minutes after switching before removing it. Shorter waits cause runs to fail until Snowflake refreshes its cache.
54+
55+
## Use a programmatic access token [#programmatic-access-token]
1256

13-
## Prerequisites
57+
### Prerequisites
1458

1559
- A Snowflake user you can generate a token for. For another user or a service user, your role needs `OWNERSHIP` or `MODIFY PROGRAMMATIC AUTHENTICATION METHODS` on that user.
1660
- Your account host — the `<account_identifier>.snowflakecomputing.com` hostname, for example `myorg-myaccount.snowflakecomputing.com`. Snowsight shows it under **Account details**.
@@ -26,9 +70,9 @@ Snowflake's **network policy** requirement varies by user type, and getting it w
2670
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.
2771
</Callout>
2872

29-
## Create the token [#creating-the-token]
73+
### Create the token [#creating-the-token]
3074

31-
### Option 1 — Snowsight
75+
#### Option 1 — Snowsight
3276

3377
<Steps>
3478
<Step>
@@ -45,7 +89,7 @@ If your account has no network policy, either create one (allowing Sim's egress)
4589
</Step>
4690
</Steps>
4791

48-
### Option 2 — SQL
92+
#### Option 2 — SQL
4993

5094
```sql
5195
ALTER USER my_service_user ADD PROGRAMMATIC ACCESS TOKEN sim_workflows
@@ -59,11 +103,11 @@ Service users (`TYPE = SERVICE`, `LEGACY_SERVICE`, or `SERVICE_AGENT`) **must**
59103

60104
If an authentication policy applies to the user, `'PROGRAMMATIC_ACCESS_TOKEN'` must appear in its `AUTHENTICATION_METHODS` list, otherwise the token is refused.
61105

62-
## Add the credential to Sim [#adding-the-credential-to-sim]
106+
### Add the credential to Sim [#adding-the-credential-to-sim]
63107

64108
<Steps>
65109
<Step>
66-
Add a **Snowflake** block to a workflow, open the credential dropdown, and choose to add a programmatic access token
110+
Add a **Snowflake** block to a workflow, open the credential dropdown, add a connection, and choose **Programmatic access token**
67111
</Step>
68112
<Step>
69113
Enter the **account host** (`myorg-myaccount.snowflakecomputing.com`) and paste the **token**
@@ -73,7 +117,7 @@ If an authentication policy applies to the user, `'PROGRAMMATIC_ACCESS_TOKEN'` m
73117
</Step>
74118
</Steps>
75119

76-
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.
120+
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. Keyless tokens are signed on Sim's servers at run time and never stored.
77121

78122
## Use the credential in workflows [#using-the-credential-in-workflows]
79123

@@ -91,7 +135,7 @@ With a credential selected, these fields become pickers backed by metadata-only
91135
| Named file format | `SHOW FILE FORMATS IN SCHEMA` | database, schema |
92136
| Procedure | `SHOW PROCEDURES IN SCHEMA` | database, schema |
93137

94-
Pickers use the token's effective role: its restricted role when set, otherwise the user's default role. They do not apply the execution role selected on the block. An empty list can indicate a privilege gap. Switch any field to advanced mode to type a name directly or reference an upstream block's output instead.
138+
Pickers use the connection's effective role: its restricted role when set, otherwise the user's default role. They do not apply the execution role selected on the block. An empty list can indicate a privilege gap. Switch any field to advanced mode to type a name directly or reference an upstream block's output instead.
95139

96140
**Unload Data requires a table or view.** To export a query result, create a view or use `CREATE TABLE AS SELECT` through Execute SQL, then unload that object.
97141

@@ -103,6 +147,10 @@ A token's expiry is fixed at creation. To rotate, generate a new token on the sa
103147

104148
| Problem | What to check |
105149
| --- | --- |
150+
| Keyless: "Snowflake did not accept Sim's token" | No user in this account was created with exactly the issuer and subject from the dialog, the user is not `TYPE = SERVICE`, or a network or authentication policy blocks it. Run `SHOW USER WORKLOAD IDENTITY AUTHENTICATION METHODS FOR USER SIM_WORKFLOWS` to compare. |
151+
| Keyless: error 099706 when creating the user | Another user in the account already has this issuer and subject. Find it with `SHOW USER WORKLOAD IDENTITY AUTHENTICATION METHODS` and remove it, or reconnect with a new subject. |
152+
| Keyless: runs fail for up to an hour after a signing-key rotation | Snowflake still caches the old keys. Keep the previous key published for 60 minutes (see [Self-hosted deployments](#self-hosted-deployments)). |
153+
| Keyless option missing | The deployment has no workload-identity signing key, or the connection belongs to an organization rather than a workspace. Use a programmatic access token. |
106154
| Lost token secret | Snowflake shows it only at creation. Generate a replacement and reconnect the credential in Sim. |
107155
| Authentication fails | Check expiry or revocation, the user's network policy and Sim's egress, permitted authentication methods, role restriction, and SQL API access. |
108156
| Wrong host | Use the account's Snowflake hostname. Sim reports a host error separately when the verification endpoint returns `404`. |

0 commit comments

Comments
 (0)