Skip to content

feat(snowflake): credential-based auth, object pickers, and 9 new operations - #6474

Merged
waleedlatif1 merged 7 commits into
stagingfrom
snowflake-credential
Aug 9, 2026
Merged

feat(snowflake): credential-based auth, object pickers, and 9 new operations#6474
waleedlatif1 merged 7 commits into
stagingfrom
snowflake-credential

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Snowflake now authenticates with a credential instead of per-block host + PAT fields — connect once with an account host and programmatic access token, then pick it from the dropdown like any other integration. Credential picker moved to the top of the block.
  • Database, schema, table, warehouse, execution role, file format and procedure fields are now pickers backed by metadata-only statements (no warehouse, no credits), behind one /api/tools/snowflake/objects route.
  • Added 9 operations: Unload Data, List Databases/Schemas/Tables, Alter Warehouse, Resume/Suspend Task, List Query History, List Copy History.
  • New setup guide at docs.sim.ai/integrations/snowflake-service-account.

Breaking

Saved Snowflake blocks must be reconnected — the host and apiKey fields are gone. The block shipped in #6407 (same day), so blast radius should be minimal.

Type of Change

  • New feature

Testing

Tested manually. Five parallel audits against Snowflake's live docs surfaced and fixed, among others:

  • errorOnly on query history filtered on 'FAIL', which is not a valid INFORMATION_SCHEMA execution status — the filter matched nothing and returned "no failures" forever.
  • HEADER was emitted as a copy option in COPY INTO <location>; the grammar places it after them.
  • The credential sub-block was missing canonicalParamId: 'oauthCredential', which left every picker permanently disabled.
  • The Alter Warehouse size dropdown auto-seeded its first option, silently resizing warehouses to XSMALL.
  • An unload source query could break out of its derived-table parentheses and set its own OVERWRITE = TRUE.
  • Wrong account hosts were reported as a Snowflake outage (Snowflake wildcard-resolves and answers 404).

Added SQL builder tests for every new statement, credential-validator tests, and block↔tool contract tests covering required-param alignment, canonical groups, and dependsOn wiring.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…rations

Replace the per-block host + PAT fields with a Snowflake service-account
credential, move the credential picker to the top of the block, back the
object fields with metadata-only pickers, and add nine operations.

- credential: snowflake-service-account token service account (account host +
  programmatic access token), verified against the SQL API with the same
  headers the tools use
- selectors: database, schema, table, warehouse, execution role, file format
  and procedure pickers behind one /api/tools/snowflake/objects route
- new operations: unload_data, list_databases, list_schemas, list_tables,
  alter_warehouse, resume_task, suspend_task, list_query_history,
  list_copy_history
@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 9, 2026 6:20am

Request Review

@cursor

cursor Bot commented Aug 9, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Breaking credential migration for Snowflake blocks and a new server route that resolves stored PATs; warehouse alter and task suspend/resume can change production Snowflake behavior if misconfigured.

Overview
Snowflake workflows now use a stored programmatic access token credential (account host + PAT) instead of per-block host and apiKey fields. The block resolves the token server-side via oauthCredential; saved workflows need reconnecting after migration renames legacy fields onto advanced text inputs and drops retired secrets.

Object pickers for database, schema, table, warehouse, role, file format, and procedure are backed by a new POST /api/tools/snowflake/objects route that runs metadata-only SHOW statements with credential authorization.

Nine new block operations are documented and wired: unload data, list databases/schemas/tables, alter warehouse, resume/suspend task, list query history, and list copy history. Integration docs add a snowflake-service-account setup guide; action reference tables no longer list host/apiKey on each tool.

Supporting changes: Snowflake PAT credential validation on connect, selector registry/contracts, json-array wand generation for row/binding fields, and migration logic that deletes _removed_* parked subblocks so old PATs do not linger in exports.

Reviewed by Cursor Bugbot for commit 2aa6af6. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves Snowflake tools to credential-based authentication and adds metadata-backed object pickers plus nine operations.

  • Adds a session/internal-authenticated endpoint for selecting Snowflake databases, schemas, tables, warehouses, roles, file formats, and procedures.
  • Adds unload, object-listing, warehouse-alteration, task-control, query-history, and copy-history operations.
  • Updates block configuration, credential validation, migrations, generated tool metadata, tests, and integration documentation.

Confidence Score: 5/5

The PR appears safe to merge because the previously reported authentication-order issue is fixed and no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/app/api/tools/snowflake/objects/route.ts Adds an authenticated and credential-authorized metadata selector route; the prior validation-order issue is fixed at current HEAD.
apps/sim/blocks/blocks/snowflake.ts Reworks Snowflake block inputs around a shared credential and adds picker and operation wiring.
apps/sim/tools/snowflake/sql.ts Extends centralized Snowflake SQL construction for the new metadata and operational statements.
apps/sim/lib/credentials/token-service-accounts/validators/snowflake.ts Adds validation for Snowflake account-host and programmatic-access-token credentials.
apps/docs/content/docs/en/integrations/snowflake-service-account.mdx Documents Snowflake programmatic access token creation, configuration, use, and rotation.

Sequence Diagram

sequenceDiagram
  participant UI as Snowflake Block Picker
  participant API as /api/tools/snowflake/objects
  participant Auth as Session/Internal Auth
  participant Cred as Credential Authorization
  participant SF as Snowflake SQL API
  UI->>API: POST credential, workflowId, kind
  API->>Auth: Authenticate before body validation
  Auth-->>API: caller userId
  API->>API: Validate selector request
  API->>Cred: Authorize credential use
  Cred-->>API: credential owner
  API->>SF: Execute metadata-only statement
  SF-->>API: Object rows
  API-->>UI: Picker objects
