From ef3c5c7ea36db45c40fe7fd6cacca5e21dd7c724 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 15:13:20 -0700 Subject: [PATCH 01/13] docs: correct Azure Entra OAuth kernel support in connection param reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The connection-parameter reference (added in #457) predated #505 (feat(kernel): thread Azure Entra auth (U2M + SP M2M) through the kernel path) and still claimed the kernel "rejects Azure-direct (Entra) OAuth". That is now inverted: buildKernelConnectionOptions (lib/kernel/KernelAuth.ts) has a dedicated AzureSpM2m mode for Entra- direct service-principal M2M and consumes both azureTenantId and useDatabricksOAuthInAzure. - Authentication table: azureTenantId / useDatabricksOAuthInAzure kernel cell ❌ → ⚠️, with an accurate flow-selection note. - authType "supported on both" note now mentions Azure Entra SP M2M. - Summary of gaps: drop Azure from "missing/ignored on Kernel" (renumber) and record it under "Behavioral divergences to watch" instead. Other cross-backend rows spot-checked against source and left as-is. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 6c135dd4..cb14b232 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,12 +57,12 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`) and U2M (browser; no secret). | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ❌ | — | **Thrift-only.** Kernel rejects Azure-direct (Entra) OAuth; workspace-OIDC discovery covers Azure workspaces without it. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** Kernel: on an Azure host, `databricks-oauth` **M2M** (secret present) with `useDatabricksOAuthInAzure` absent/`false` routes to Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`); `true` routes to workspace-OIDC M2M. `azureTenantId` is optional (kernel auto-discovers from the workspace `/aad/auth` redirect when omitted). **U2M** ignores the flag — the kernel's cloud-blind in-house flow works against Azure. One divergence: the kernel treats `.databricks.azure.us` as Azure in every arm, whereas Thrift's `useDatabricksOAuthInAzure`-true arm does not. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | @@ -162,10 +162,9 @@ backend, so they are read regardless of `useKernel`. Defaults are sourced from `DBSQLClient.openSession`, but the conf key is likely dropped by the kernel's session-conf allowlist, so it has no effect on the kernel path. 2. Auth types `custom`, `token-provider`, and `external-token`. -3. `azureTenantId` / `useDatabricksOAuthInAzure` (Azure-direct OAuth). -4. `persistence` (custom OAuth token store). -5. SOCKS proxies. -6. Per-statement `useCloudFetch`, `useLZ4Compression`, +3. `persistence` (custom OAuth token store). +4. SOCKS proxies. +5. Per-statement `useCloudFetch`, `useLZ4Compression`, `stagingAllowedLocalPath`. ### Supported on Kernel, no Thrift public equivalent @@ -187,5 +186,12 @@ backend, so they are read regardless of `useKernel`. Defaults are sourced from kernel path (kernel default kept). - **`configuration`** is allowlist-filtered on the kernel path but forwarded more freely on Thrift. +- **Azure OAuth flow selection** differs in mechanism. Both backends honor + `azureTenantId` / `useDatabricksOAuthInAzure`, but the kernel routes Entra- + direct M2M through a dedicated native `AzureSpM2m` mode (auto-discovering the + tenant when `azureTenantId` is omitted) and treats U2M as cloud-blind, while + Thrift builds the Azure authorize URL in-process. The kernel also treats + `.databricks.azure.us` as Azure in every arm; Thrift's + `useDatabricksOAuthInAzure`-true arm does not. > All kernel-path behavior reflects the **M0 stub** and is subject to change. From 44e42bc07a77ee063f18d9e9c2785a54079f4d37 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 15:26:52 -0700 Subject: [PATCH 02/13] =?UTF-8?q?docs:=20mark=20Azure=20OAuth=20options=20?= =?UTF-8?q?fully=20supported=20(=E2=9C=85)=20on=20kernel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design intent: all U2M routes to the cloud-blind in-house OAuth U2M flow (no Azure-specific U2M mode), so `.databricks.azure.us` (US-gov) is always supported via that flow — that is intended completeness, not a support gap. Both `azureTenantId` and `useDatabricksOAuthInAzure` are read and forwarded on both backends, so the kernel cell is ✅ (not ⚠️). Notes reframed: US-gov behavior now reads as the kernel being more complete than Thrift (whose useDatabricksOAuthInAzure-true arm rejects US-gov), and useDatabricksOAuthInAzure documented as selecting only the M2M mechanism. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index cb14b232..780177dd 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -62,7 +62,7 @@ column. | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** Kernel: on an Azure host, `databricks-oauth` **M2M** (secret present) with `useDatabricksOAuthInAzure` absent/`false` routes to Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`); `true` routes to workspace-OIDC M2M. `azureTenantId` is optional (kernel auto-discovers from the workspace `/aad/auth` redirect when omitted). **U2M** ignores the flag — the kernel's cloud-blind in-house flow works against Azure. One divergence: the kernel treats `.databricks.azure.us` as Azure in every arm, whereas Thrift's `useDatabricksOAuthInAzure`-true arm does not. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | @@ -186,12 +186,12 @@ backend, so they are read regardless of `useKernel`. Defaults are sourced from kernel path (kernel default kept). - **`configuration`** is allowlist-filtered on the kernel path but forwarded more freely on Thrift. -- **Azure OAuth flow selection** differs in mechanism. Both backends honor - `azureTenantId` / `useDatabricksOAuthInAzure`, but the kernel routes Entra- - direct M2M through a dedicated native `AzureSpM2m` mode (auto-discovering the - tenant when `azureTenantId` is omitted) and treats U2M as cloud-blind, while - Thrift builds the Azure authorize URL in-process. The kernel also treats - `.databricks.azure.us` as Azure in every arm; Thrift's - `useDatabricksOAuthInAzure`-true arm does not. +- **Azure OAuth** is honored on both, but the mechanism differs. The kernel + runs a cloud-blind in-house flow for **all U2M**, so every Azure workspace — + including `.databricks.azure.us` (US-gov) — is always supported; Thrift's + `useDatabricksOAuthInAzure`-true arm instead rejects US-gov hosts. For + **M2M** the kernel routes Entra-direct through a native `AzureSpM2m` mode + (auto-discovering `azureTenantId` when omitted), whereas Thrift builds the + Azure authorize URL in-process. > All kernel-path behavior reflects the **M0 stub** and is subject to change. From 29f1aa5d8e24920423fb8c6969e2880c16bd6ac2 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 15:33:12 -0700 Subject: [PATCH 03/13] docs: add token, staticToken, and oauthClientSecret rows to auth table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Authentication table documented `authType` and the OAuth modifier options but never gave the credential-bearing fields their own rows — `oauthClientSecret` in particular was only named inline as the flow selector, despite its non-trivial kernel mapping (remapped to `azureClientSecret` on the Entra-direct arm) and a blank-handling divergence (rejected only on the Azure SP arm). Adds three rows, each with the Thrift↔kernel mapping verified against source: - `token` (PAT): Thrift PlainHttpAuthentication vs kernel native `Pat`; kernel rejects blank/reserved + OAuth-field pairing, Thrift does not. - `staticToken`: Thrift StaticTokenProvider (federation opt-in) vs kernel `Pat` bearer with federation always on. - `oauthClientSecret` (M2M): flow selector on both; kernel native `oauthClientSecret` or remapped `azureClientSecret`. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 780177dd..e56ceafd 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -59,9 +59,12 @@ column. | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | +| `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | +| `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | +| `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | | `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From d5f31c698bbf26a592a71eada06d03895c1d9e12 Mon Sep 17 00:00:00 2001 From: "peco-engineer-bot[bot]" Date: Mon, 24 Aug 2026 22:37:04 +0000 Subject: [PATCH 04/13] ai: apply changes for #509 (2 review threads) Addresses: - #3847919330 at CONNECTION_PARAMETERS.md:65 - #3848004541 at CONNECTION_PARAMETERS.md:68 Signed-off-by: peco-engineer-bot[bot] --- CONNECTION_PARAMETERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index e56ceafd..082f9a56 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,7 +57,7 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which requires a kernel binary newer than the `0.2.0` native packages currently pinned in `package.json`; against `0.2.0` the native binding rejects that mode. | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | @@ -65,7 +65,7 @@ column. | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode requires a kernel binary newer than the pinned `0.2.0` native packages** (see #505); against `0.2.0` the native binding rejects it, so this arm is usable only once the pins are bumped to a release that ships that mode. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From ecaf36d0994163a5a617e73eef8e76738d151bf1 Mon Sep 17 00:00:00 2001 From: "peco-engineer-bot[bot]" Date: Mon, 24 Aug 2026 22:38:23 +0000 Subject: [PATCH 05/13] ai: apply changes for #509 (1 review thread) Addresses: - #3848036730 at CONNECTION_PARAMETERS.md:68 Signed-off-by: peco-engineer-bot[bot] --- CONNECTION_PARAMETERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 082f9a56..03f84570 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -65,7 +65,7 @@ column. | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode requires a kernel binary newer than the pinned `0.2.0` native packages** (see #505); against `0.2.0` the native binding rejects it, so this arm is usable only once the pins are bumped to a release that ships that mode. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on Thrift; partial/divergent on the kernel.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode requires a kernel binary newer than the pinned `0.2.0` native packages** (see #505); against `0.2.0` the native binding rejects it, so this arm is usable only once the pins are bumped to a release that ships that mode. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From 87bfa3d15c0cc40d8a5a2b8ce5ecd26ab0f7397b Mon Sep 17 00:00:00 2001 From: "peco-engineer-bot[bot]" Date: Mon, 24 Aug 2026 22:45:08 +0000 Subject: [PATCH 06/13] ai: apply changes for #509 (1 review thread) Addresses: - #3848073178 at CONNECTION_PARAMETERS.md:60 Signed-off-by: peco-engineer-bot[bot] --- CONNECTION_PARAMETERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 03f84570..f35b27f0 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,7 +57,7 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which requires a kernel binary newer than the `0.2.0` native packages currently pinned in `package.json`; against `0.2.0` the native binding rejects that mode. | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`. The committed napi typings (`native/kernel/index.d.ts`) declare this mode, but whether the shipped `0.2.0` binaries implement it is not observable from this repo — confirm your installed kernel build supports `AzureSpM2m` before relying on this arm. | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | @@ -65,7 +65,7 @@ column. | `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | | `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on Thrift; partial/divergent on the kernel.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode requires a kernel binary newer than the pinned `0.2.0` native packages** (see #505); against `0.2.0` the native binding rejects it, so this arm is usable only once the pins are bumped to a release that ships that mode. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on Thrift; partial/divergent on the kernel.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode is declared in the committed napi typings, but the shipped `0.2.0` binaries may predate it** (see #505); the runtime behavior of the pinned binaries is not observable from this repo, so confirm your installed kernel build supports `AzureSpM2m` before relying on this arm. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From 1ebdc6577e7bb8abb61fed75bf96aac299da2326 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 15:54:39 -0700 Subject: [PATCH 07/13] docs: merge the two oauthClientId rows into one complete row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The table had two oauthClientId entries both describing the U2M/no-secret case (one about defaulting, one about flow-selection), which read as two different options, used inconsistent cell notation (✅ vs ✅ (U2M)), and omitted M2M entirely. The flow-selection parity is also now covered by the oauthClientSecret row. Merged into a single oauthClientId row covering both flows: forwarded verbatim when set; defaults to `databricks-sql-connector` when absent (Thrift getClientId() for both flows; kernel `?? DEFAULT_OAUTH_CLIENT_ID` on M2M, napi's own default on U2M); retains the "id + no secret ⇒ U2M, no secret-required error" parity note. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index f35b27f0..ded79d55 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -62,8 +62,7 @@ column. | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | -| `oauthClientId` (U2M) | `string` | ✅ | ✅ | napi default `client_id` when absent | The kernel adapter (`buildKernelConnectionOptions`) forwards a custom `oauthClientId` verbatim on the U2M arm; when it is absent the napi binding applies its own default `client_id`. Whether the native binding then honors or rejects a custom id is not observable from this repo — the TypeScript layer neither hardcodes an id nor rejects one. | -| `oauthClientId` + no secret | `string` | ✅ (U2M) | ✅ (U2M) | — | **Parity.** The kernel keys flow selection off `oauthClientSecret` presence exactly like Thrift, so `oauthClientId` + no secret routes to **U2M** (with the id forwarded) — it does **not** throw an M2M "secret required" error. | +| `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | | `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on Thrift; partial/divergent on the kernel.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode is declared in the committed napi typings, but the shipped `0.2.0` binaries may predate it** (see #505); the runtime behavior of the pinned binaries is not observable from this repo, so confirm your installed kernel build supports `AzureSpM2m` before relying on this arm. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | From 0a90d419500e7485d3a247fd002dd3acc224d0b5 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 16:02:40 -0700 Subject: [PATCH 08/13] =?UTF-8?q?docs:=20restore=20Azure=20kernel=20suppor?= =?UTF-8?q?t=20to=20=E2=9C=85=20with=20a=201.0.0=20version=20floor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The review-bot hedged the Azure row to ⚠️ because the pinned 0.2.0 native binary might predate the AzureSpM2m surface. With a 1.0.0 kernel binary (which carries kernel#282), the Entra-direct M2M arm is implemented at runtime, so the row is ✅ again. Replaces the "0.2.0 may predate / not observable / confirm your build" hedges (Azure row + authType note) with a concrete, checkable version floor: the Entra-direct M2M arm needs the native binary >= 1.0.0; U2M works on any build. Per the ✅ legend (option is read and forwarded), the connector honors these options on both backends; the binary floor is a deployment note, not a support downgrade. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index ded79d55..944be8db 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,14 +57,14 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`. The committed napi typings (`native/kernel/index.d.ts`) declare this mode, but whether the shipped `0.2.0` binaries implement it is not observable from this repo — confirm your installed kernel build supports `AzureSpM2m` before relying on this arm. | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which requires the kernel's Azure service-principal surface (kernel#282) — carried by the native binary from `1.0.0` onward. | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on Thrift; partial/divergent on the kernel.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) **The `AzureSpM2m` mode is declared in the committed napi typings, but the shipped `0.2.0` binaries may predate it** (see #505); the runtime behavior of the pinned binaries is not observable from this repo, so confirm your installed kernel build supports `AzureSpM2m` before relying on this arm. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The Entra-direct M2M arm requires the kernel's Azure service-principal surface (kernel#282), carried by the native binary from **`1.0.0`** onward; U2M needs no minimum. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From e25804b5ea43de217b4091dd8e02d3b1977c5f85 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 16:04:23 -0700 Subject: [PATCH 09/13] docs: phrase kernel 1.0.0 as forthcoming, not an existing version floor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.0.0 is not published yet, so "carried by the native binary from 1.0.0 onward" overstated it as a shipping fact. Reword the Azure row and the authType note: the connector forwards AzureSpM2m today, but its runtime path needs the kernel Azure SP surface (kernel#282), which the currently pinned 0.2.0 binary predates — it lands in a forthcoming release (planned 1.0.0, not yet published). U2M still needs no minimum. Row stays ✅ (the options are read and forwarded per the legend). Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 944be8db..d7f75fd3 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,14 +57,14 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which requires the kernel's Azure service-principal surface (kernel#282) — carried by the native binary from `1.0.0` onward. | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which needs the kernel's Azure service-principal surface (kernel#282) — not in the pinned `0.2.0` binary; it lands in a forthcoming release (planned `1.0.0`, not yet published). | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The Entra-direct M2M arm requires the kernel's Azure service-principal surface (kernel#282), carried by the native binary from **`1.0.0`** onward; U2M needs no minimum. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The connector forwards `AzureSpM2m` today, but its runtime path needs the kernel's Azure service-principal surface (kernel#282), which the currently pinned `0.2.0` native binary predates — it lands in a forthcoming kernel release (planned `1.0.0`, not yet published). U2M needs no minimum. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From d970ea72520bb0ac7d6c433ca39a74d7ba841603 Mon Sep 17 00:00:00 2001 From: "peco-engineer-bot[bot]" Date: Mon, 24 Aug 2026 23:09:42 +0000 Subject: [PATCH 10/13] ai: apply changes for #509 (1 review thread) Addresses: - #3848192767 at CONNECTION_PARAMETERS.md:67 Signed-off-by: peco-engineer-bot[bot] --- CONNECTION_PARAMETERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index d7f75fd3..66c03cec 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -64,7 +64,7 @@ column. | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The connector forwards `AzureSpM2m` today, but its runtime path needs the kernel's Azure service-principal surface (kernel#282), which the currently pinned `0.2.0` native binary predates — it lands in a forthcoming kernel release (planned `1.0.0`, not yet published). U2M needs no minimum. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The connector forwards `AzureSpM2m` today, but its runtime path needs the kernel's Azure service-principal surface (kernel#282), which the currently pinned `0.2.0` native binary predates — it lands in a forthcoming kernel release (planned `1.0.0`, not yet published). U2M needs no minimum. | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From 55ead2bd271ea0ac49d2ccfaea68a82382e3d080 Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 16:13:17 -0700 Subject: [PATCH 11/13] docs: drop kernel binary/version hedging from the Azure rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per direction, treat the kernel Azure SP surface as included. Remove the "0.2.0 predates it / planned 1.0.0, not yet published" caveats from both the Azure row and the authType note; Azure is ✅ on both backends with a clean flow-selection description. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 66c03cec..c7086424 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -57,14 +57,14 @@ column. | Option | Type | Thrift | Kernel | Default Value | Note | | ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). **Note:** the Entra-direct arm emits native `authMode: 'AzureSpM2m'`, which needs the kernel's Azure service-principal surface (kernel#282) — not in the pinned `0.2.0` binary; it lands in a forthcoming release (planned `1.0.0`, not yet published). | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | | `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | | `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | | `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) The connector forwards `AzureSpM2m` today, but its runtime path needs the kernel's Azure service-principal surface (kernel#282), which the currently pinned `0.2.0` native binary predates — it lands in a forthcoming kernel release (planned `1.0.0`, not yet published). U2M needs no minimum. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From 69bf3883af68ad511924251a87ca8671aa986e9a Mon Sep 17 00:00:00 2001 From: "peco-engineer-bot[bot]" Date: Mon, 24 Aug 2026 23:19:05 +0000 Subject: [PATCH 12/13] ai: apply changes for #509 (1 review thread) Addresses: - #3848237239 at CONNECTION_PARAMETERS.md:66 Signed-off-by: peco-engineer-bot[bot] --- CONNECTION_PARAMETERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index c7086424..029d013f 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -64,7 +64,7 @@ column. | `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | | `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | | `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ✅ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | | `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | | `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | From ce31281061bcc2f51fda8e1e481a9aa0424ad98a Mon Sep 17 00:00:00 2001 From: eric-wang-1990 Date: Mon, 24 Aug 2026 22:19:03 -0700 Subject: [PATCH 13/13] docs: run prettier on CONNECTION_PARAMETERS.md Reformat the Authentication table to match prettier's column padding so the lint check passes. Whitespace-only, no content change. Signed-off-by: eric-wang-1990 --- CONNECTION_PARAMETERS.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CONNECTION_PARAMETERS.md b/CONNECTION_PARAMETERS.md index 029d013f..ea0af4fb 100644 --- a/CONNECTION_PARAMETERS.md +++ b/CONNECTION_PARAMETERS.md @@ -55,18 +55,18 @@ column. ## Authentication -| Option | Type | Thrift | Kernel | Default Value | Note | -| ---------------------------------------------- | ------------------------------------------------------------ | :------: | :------: | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | -| `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | -| `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | -| `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | -| `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | -| `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | -| `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | -| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | -| `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | -| `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | +| Option | Type | Thrift | Kernel | Default Value | Note | +| ---------------------------------------------- | ------------------------------------------------------------ | :----: | :----: | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `authType` — supported on both backends | `'access-token'` \| `'databricks-oauth'` \| `'static-token'` | ✅ | ✅ | `'access-token'` | `access-token` uses `token` (PAT) and is the default when `authType` is omitted. `static-token` uses `staticToken`; the kernel maps it to its native bearer-token mode. `databricks-oauth` covers M2M (`oauthClientId` + `oauthClientSecret`), U2M (browser; no secret), and — on an Azure host — Entra-direct service-principal M2M (see the `azureTenantId` / `useDatabricksOAuthInAzure` row). | +| `authType` — Thrift-only | `'custom'` \| `'token-provider'` \| `'external-token'` | ✅ | ❌ | — | **Thrift-only.** `custom` uses `provider: IAuthentication`, `token-provider` uses `tokenProvider: ITokenProvider`, and `external-token` uses `getToken: TokenCallback`. The kernel throws `unsupported auth mode` for these modes. | +| `token` (PAT) | `string` | ✅ | ✅ | — (required for `access-token`) | Personal access token for `access-token` (the default mode). Thrift → `PlainHttpAuthentication` HTTP basic auth (username `token`). Kernel → native `Pat` authMode. Kernel rejects a blank/reserved token client-side (`AuthenticationError`) and rejects pairing it with OAuth fields; Thrift forwards it verbatim (a blank surfaces as a server-side 401). | +| `staticToken` | `string` | ✅ | ✅ | — (required for `static-token`) | Bearer/JWT for `static-token`. Thrift → `StaticTokenProvider.fromJWT` wrapped in `TokenProviderAuthenticator` (federation opt-in via `enableTokenFederation`). Kernel → native `Pat` bearer mode with federation always on (`federationClientId` ⇒ SP-wide WIF, omitted ⇒ account-wide). Kernel rejects a blank/reserved value; see the `enableTokenFederation` row. | +| `oauthScopes` | `Array` | ❌ | ✅ | U2M `['sql','offline_access']`, M2M `['all-apis']` | **Thrift ignores `oauthScopes`** — `createAuthProvider` never threads it into `DatabricksOAuth`, so `authenticate()` always falls back to `defaultOAuthScopes` (`['sql','offline_access']`). Only the kernel honors a custom `oauthScopes`; its defaults happen to match Thrift's fallback. | +| `oauthClientId` | `string` | ✅ | ✅ | `databricks-sql-connector` when absent | OAuth client id, used on **both** U2M and M2M. Forwarded verbatim on both backends when set. When absent it defaults to `databricks-sql-connector` — Thrift via `getClientId()` for both flows; kernel via `oauthClientId ?? DEFAULT_OAUTH_CLIENT_ID` on M2M, and by letting the napi binding apply its own (identical) default on U2M. **Parity:** `oauthClientId` + no secret routes to **U2M** with the id forwarded (flow selection keys off `oauthClientSecret` presence — see that row), so it does **not** throw an M2M "secret required" error. | +| `oauthClientSecret` (M2M) | `string` | ✅ | ✅ | — | M2M client-credentials secret; its **presence** is the U2M-vs-M2M flow selector on both backends (`undefined` ⇒ U2M). Thrift → `DatabricksOAuth.clientSecret`. Kernel → native `oauthClientSecret` (workspace-OIDC M2M) or remapped to `azureClientSecret` (Entra-direct `AzureSpM2m`). A blank/reserved secret is forwarded verbatim and still selects M2M (Thrift parity) — except the Azure SP arm, which rejects it. | +| `azureTenantId` / `useDatabricksOAuthInAzure` | `string` / `boolean` | ✅ | ⚠️ | — | **Honored on both.** By design the kernel routes **all U2M** (no secret, any cloud) to its cloud-blind in-house OAuth U2M flow — there is no Azure-specific U2M mode, so `useDatabricksOAuthInAzure` is inert on U2M and every Azure workspace (including `.databricks.azure.us` US-gov) is always supported, on any kernel build. `useDatabricksOAuthInAzure` selects only the **M2M** mechanism on an Azure host: absent/`false` → Entra-direct service-principal M2M (native `AzureSpM2m` mode, creds ride `oauthClientId`/`oauthClientSecret`, `azureTenantId` optional — kernel auto-discovers from the workspace `/aad/auth` redirect when omitted); `true` → workspace-OIDC M2M. (`lib/kernel/KernelAuth.ts` `buildKernelConnectionOptions`.) | +| `persistence` (custom OAuth token store) | `OAuthPersistence` | ✅ | ❌ | — | **Thrift-only.** Kernel throws; it auto-persists U2M tokens to `~/.config/databricks-sql-kernel/oauth/` and does not cache M2M. | +| `enableTokenFederation` / `federationClientId` | `boolean` / `string` | ✅ | ⚠️ | `false` / — | On the kernel backend these options apply only to `static-token`. Federation is always enabled, so `enableTokenFederation` is ignored; an omitted or empty client ID selects account-wide WIF and a non-empty ID selects SP-wide WIF. Thrift honors the boolean and also supports these options for `token-provider` and `external-token`. | ## HTTP client, proxy, retries