Skip to content

Commit 50ae2a8

Browse files
committed
feat(kernel): forward identity federation client ID
1 parent 5574e01 commit 50ae2a8

6 files changed

Lines changed: 37 additions & 21 deletions

File tree

KERNEL_REV

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7ffb30d533c08651ca707b8dd13894c9e01cb68e
1+
eff8950428f4e6cc9975c663ec919f334962f7d0

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ Notes:
5252
`cp310-abi3`). On older interpreters the `[kernel]` extra installs
5353
nothing and `use_kernel=True` raises an `ImportError`.
5454
- The extra also pulls in PyArrow, which the kernel result path requires.
55-
- Authentication supports PAT (`access_token`), OAuth M2M, and OAuth U2M.
55+
- Authentication supports PAT (`access_token`), OAuth M2M/U2M, and SP-wide
56+
workload identity federation (`identity_federation_client_id`).
5657

5758

5859
```bash

src/databricks/sql/backend/kernel/auth_bridge.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
kernel's ``auth_type='oauth-u2m'`` and the kernel runs the browser
2222
flow itself.
2323
24+
``identity_federation_client_id`` is forwarded with whichever auth shape
25+
wins resolution. It selects mandatory SP-wide workload-identity token
26+
exchange in the kernel; omitting it preserves BYOT / account-wide behavior.
27+
2428
A user-supplied custom ``credentials_provider`` is **rejected** on the
2529
kernel path with ``NotSupportedError``: it's an opaque token source
2630
with no extractable raw credentials, so the kernel can't own the
@@ -125,10 +129,10 @@ def kernel_auth_kwargs(
125129
126130
``auth_options`` carries the raw connect() kwargs relevant to auth
127131
(``auth_type``, ``oauth_client_id``, ``oauth_client_secret``,
128-
``oauth_redirect_port``, ``credentials_provider``). They drive the
129-
OAuth decisions because the OAuth secret is consumed during
130-
``AuthProvider`` construction and can't be read back off the built
131-
provider.
132+
``oauth_redirect_port``, ``credentials_provider``,
133+
``identity_federation_client_id``). They drive the OAuth decisions
134+
because the OAuth secret is consumed during ``AuthProvider``
135+
construction and can't be read back off the built provider.
132136
133137
Resolution order:
134138
@@ -161,6 +165,7 @@ def kernel_auth_kwargs(
161165

162166
client_id = opts.get("oauth_client_id")
163167
client_secret = opts.get("oauth_client_secret")
168+
federation_client_id = opts.get("identity_federation_client_id")
164169
auth_type = opts.get("auth_type")
165170
has_m2m = bool(client_id and client_secret)
166171

@@ -191,6 +196,8 @@ def kernel_auth_kwargs(
191196
scopes = _normalize_scopes(opts.get("oauth_scopes"))
192197
if scopes is not None:
193198
kwargs["oauth_scopes"] = scopes
199+
if federation_client_id:
200+
kwargs["identity_federation_client_id"] = federation_client_id
194201
return kwargs
195202

196203
# 2. PAT (including TokenFederationProvider-wrapped PAT).
@@ -201,7 +208,10 @@ def kernel_auth_kwargs(
201208
"PAT auth provider did not produce a Bearer Authorization "
202209
"header; cannot route through the kernel's PAT path"
203210
)
204-
return {"auth_type": "pat", "access_token": token}
211+
kwargs = {"auth_type": "pat", "access_token": token}
212+
if federation_client_id:
213+
kwargs["identity_federation_client_id"] = federation_client_id
214+
return kwargs
205215

206216
# 3. OAuth U2M — browser authorization-code flow; the kernel runs it.
207217
if auth_type in ("databricks-oauth", "azure-oauth"):
@@ -214,6 +224,8 @@ def kernel_auth_kwargs(
214224
scopes = _normalize_scopes(opts.get("oauth_scopes"))
215225
if scopes is not None:
216226
kwargs["oauth_scopes"] = scopes
227+
if federation_client_id:
228+
kwargs["identity_federation_client_id"] = federation_client_id
217229
return kwargs
218230

219231
# 4. Custom credentials_provider — the connector's primary M2M path

src/databricks/sql/backend/kernel/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ def __init__(
206206
# Forwarded to the kernel Session in ``open_session``.
207207
self._http_headers = http_headers or []
208208
# Raw auth-relevant connect() kwargs (auth_type,
209-
# oauth_client_id/secret, redirect port, credentials_provider).
209+
# oauth_client_id/secret, redirect port, credentials_provider,
210+
# identity_federation_client_id).
210211
# The kernel auth bridge needs these to build OAuth kwargs — the
211212
# OAuth secret is consumed during ``auth_provider`` construction
212213
# and isn't recoverable from the built provider.

src/databricks/sql/client.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,11 @@ def __init__(
119119
the Thrift backend.
120120
:param use_kernel: `bool`, optional (default is False)
121121
Route the connection through the Rust kernel
122-
(``databricks-sql-kernel`` via PyO3). Requires the
123-
kernel extension to be installed separately — the
124-
wheel is not yet published on PyPI, so today the
125-
only supported install path is a local
126-
``maturin develop --release`` build from the
127-
``databricks-sql-kernel`` repo into the same venv.
128-
Raises ``ImportError`` if the extension is not
129-
available. In active development — PAT auth only
130-
today; OAuth / federation / external credentials
131-
and native parameter binding land in follow-ups.
132-
Mutually exclusive with ``use_sea``.
122+
(``databricks-sql-kernel`` via PyO3). Install the
123+
connector's ``kernel`` extra to include the extension.
124+
Supports PAT, OAuth M2M/U2M, and workload identity
125+
federation; custom credentials providers are not
126+
supported. Mutually exclusive with ``use_sea``.
133127
:param use_hybrid_disposition: `bool`, optional (default is False)
134128
Use the hybrid disposition instead of the inline disposition.
135129
:param server_hostname: Databricks instance host name.
@@ -170,6 +164,10 @@ def __init__(
170164
port of the oauth redirect uri (localhost). This is required when custom oauth client_id
171165
`oauth_client_id` is set
172166
167+
identity_federation_client_id: `str`, optional
168+
Service-principal client ID for mandatory SP-wide workload identity
169+
token exchange. Supported by both the default and kernel backends.
170+
173171
user_agent_entry: `str`, optional
174172
A custom tag to append to the User-Agent header. This is typically used by partners to identify their applications.. If not specified, it will use the default user agent PyDatabricksSqlConnector
175173

src/databricks/sql/session.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,19 @@ def _create_backend(
164164
# original credentials. On this path we intentionally did
165165
# NOT build the connector's own OAuth provider (see __init__
166166
# above), so these raw kwargs are the only source of the
167-
# OAuth client id/secret. These are kernel-only; the Thrift
168-
# / SEA backends are unaffected.
167+
# OAuth client id/secret and optional federation client id.
168+
# These are kernel-only; the Thrift / SEA backends are
169+
# unaffected.
169170
kernel_auth_options = {
170171
"auth_type": kwargs.get("auth_type"),
171172
"oauth_client_id": kwargs.get("oauth_client_id"),
172173
"oauth_client_secret": kwargs.get("oauth_client_secret"),
173174
"oauth_redirect_port": kwargs.get("oauth_redirect_port"),
174175
"oauth_scopes": kwargs.get("oauth_scopes"),
175176
"credentials_provider": kwargs.get("credentials_provider"),
177+
"identity_federation_client_id": kwargs.get(
178+
"identity_federation_client_id"
179+
),
176180
}
177181
# Forward the connector's retry-tuning kwargs so the kernel's
178182
# own retry policy honours them (the kernel owns the retry

0 commit comments

Comments
 (0)