Loading

Reviews (7): Last reviewed commit: "fix(snowflake): unload a table, not an i..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/snowflake/objects/route.ts
…parsing

- add SUBBLOCK_ID_MIGRATIONS entries so the renamed object fields map onto
  their pickers and the removed host/apiKey values are parked
- authenticate the caller before contract validation in the selector route,
  per the API route convention
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/workflows/migrations/subblock-migrations.ts
…rrect docs

- assertBalancedQuery now skips // line comments, $$ dollar quoting and rejects
  ambiguous nested block comments; each hid a paren that let an injected
  OVERWRITE = TRUE escape the derived table
- always emit OVERWRITE so an injected duplicate is rejected by Snowflake
  rather than silently replacing staged files
- _removed_ migration targets now drop the stored value instead of parking it
  under a dead key, where export scrubbing (which walks the block config) would
  never clear it
- 403 falls back to the shared invalid-credentials message, which names the
  network policy and SQL API causes Snowflake does not distinguish in the body
- correct the network-policy-by-user-type claim: only SERVICE_AGENT is exempt
- correct MAX_FILE_SIZE and errorOnly tool descriptions to match the fixed code
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

…gration

- an untouched switch serializes as null, and advanced mode emits every
  advanced subblock, so alter_warehouse silently sent AUTO_RESUME = FALSE and
  permanently disabled auto-resume on the warehouse; normalize optional
  booleans to undefined in tools.config.params
- point the subblock migration at the advanced text members: a migrated block
  has no credential, so a picker cannot hydrate a stored name, and legacy
  fileFormat values were qualified while the picker lists bare names
- add the missing json-object wand type and scope the SQL wand prompt, which
  promised bindings that unload_data does not accept
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/workflows/migrations/subblock-migrations.ts
Comment thread apps/sim/app/api/tools/snowflake/objects/route.ts
Comment thread apps/sim/blocks/blocks/snowflake.ts Outdated
- an earlier version of this migration renamed retired fields into _removed_*
  keys instead of deleting them, so deployed workflows still hold those values;
  they match no oldId, so a dedicated sweep clears them for every block type
- the picker now treats a Snowflake 403 like a 401: it means a network policy
  or a disabled SQL API, which the credential validator already reports as a
  credential problem rather than a bad request
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

1 issue from previous review remains unresolved.

Fix All in Cursor

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0307c39. Configure here.

The json-object reinforcement tells the model the response must start with {
and end with }, which fights any field whose contract is an array. Snowflake's
rows, matchColumns and procedureArguments all ask for arrays, so they were
being steered toward an object that the JSON parse would then reject.

Adds a sibling json-array type that strips fences the same way but reinforces
brackets, and points the three array fields at it. bindings and filters are
genuine objects and stay on json-object.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d5ede2e. Configure here.

The COPY INTO grammar places the source immediately before its copy options, so
an inlined query sits one parenthesis from being able to rewrite them. Guarding
that means matching Snowflake's tokenizer exactly, and three successive versions
of the guard were each defeated: // line comments, $$ dollar quoting, and a bare
carriage return, which the scanner did not treat as a line terminator but
Snowflake does. Each fix was a guess at a lexer the public docs do not specify.

Removes the inline-query source instead of guessing a fourth time. A table name
goes through qualifiedIdentifier, which is provably safe. Exporting a query
result now means materializing it first — a view, or CREATE TABLE AS SELECT via
Execute SQL — which the tool description, the block skill and the docs all say.

Also from the final audit:
- optionalBoolean accepts the string forms a direct tool call delivers, matching
  the other boolean readers on this block, and its TSDoc no longer states the
  serializer rule backwards
- the five JSON editors declare language: 'json', so invalid JSON is caught
  inline instead of at execution
- bound the RESULT_SCAN read in SQL, not only by rows_per_resultset
- pin every migration target to a live subblock id, for all blocks
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Final validation round removed a capability rather than guarding it again — flagging since it narrows the PR's scope.

Unload Data now exports a table, not an inline query. The COPY INTO <location> grammar places the source immediately before the copy-option slot, so an inlined query sits one parenthesis away from being able to rewrite those options. Guarding that requires matching Snowflake's tokenizer exactly, and three successive versions of the guard were each defeated by a construct the public docs do not enumerate:

  1. // line comments (Snowflake supports them alongside --)
  2. $$…$$ dollar quoting
  3. a bare \r, which the scanner did not treat as a line terminator but Snowflake does — yielding a valid COPY INTO with an injected PARTITION BY

Each fix was a guess at an unspecified lexer, so the fourth guess did not seem better than removing the surface. A table name goes through qualifiedIdentifier, which is provably safe. Exporting a query result now means materializing it first (a view, or CREATE TABLE AS SELECT via Execute SQL) — stated in the tool description, the block skill, and the docs page. Happy to restore the query mode in a follow-up if someone wants it, ideally by having Snowflake parse the query rather than us.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2aa6af6. Configure here.

@waleedlatif1
waleedlatif1 merged commit 303986f into staging Aug 9, 2026
30 checks passed
@waleedlatif1
waleedlatif1 deleted the snowflake-credential branch August 9, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant