OAuth M2M fails with scoped secrets because all-apis is always requested

Open Beginner friendly
#476 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
go

Research direction

Start with NewAuthenticatorWithScopes and GetScopes, where the issue reports that all-apis is appended unconditionally. Reproduce the scoped-secret flow with the provided SQL scope and verify that a nonempty caller-provided scope reaches the token request without requiring all-apis; confirm that the SQL connection succeeds.

Written by the indexing model from the issue text.

Description

Hi team! We are having trouble with service principal authentication following the introduction of scoped OAuth secrets. The M2M authenticator in databricks-sql-go unconditionally requests all-apis, but all-apis is no longer the default in the UI.

Steps to reproduce
  1. Create a Databricks service principal with access to a SQL warehouse.
  2. Generate an OAuth secret restricted to the sql scope.
  3. Verify the credential directly:
curl --request POST \
  --url "https://<workspace-host>/oidc/v1/token" \
  --user "<client-id>:<client-secret>" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=sql"

This succeeds and returns a token with scope sql.

  1. Connect using the Go driver's M2M authenticator:
authenticator := m2m.NewAuthenticator(
	clientID,
	clientSecret,
	workspaceHost,
)

connector, err := dbsql.NewConnector(
	dbsql.WithServerHostname(workspaceHost),
	dbsql.WithPort(443),
	dbsql.WithHTTPPath(warehouseHTTPPath),
	dbsql.WithAuthenticator(authenticator),
)
if err != nil {
	return err
}

db := sql.OpenDB(connector)
defer db.Close()

var result int
err = db.QueryRowContext(context.Background(), "SELECT 1").Scan(&result)

The connection fails before opening the SQL session:

oauth2: "access_denied" "Scopes 'all-apis' are not assigned to the client <redacted>"
Root cause

NewAuthenticatorWithScopes calls GetScopes, which always appends all-apis:

func GetScopes(hostName string, scopes []string) []string {
	if !oauth.HasScope(scopes, "all-apis") {
		scopes = append(scopes, "all-apis")
	}
	return scopes
}

The code comments say the behavior matches the underlying kernel unconditionally requiring all-apis.

Suggested fix: Investigate whether NewAuthenticatorWithScopes can pass through nonempty caller-provided scopes.

Thank you!

Dominant language
Go
Stars
53
Forks
66
Avg merge
1d 1h
Merged PRs (30d)
21

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from databricks/databricks-sql-go

All issues in databricks/databricks-sql-go

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.