From 25933817b877d21ecff2ebc3b6ec22c0a7948628 Mon Sep 17 00:00:00 2001 From: Darksinian Date: Mon, 6 Jul 2026 12:53:43 -0700 Subject: [PATCH 1/4] Document Snowflake key-pair authentication in the integration docs Co-Authored-By: Claude Fable 5 --- .../src/integrations_docs/docs/snowflake.md | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md index a015a3a492a..bcf963db699 100644 --- a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md +++ b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md @@ -2,7 +2,11 @@ Snowflake is a cloud-based data warehousing platform that enables users to store, manage, and analyze large volumes of data. It provides a scalable and flexible architecture that separates storage and compute resources, allowing for efficient data processing and querying. -## Step 1: Create an OAuth Integration in Snowflake +The integration supports two authentication methods: **OAuth** (each user logs in with their own Snowflake account) and **Key Pair** (the app authenticates as a shared service user with an RSA key pair — no browser login, tokens never expire mid-session). + +## OAuth + +### Step 1: Create an OAuth Integration in Snowflake To enable OAuth for your Snowflake account, an administrator must first register the connected app. @@ -35,11 +39,51 @@ get_base_component_map()["pre"]( ) ``` -## Step 2: Log in via OAuth +### Step 2: Log in via OAuth NOTE: you must use a non-admin account to complete the OAuth flow. +## Key Pair + +Key-pair authentication connects as a Snowflake service user with a registered RSA public key. Use it when the app should have its own identity instead of a user's OAuth session. + +### Step 1: Generate an RSA key pair + +```bash +# Private key (unencrypted PKCS#8; add a passphrase with `-v2 aes256` instead of `-nocrypt`) +openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt + +# Public key +openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub +``` + +### Step 2: Register the public key on a Snowflake user + +Run as an administrator, pasting the contents of `rsa_key.pub` without the `BEGIN/END PUBLIC KEY` lines: + +```sql +CREATE USER IF NOT EXISTS svc_reflex TYPE = SERVICE DEFAULT_ROLE = ; + +ALTER USER svc_reflex SET RSA_PUBLIC_KEY='MIIBIjANBgkq...'; +``` + +The user's role needs `USAGE` on the warehouse, database, and schema the app will query. To verify the registration, compare `RSA_PUBLIC_KEY_FP` from `DESC USER svc_reflex` with: + +```bash +openssl rsa -pubin -in rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64 +``` + +### Step 3: Fill in the Key Pair tab + +- `SNOWFLAKE_USER`: the user the public key is registered on (e.g. `svc_reflex`) +- `SNOWFLAKE_PRIVATE_KEY`: paste the full contents of `rsa_key.p8` (mangled newlines from copy/paste are fine) +- `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE`: only if the private key is encrypted + +The warehouse and database dropdowns populate once the key pair authenticates, which doubles as a connection check. + +If a private key is ever lost or leaked, generate a new pair and re-run the `ALTER USER ... SET RSA_PUBLIC_KEY` — Snowflake also supports `RSA_PUBLIC_KEY_2` for zero-downtime rotation. + # Roadmap In the future, this integration will be extended to support external OAuth -flows, service principal authentication, and external network access. \ No newline at end of file +flows, service principal authentication, and external network access. From a48610d836edeb59007e29a12ab8601cceb21f2d Mon Sep 17 00:00:00 2001 From: Darksinian Date: Mon, 6 Jul 2026 13:29:04 -0700 Subject: [PATCH 2/4] Address review: GRANT ROLE step and SHA256: fingerprint prefix Co-Authored-By: Claude Fable 5 --- .../integrations-docs/src/integrations_docs/docs/snowflake.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md index bcf963db699..cbcbe2d9864 100644 --- a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md +++ b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md @@ -63,11 +63,12 @@ Run as an administrator, pasting the contents of `rsa_key.pub` without the `BEGI ```sql CREATE USER IF NOT EXISTS svc_reflex TYPE = SERVICE DEFAULT_ROLE = ; +GRANT ROLE TO USER svc_reflex; ALTER USER svc_reflex SET RSA_PUBLIC_KEY='MIIBIjANBgkq...'; ``` -The user's role needs `USAGE` on the warehouse, database, and schema the app will query. To verify the registration, compare `RSA_PUBLIC_KEY_FP` from `DESC USER svc_reflex` with: +The `GRANT ROLE` is required — `DEFAULT_ROLE` only sets a preference and does not grant the role. The role needs `USAGE` on the warehouse, database, and schema the app will query. To verify the registration, compare `RSA_PUBLIC_KEY_FP` from `DESC USER svc_reflex` (Snowflake prefixes it with `SHA256:`) against the output of: ```bash openssl rsa -pubin -in rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64 From 2405e24e9d1e2a15427ed23df7770a90eb26f2ba Mon Sep 17 00:00:00 2001 From: Darksinian Date: Mon, 6 Jul 2026 16:17:09 -0700 Subject: [PATCH 3/4] Address review: passphrase guidance and single-line public key command Co-Authored-By: Claude Fable 5 --- .../src/integrations_docs/docs/snowflake.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md index cbcbe2d9864..d9579ec07c4 100644 --- a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md +++ b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md @@ -50,9 +50,12 @@ Key-pair authentication connects as a Snowflake service user with a registered R ### Step 1: Generate an RSA key pair ```bash -# Private key (unencrypted PKCS#8; add a passphrase with `-v2 aes256` instead of `-nocrypt`) +# Private key (unencrypted PKCS#8) openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt +# — or encrypted, if your organization requires passphrase-protected keys at rest +openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes256 -inform PEM -out rsa_key.p8 + # Public key openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub ``` @@ -68,6 +71,12 @@ GRANT ROLE TO USER svc_reflex; ALTER USER svc_reflex SET RSA_PUBLIC_KEY='MIIBIjANBgkq...'; ``` +To print the `ALTER USER` statement with the key already formatted on a single line: + +```bash +echo "ALTER USER svc_reflex SET RSA_PUBLIC_KEY='$(grep -v '^-----' rsa_key.pub | tr -d '\n')';" +``` + The `GRANT ROLE` is required — `DEFAULT_ROLE` only sets a preference and does not grant the role. The role needs `USAGE` on the warehouse, database, and schema the app will query. To verify the registration, compare `RSA_PUBLIC_KEY_FP` from `DESC USER svc_reflex` (Snowflake prefixes it with `SHA256:`) against the output of: ```bash @@ -78,7 +87,7 @@ openssl rsa -pubin -in rsa_key.pub -outform DER | openssl dgst -sha256 -binary | - `SNOWFLAKE_USER`: the user the public key is registered on (e.g. `svc_reflex`) - `SNOWFLAKE_PRIVATE_KEY`: paste the full contents of `rsa_key.p8` (mangled newlines from copy/paste are fine) -- `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE`: only if the private key is encrypted +- `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE`: only if the private key is encrypted. It is stored with the integration secrets and used to decrypt the key at connect time. To strip a passphrase from an existing key instead: `openssl pkcs8 -topk8 -in rsa_key.p8 -nocrypt -out rsa_key_plain.p8` The warehouse and database dropdowns populate once the key pair authenticates, which doubles as a connection check. From da92bd5c53b7db1db03b7e2d77440a1478fb152e Mon Sep 17 00:00:00 2001 From: Darksinian Date: Mon, 6 Jul 2026 16:25:08 -0700 Subject: [PATCH 4/4] Split key generation commands into separate copyable code blocks Co-Authored-By: Claude Fable 5 --- .../src/integrations_docs/docs/snowflake.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md index d9579ec07c4..e7f50b84ef6 100644 --- a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md +++ b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md @@ -49,14 +49,21 @@ Key-pair authentication connects as a Snowflake service user with a registered R ### Step 1: Generate an RSA key pair +Generate an unencrypted PKCS#8 private key: + ```bash -# Private key (unencrypted PKCS#8) openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt +``` -# — or encrypted, if your organization requires passphrase-protected keys at rest +Or generate an encrypted one, if your organization requires passphrase-protected keys at rest: + +```bash openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes256 -inform PEM -out rsa_key.p8 +``` + +Then derive the public key: -# Public key +```bash openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub ```