Repository navigation
fix: discover the Azure tenant for Thrift service-principal M2M - #606
vuanhphung wants to merge 3 commits into
Conversation
Thrift Azure service-principal M2M without `azureTenantId` sent the client-credentials grant to the `/organizations` authority, which Entra rejects for that grant, so the connection could not authenticate. Discover the tenant from the workspace's `/aad/auth` redirect first, as the kernel backend and the Python connector do. An explicit `azureTenantId` skips discovery, and U2M is unchanged. Co-authored-by: Isaac <no-reply@databricks.com> Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
There was a problem hiding this comment.
Verdict: 1 Low
Looks good, with one low concern: network failures during tenant discovery reach the caller without the azureTenantId hint. Follow-up (this is not caused by the PR): discovery accepts the US Gov and China login hosts, but getOIDCConfigUrl always builds the URL on login.microsoftonline.com and drops the discovered authority host. Sovereign-cloud M2M therefore still doesn't work, and the same is true with an explicit azureTenantId.
A network failure during `/aad/auth` discovery (DNS, proxy or TLS error, timeout) escaped as a raw node-fetch error without the hint that setting `azureTenantId` avoids the request. Wrap it in an AuthenticationError that names only the error code or type. Co-authored-by: Isaac <no-reply@databricks.com> Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
|
On the sovereign-cloud follow-up in the review summary: agreed, and it's left out of this PR on purpose. |
There was a problem hiding this comment.
Verdict: 1 Low · 1 Nit
Looks good, with 2 low concerns: the redirect body is never drained on the keep-alive agent, and the tests don't check that the agent is passed to discovery. The discovery logic, host-suffix validation, credential-safe error messages (only code/type, as driver-pitfalls.md requires) and caching are correct. Follow-up, not caused by this PR: getOIDCConfigUrl always uses login.microsoftonline.com, so a tenant discovered from a US Gov or China redirect is still looked up on the public authority. An explicit azureTenantId has the same limitation today. Nit: the existing test 'falls back to /organizations/ when azureTenantId is not set' now only describes getOIDCConfigUrl before discovery runs, not what M2M actually does.
Other findings
- ⚪ Nit — The PR says discovery goes "through the connection's agent so
proxyand TLS options apply". The wiring test only checksdiscoverStub.firstCall.args[0](the host), not thatargs[1]is the agent fromconnectionProvider.getAgent('https:'). If someone later drops theagentargument, the request would quietly skip proxy/TLS config and every unit test would still pass. Asserting the second argument against the stub provider's https agent would lock in that contract.
The redirect response body was never read, so on the connection's keep-alive agent a large body could hold the socket. Drain it before reading the Location header. Also assert that discovery uses the connection's https agent (proxy and TLS options), and rename the pre-discovery tests. Co-authored-by: Isaac <no-reply@databricks.com> Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
|
Review-body nits, both addressed in c4a9c21:
The sovereign-cloud follow-up is out of scope, as in my earlier comment. |
Problem
On the Thrift backend, Azure service-principal M2M (
authType: 'databricks-oauth'withoauthClientSecreton an Azure host) fails whenazureTenantIdis omitted, even though the option is optional.AzureOAuthManager.getOIDCConfigUrlfalls back to the multi-tenant/organizationsauthority (OAuthManager.ts:292-296), and Entra rejects the client-credentials grant there. The kernel backend (useKernel: true) and the Python connector discover the tenant from the workspace's/aad/authredirect, so the same credentials work on SEA but not on Thrift.Found by databricks-driver-test AUTH-012 (Azure SP M2M with the tenant auto-discovered), which now runs on Node.js Thrift as an xfail tripwire.
Change
For M2M without
azureTenantId,AzureOAuthManagernow reads the tenant from the first{host}/aad/authredirect (login.microsoftonline.com/{tenant}/...) before OIDC discovery, through the connection's agent soproxyand TLS options apply. The redirect host must be a Microsoft login authority (commercial, US Gov or China), matched by suffix, as in the kernel'sdiscover_tenant. A discovery failure is surfaced with a hint to passazureTenantId. An explicitazureTenantIdskips discovery, and U2M keeps/organizations.Verification
AzureOAuthManagerwiring (including the agent passed to discovery).npm test(1764 passing),npm run lint,npm run prettier.main, AUTH-012 Thrift fails withAADSTS50059: No tenant-identifying information found(run).XPASS: tenant-omitted M2M connects, opens one session, runsSELECT 1and sends no Azure management headers. AUTH-013 (explicit tenant) and the rest of the suite pass on Thrift and SEA (run). The later commits only change the error raised when the discovery request fails and drain the redirect body.This pull request and its description were written by Isaac.