Skip to content

auth: clear error for PAT profile on SPOG without workspace_id#5341

Merged
simonfaltum merged 6 commits into
mainfrom
simonfaltum/auth-pat-spog-no-wid-error
May 28, 2026
Merged

auth: clear error for PAT profile on SPOG without workspace_id#5341
simonfaltum merged 6 commits into
mainfrom
simonfaltum/auth-pat-spog-no-wid-error

Conversation

@simonfaltum
Copy link
Copy Markdown
Member

Why

Personal access tokens are workspace-scoped. When a PAT profile points at a SPOG host (account-scoped OIDC discovery) without `workspace_id`, the SDK can't add the routing identifier, the request lands on the account-plane where PATs aren't accepted, and the user sees the opaque error "Credential was not sent or was of an unsupported type for this API" from the auth endpoint. Reported in a bug bash.

Reproduced against `db-deco-test.databricks.com`:
```
[spog-pat-no-wid]
host = https://db-deco-test.databricks.com
token = dapi...

$ databricks auth describe --profile spog-pat-no-wid
Unable to authenticate: Credential was not sent or was of an unsupported type for this API. [ReqId: ...]
```

Changes

  • Before: PAT-on-SPOG without `workspace_id` failed with the opaque credentials error.
  • Now: `workspaceClientOrPrompt` detects the combination (`auth_type=pat` + SPOG discovery signal + `workspace_id` empty) before any API call and returns a message that names the profile, explains the routing constraint, and points at the fix: add `workspace_id = ` for the workspace the token was minted in.

`databricks auth describe --profile spog-pat-no-wid` now prints:
```
Unable to authenticate: profile "spog-pat-no-wid" uses PAT auth on a SPOG host but is missing workspace_id; PATs are workspace-scoped, so the request can't be routed. Edit the profile to add workspace_id = matching the workspace the token was minted in
```

Test plan

  • Reproduced against `db-deco-test.databricks.com` with a PAT profile that has no `workspace_id`; saw the opaque "Credential was not sent" error.
  • Same profile with the fix → clear, actionable error message naming the profile and pointing at the fix (verified with `auth describe` and `current-user me`).
  • Existing `spog-deco-aws` (PAT with valid `workspace_id`) still works against the same host — no regression.
  • New unit tests: `TestIsPATOnSPOGWithoutWorkspaceID`, `TestWorkspaceClientOrPromptRejectsPATOnSPOGWithoutWorkspaceID`
  • `go test ./cmd/root/...`, `./task checks`, `./task lint-q`

Personal access tokens are workspace-scoped. When a PAT profile points
at a SPOG host (account-scoped OIDC discovery) without `workspace_id`,
the SDK can't add the routing identifier; the request lands on the
account-plane where PATs aren't accepted, and the user sees the opaque
"Credential was not sent or was of an unsupported type for this API"
error from the auth endpoint.

Detect this combination (auth_type=pat, SPOG discovery signal,
workspace_id empty) up front in `workspaceClientOrPrompt` and return a
message that names the profile, explains the routing constraint, and
points at the fix: add `workspace_id = <id>` for the workspace the
token was minted in.

Co-authored-by: Isaac
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

eng-dev-ecosystem-bot commented May 27, 2026

Commit: 391e98e

Run: 26582843064

GPT review pointed out the existing test seeded AuthType and DiscoveryURL
manually, so it didn't prove the detector still fires when those fields
come from the SDK during NewWorkspaceClient (the realistic flow).

Add a test that writes a .databrickscfg with only `host` and `token`
(matching the bug bash repro), points the host at an httptest server
serving SPOG-style .well-known metadata, and runs through the public
workspaceClientOrPrompt entry point. AuthType is populated by the SDK
credential probe; DiscoveryURL is populated by host metadata
resolution. The detector still catches the case.

Co-authored-by: Isaac
The Windows GitHub runner doesn't have IPv6 configured. httptest.NewServer
tried 127.0.0.1 first and fell through to "[::1]:0" on retry, then
panicked: "listen tcp6 [::1]:0: socket: The requested service provider
could not be loaded or initialized." Build the listener directly with
net.Listen("tcp4", "127.0.0.1:0") and hand it to httptest.

Co-authored-by: Isaac
The fresh Windows failure was a different shape: "listen tcp4 127.0.0.1:0:
socket: The requested service provider could not be loaded or
initialized." Root cause: testutil.CleanupEnvironment calls os.Clearenv,
which on Windows wipes SystemRoot/WINDIR and trips Winsock
initialization in the test process. Subsequent net.Listen — including
httptest's own listener — then fails.

Skip CleanupEnvironment for this test and instead t.Setenv only the
Databricks vars we need to clear. The Windows networking stack stays
intact and httptest.NewServer works without manual listener wiring.

Co-authored-by: Isaac
Comment thread cmd/root/auth.go
Comment thread cmd/root/auth.go Outdated
Two changes from Mihai's review on #5341:

- isPATOnSPOGWithoutWorkspaceID now also matches the legacy "none" sentinel
  (auth.WorkspaceIDNone), matching how libs/databrickscfg/profile/profiler.go
  treats it. Without this, a PAT profile that explicitly set
  workspace_id = none would still hit the opaque "Credential was not sent"
  error from the auth endpoint.
- Reworded the empty-profile branch of patSPOGNoWorkspaceIDError. The old
  phrasing read "to the profile ... to the workspace" once the parenthetical
  was elided. New phrasing keeps the parens grouped with the option that
  introduces them.

Co-authored-by: Isaac
@simonfaltum simonfaltum temporarily deployed to test-trigger-is May 28, 2026 14:59 — with GitHub Actions Inactive
@simonfaltum simonfaltum temporarily deployed to test-trigger-is May 28, 2026 14:59 — with GitHub Actions Inactive
@simonfaltum simonfaltum added this pull request to the merge queue May 28, 2026
Merged via the queue into main with commit aaebbe8 May 28, 2026
23 checks passed
@simonfaltum simonfaltum deleted the simonfaltum/auth-pat-spog-no-wid-error branch May 28, 2026 15:56
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: aaebbe8

Run: 26586096545

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants