diff --git a/packages/integrations-docs/src/integrations_docs/docs/snowflake.md b/packages/integrations-docs/src/integrations_docs/docs/snowflake.md index a015a3a492a..e7f50b84ef6 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,68 @@ 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 + +Generate an unencrypted PKCS#8 private key: + +```bash +openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt +``` + +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: + +```bash +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 = ; +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 +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. 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. + +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.