OAuth M2M: token requests ignore the connector's User-Agent (WithUserAgentEntry not threaded into the token exchange)
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 52/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- go
調査の方向性
まず auth/oauth/m2m/m2m.go と internal/client/client.go を読み、token source の作成に使用される context と、BuildUserAgent が適用される箇所に注目します。connector の OAuth M2M パスを追跡し、token リクエストで設定済みの User-Agent が使用されることを確認するとともに、別途記載されている endpoint 解決の制限について auth/oauth/oauth.go を確認します。mintOAuthToken の監査エントリが Go のデフォルトクライアントではなく、設定済みの connector を識別すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
When a connector authenticates with OAuth M2M (WithClientCredentials, or client credentials via DSN), the driver's token requests are issued with Go's default HTTP client, so they reach the workspace as Go-http-client/2.0 instead of the User-Agent configured through WithUserAgentEntry. Query traffic is attributed correctly — only the token exchange is anonymous.
This matters for ISV partner attribution: the Databricks partner program asks integrations to identify themselves via a programmatic User-Agent, and these token grants show up in system.access.audit as an unidentified generic Go client.
Current behavior
Connector configured as:
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(host),
dbsql.WithPort(443),
dbsql.WithHTTPPath(httpPath),
dbsql.WithClientCredentials(clientID, clientSecret),
dbsql.WithUserAgentEntry("MyISV_MyProduct/1.0"),
)
system.access.audit rows for the resulting activity (identifiers redacted):
| service_name | action_name | user_agent |
|---|---|---|
| workspace | workspaceInHouseOAuthClientAuthentication |
Go-http-client/2.0 |
| workspace | mintOAuthToken |
Go-http-client/2.0 |
| accounts | oidcTokenAuthorization |
godatabrickssqlconnector/1.13.0 (MyISV_MyProduct/1.0) |
The Thrift/query path carries the configured entry as expected; the token-mint requests do not.
Root cause
BuildUserAgent(cfg) is applied only to the Thrift HTTP client:
internal/client/client.go—thriftHttpClient.SetHeader("User-Agent", BuildUserAgent(cfg))
The M2M authenticator builds its token source with a hardcoded background context, so a caller has no way to supply an *http.Client — oauth2 takes its HTTP client from the context (oauth2.HTTPClient), and that context never leaves the package:
auth/oauth/m2m/m2m.go(onmain) —GetConfig(context.Background(), ...)andconfig.TokenSource(context.Background())
Because of that, neither WithUserAgentEntry nor WithTransport can influence token requests.
This is adjacent to a limitation already acknowledged in-tree for the endpoint-resolution path (auth/oauth/oauth.go):
NOTE: this client uses the default transport, matching the existing
oidc.NewProviderdiscovery below. A connector-supplied transport / TLS config (WithTransport,WithSkipTLSHostVerify) is not yet threaded into the OAuth endpoint-resolution path; that is a pre-existing limitation, tracked separately.
This report is that same limitation one step further along: the token exchange itself.
Expected behavior
Token requests (and ideally OIDC discovery) carry the same User-Agent as the rest of the connector's traffic — which is what BuildUserAgent's own doc comment states as the intent:
…used by the driver for Thrift, telemetry, and feature-flag requests so all traffic from a single connection is attributable to the same identifier in access logs.
Possible directions
- Thread the connector's HTTP client/context into the authenticator — e.g. have the connector pass an
*http.Clientbuilt with the driver's transport + User-Agent, and create the token source withcontext.WithValue(ctx, oauth2.HTTPClient, client). - Or expose an option to supply the token-exchange HTTP client, so callers can set headers without re-implementing the M2M flow.
We verified direction 1 works: injecting an *http.Client whose RoundTripper sets the User-Agent into the token source makes every mintOAuthToken audit row correctly attributed. We did not keep that as a workaround — replacing the built-in authenticator with an application-side copy of the credential flow would risk drifting from upstream on every release, which is exactly why we'd prefer this handled in the driver.
Environment
databricks-sql-gov1.13.0 — code path verified unchanged in v1.14.0 and onmain- Auth: OAuth M2M (client credentials, Databricks-managed service principal)
- Go 1.25, Linux
Happy to open a PR for direction 1 if you'd like it contributed.
- 主要言語
- Go
- スター
- 53
- フォーク
- 66
- 平均マージ
- 7時間 57分
- マージ済み PR(30日)
- 16
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
databricks/databricks-sql-go のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
databricks/databricks-sql-go#476 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
databricks/databricks-sql-go#481 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
databricks/databricks-sql-go#480 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
databricks/databricks-sql-go#475 · コメント 1 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 65/100
databricks/databricks-sql-go#474 ·
databricks/databricks-sql-go の issue をすべて見る
似ている issue
-
bug github_actions
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
registrystack/registry-stack#1393 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
JakeChampion/lang#10213 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
oasisprotocol/oasis-sdk#2523 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100