feat(kernel): thread Azure Entra auth (U2M + SP M2M) through the kernel path - #505
Conversation
There was a problem hiding this comment.
Verdict: 2 Low
Looks good — the Entra-direct routing (useDatabricksOAuthInAzure splitting in-house vs Entra-direct, SP M2M → AzureSpM2m, Entra-direct U2M rejected) is correct and matches the described table and the updated tests. Two low-severity consistency notes: persistence is silently accepted on the new AzureSpM2m branch (rejected everywhere else on the M2M/U2M paths, and contradicts the contract docblock), and the oauthClientId-required rejection for Azure SP M2M lacks a unit test. The bundled bot-infra changes (.bot/config.yaml, learning-log, workflow) are unrelated to the auth feature but self-contained.
…el path On useKernel=true + authType='databricks-oauth', route Azure Entra auth to the kernel instead of rejecting it. Mirrors the Thrift OAuthManager.getManager: useDatabricksOAuthInAzure selects the flavour on an Azure host. - useDatabricksOAuthInAzure: true -> in-house workspace-federated flow, which the kernel runs natively: no secret -> OAuthU2m (browser), secret -> OAuthM2m (workspace-OIDC client-credentials). Works against Azure workspaces. - absent/false on an Azure host -> Entra-direct: with a secret -> the kernel's Azure SP M2M (AzureSpM2m; Entra SP creds ride oauthClientId/oauthClientSecret, azureTenantId optional/auto-discovered); without a secret -> Entra-direct browser U2M, which the kernel does not implement -> rejected with a pointer to useDatabricksOAuthInAzure: true or the Thrift backend. - Non-Azure host: the flags are inert (in-house is the only flow). Adds an AzureSpM2m variant to the native-options union + an isAzureHost helper. Replaces the previous blanket Azure-OAuth rejection. Verified end-to-end against a live Azure workspace (U2M browser flow + SP M2M data token) with a native module built from databricks-sql-kernel#280. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
Point the kernel-e2e KERNEL_REV at the kernel commit that adds the napi AzureSpM2m surface (databricks-sql-kernel#280, stacked on #263), so the connector's kernel-e2e builds a kernel that can accept azure-sp-m2m. This is a temporary pin to the unmerged #280 branch tip; re-point to a kernel main SHA once #263 + #280 merge and a kernel release is cut. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
64307cd to
acbccbf
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends the NodeJS kernel backend (useKernel: true) to support Azure Entra (Azure AD) authentication routing for authType: 'databricks-oauth', including Entra-direct service-principal M2M (AzureSpM2m) and in-house/workspace-federated U2M/M2M flows, and updates tests accordingly. It also adds an “engineer-bot learning” daily workflow and supporting configuration/log scaffolding.
Changes:
- Add
AzureSpM2mto the kernel native auth options union and implement Azure-host routing logic inbuildKernelConnectionOptions. - Update kernel unit tests to reflect the new Azure routing and the Entra-direct U2M rejection behavior.
- Add engineer-bot retrospective learning workflow + config/log plumbing, and bump the shared bot engine pin.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
lib/kernel/KernelAuth.ts |
Adds AzureSpM2m native options and implements Azure host routing for in-house vs Entra-direct flows. |
tests/unit/kernel/auth-u2m.test.ts |
Updates U2M kernel tests for Azure routing and Entra-direct U2M rejection. |
tests/unit/kernel/auth-m2m.test.ts |
Updates M2M kernel tests to cover Azure Entra-direct SP M2M (AzureSpM2m) and in-house routing. |
CHANGELOG.md |
Documents the new Azure Entra auth routing behavior on the kernel backend. |
.github/workflows/engineer-bot-learning.yml |
Adds a daily cron workflow to extract retrospective learnings and open/update a rolling PR. |
.github/actions/bot-prelude/action.yml |
Updates the pinned bot-engine commit SHA used by bot workflows. |
.claude/knowledge/learning-log.md |
Seeds the shared learning log file consumed by the author flow and appended by retrospective. |
.bot/config.yaml |
Wires the author phase to read the learning log and enables the retrospective configuration block. |
Suppressed comments (1)
lib/kernel/KernelAuth.ts:688
- Azure routing diverges from the Thrift
OAuthManager.getManagerbehavior for.databricks.azure.us: Thrift only treats that suffix as Azure whenuseDatabricksOAuthInAzureis false (Entra-direct), but the kernel path will currently allowuseDatabricksOAuthInAzure: trueand route it to in-houseOAuthU2m/OAuthM2m. If the goal is to mirror Thrift routing (as described in the PR), add an explicit guard for.databricks.azure.uswhenuseDatabricksOAuthInAzure:trueto avoid a silent behavior mismatch.
staticToken?: string;
federationClientId?: string;
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Verdict: 1 Medium
Looks solid overall — the Azure routing mirrors Thrift's getManager split cleanly and is well-tested. One medium concern: the new AzureSpM2m branch bypasses the M2M persistence rejection, silently dropping an option that every other OAuth path rejects loudly.
…g it
The prior routing rejected Azure U2M when useDatabricksOAuthInAzure was
absent/false (the 'Entra-direct' default), on the assumption the kernel needed
an Entra-direct browser U2M flow it lacks. That was wrong: the kernel runs a
single, cloud-blind in-house U2M flow — it uses the workspace's OIDC-discovered
authorize endpoint ({host}/oidc/v1/authorize) verbatim — and that
workspace-federated flow works against Azure workspaces (the workspace federates
the browser login to Entra server-side; verified E2E).
So all U2M now falls through to OAuthU2m with the in-house app
(databricks-sql-connector) + sql/offline_access, regardless of cloud or
useDatabricksOAuthInAzure — consistent with the Go connector's uniform U2M
mapping. Only Entra-direct M2M (Azure host + secret + not
useDatabricksOAuthInAzure) still maps to the kernel's azure-sp-m2m.
Updated the test that asserted the rejection to assert OAuthU2m, and the
docstring/CHANGELOG.
Co-authored-by: Isaac
Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
There was a problem hiding this comment.
Verdict: 2 Medium · 2 Low
Solid, well-documented change that faithfully mirrors the Thrift OAuthManager.getManager split for the kernel path; routing logic and tests look correct. Main concerns: persistence is silently ignored on the new Azure SP M2M branch (rejected everywhere else), a stale Throws docstring line, the temporary KERNEL_REV pin to an unmerged kernel branch + un-bumped npm pins, and a missing test for the new oauthClientId-required throw.
Addresses: - #3828516211 at lib/kernel/KernelAuth.ts:747 - #3828516217 at lib/kernel/KernelAuth.ts:741 - #3828530379 at lib/kernel/KernelAuth.ts:292 - #3832331772 at lib/kernel/KernelAuth.ts:546 Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: 1 Medium
Looks good overall — the AzureSpM2m routing, TS narrowing, and persistence/clientId guards in KernelAuth.ts are correct and well-tested. One medium concern: the emitted AzureSpM2m authMode outruns the still-pinned 0.2.0 npm kernel, so end users hitting the Azure Entra-direct M2M combo get an opaque native error instead of the prior clean rejection until the pins are bumped.
Other findings
- 🟡 Medium — The new routing emits
authMode: 'AzureSpM2m'for the Azure-host + secret +useDatabricksOAuthInAzure !== truecombination, but the published native-module pins here are still0.2.0, which (per the PR description) does not expose the Azure SP surface.KERNEL_REVis bumped for kernel-e2e, but that file does not govern what end usersnpm install.
Net effect for a user on the published package who hits this combination: before this PR they got a clear HiveDriverError ("Azure-direct OAuth ... is not supported"); after this PR they instead get an opaque native failure from a 0.2.0 kernel that doesn't recognize AzureSpM2m. That's a regression in error clarity that ships the moment this merges, independent of the follow-up kernel release.
Consider gating the AzureSpM2m emission behind a kernel-capability/version check (falling back to the previous clear rejection), or holding this branch until the npm pins can be bumped in the same release, so end users never route to an authMode the installed kernel can't accept.
Addresses: - #3834226992 at lib/kernel/KernelAuth.ts:782 Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: 1 Low
Looks good — a clean, well-documented, well-tested change that threads Azure Entra auth (U2M + SP M2M) through the kernel path and correctly mirrors the Thrift OAuthManager.getManager routing (including the intentional .databricks.azure.us divergence, which I verified against lib/connection/auth/DatabricksOAuth/OAuthManager.ts). One low-severity note about missing test coverage for the new host-normalization logic that gates auth routing. The native/kernel/* changes are NAPI-RS regenerations tracking the new KERNEL_REV.
Addresses: - #3834265600 at lib/kernel/KernelAuth.ts:289 Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: 1 Low
Looks good — the Azure Entra SP M2M / U2M threading through the kernel path is well-structured, closely mirrors Thrift's OAuthManager.getManager, and is thoroughly unit-tested (routing, host normalization, blank/reserved credential hygiene, tenant auto-discovery fallback). Note: on an Azure host with a secret and no useDatabricksOAuthInAzure, M2M now routes to Entra-direct AzureSpM2m instead of the previous kernel behavior (generic workspace-OIDC OAuthM2m) — this is an intentional, CHANGELOG-documented alignment with Thrift, but is a silent routing change for existing kernel-on-Azure M2M setups. Only one low doc-accuracy nit inline. The large native/kernel/index.* churn is regenerated napi-rs output (CI asserts it matches KERNEL_REV), not a hand-edit.
Addresses: - #3834302149 at lib/kernel/KernelAuth.ts:288 Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: 1 Low
Looks good — the Azure Entra (U2M + SP M2M) kernel-path threading is correct, mirrors the Thrift OAuthManager.getManager routing, and is well covered by the new/updated unit tests (routing, host normalization, blank/reserved credential hygiene, tenant auto-discovery fallback). Comments match the code and the contract docblock/CHANGELOG were kept in sync. One low-severity note: the regenerated native/kernel/index.js/index.d.ts come from an apparently older napi-rs codegen than before — worth confirming the toolchain downgrade is intentional.
The prior refresh (d74ffaa) hand-copied the kernel's committed napi/index.* into native/kernel/. Those are @napi-rs/cli v2-style output, but the kernel's napi crate is 3.11.0, so build:native runs @napi-rs/cli@3.8.2 (v3-style) — the format the committed contract actually uses. The hand-copy therefore regressed index.js's loader (dropped the NAPI_RS_NATIVE_LIBRARY_PATH override, the per-package version-consistency checks, and the win32-x64-gnu/darwin-universal targets) and reformatted index.d.ts wholesale. Regenerate authoritatively by running npm run build:native against the pinned KERNEL_REV (kernel main 5e5dea9) with @napi-rs/cli@3.8.2. Result: - index.js: byte-identical to the pre-d74ffaa baseline (a new auth mode does not change the platform-resolution loader) — net zero change vs the PR base. - index.d.ts: purely additive (+158/-2) — exposes AuthMode.AzureSpM2m and the azureClientId/azureClientSecret/azureTenantId/azureWorkspaceResourceId fields, plus the OAuthM2mJwt mode, tokenUrl/jwt* and telemetry/system-config fields that had also drifted out of the committed contract. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
What
Threads Azure Entra (Azure AD) auth — both U2M and service-principal M2M — through the
useKernel: truepath, replacing the previous blanket Azure-OAuth rejection. This is the NodeJS analog of the Python connector's kernel Azure bridge, and it consumes the kernel Azure surface — napiAuthMode::AzureSpM2m— now on kernelmainvia databricks-sql-kernel#282 (which re-landed the napi + C-ABI surface after #280 was mis-merged into an orphaned branch).How
lib/kernel/KernelAuth.ts— onauthType: 'databricks-oauth',useDatabricksOAuthInAzureselects the flavour on an Azure host, mirroring the ThriftOAuthManager.getManager:useDatabricksOAuthInAzureOAuthU2m— in-house workspace-federated browser flow (in-house app +sql offline_access); works on Azure tootrue(in-house)OAuthM2m(workspace-OIDC client-credentials)false(Entra-direct)AzureSpM2m(Entra SP M2M)OAuthM2mU2M is never rejected and never special-cased by cloud. The kernel runs a single, cloud-blind in-house U2M flow (it uses the workspace's OIDC-discovered
{host}/oidc/v1/authorizeverbatim), and that flow works against Azure workspaces — the workspace federates the browser login to Entra server-side. Feeding the kernel the Thrift Azure Entra-direct app /user_impersonationscope would derail it to a broken AAD authorize URL, so the kernel path forwards the in-house app (databricks-sql-connector) +sql offline_accessfor all clouds. Only Entra-direct M2M (Azure host + secret + notuseDatabricksOAuthInAzure) uses the dedicatedAzureSpM2m.The kernel runs the in-house / workspace-federated flow natively (workspace-OIDC discovery works against Azure workspaces), and it is cloud-blind — so U2M always uses it (the in-house app +
sql offline_access), for every cloud, never special-cased or rejected. The only Entra-direct flow the kernel implements is SP M2M (azure-sp-m2m, direct Entra client-credentials + tenant auto-discovery). ForAzureSpM2mthe Entra SP creds ride the genericoauthClientId/oauthClientSecret(Thrift convention);azureTenantIdis forwarded when set and auto-discovered by the kernel otherwise.New: an
AzureSpM2mvariant on the native-options union and anisAzureHosthelper.azureWorkspaceResourceId(the management-token / RBAC-only-SP path) is not exposed here yet — a follow-up; the data token authenticates the common workspace-member SP.Tests
Unit (
tests/unit/kernel/auth-m2m.test.ts,auth-u2m.test.ts): Entra-direct M2M →AzureSpM2m(with/without tenant); in-house M2M underuseDatabricksOAuthInAzure: true→OAuthM2m; Azure U2M (with and withoutuseDatabricksOAuthInAzure) → in-houseOAuthU2m. All 315 kernel unit tests pass;prettier --check+eslintclean.E2E (live Azure workspace, native module built from kernel
main@5e5dea9, which includes #282):useDatabricksOAuthInAzure: true, no secret) — full browser authorization-code flow against{host}/oidc/v1/authorize, returned{ one: 1, who: 'e.wang@databricks.com' }. ✅{ one: 1, who: '<sp-app-id>' }. ✅Depends on
AzureSpM2msurface landed on kernelmainvia databricks-sql-kernel#282 (merged; it re-landed Create DBSQLOperation from IDBSQLSession #280's napi + C-ABI changes, which had been mis-merged into the already-merged Upgrade version ofapache-arrowfor security #263 branch and never reachedmain). This PR'sKERNEL_REVnow points at merged kernelmain(5e5dea9), so kernel-e2e builds the native module from amainthat carries the Azure SP surface. Re-verified E2E against that build (M2Mwho=c2108ab0…, U2Mwho=e.wang@…).@databricks/databricks-sql-kernel-* @ 0.2.0pins inpackage.jsonmust bump to a published kernel release that ships Give warning for deprecated clientId param #282 before end users get theAzureSpM2mpath —0.2.0lacks it. That release is tracked by PECOBLR-4194 (the kernel 1.0.0 cut); the pin bump waits on it. Azure U2M rides the existingOAuthU2mand needs neither theKERNEL_REVbump nor a new release.This pull request and its description were written by Isaac.