Skip to content

auth describe: try both verification endpoints before reporting failure#5512

Open
simonfaltum wants to merge 2 commits into
mainfrom
simonfaltum/describe-try-both
Open

auth describe: try both verification endpoints before reporting failure#5512
simonfaltum wants to merge 2 commits into
mainfrom
simonfaltum/describe-try-both

Conversation

@simonfaltum

Copy link
Copy Markdown
Member

Why

databricks auth describe makes a single verification call based on the client type it resolved (workspace client: CurrentUser.Me, account client: Workspaces.List). If that one call fails, describe prints "Unable to authenticate" even when the credentials are perfectly valid. Two real cases hit this on account console profiles:

  1. A profile with an accounts host plus both account_id and workspace_id (older logins wrote this shape) resolves to a workspace client. The token works, but CurrentUser.Me against the accounts host always fails with HTTP 400, so describe reports failure while databricks auth token succeeds.
  2. A clean account profile used by a non-admin: Workspaces.List is account-admin-only and returns HTTP 403, so describe reports failure even though the login is fine.

Fixes #5479.

Changes

Before, describe gave up after one failed verification call; now it tries the other endpoint first and only reports failure when neither proves the credentials.

Commit 1: if the first verification call fails, describe builds the other client type from the same resolved config (non-interactively, over the same config pointer) and tries its verification call. Account branch falls back to CurrentUser.Me; workspace branch falls back to Workspaces.List when an account_id is configured (account clients require one). If the fallback succeeds, describe reports success with the matching fields (username from Me, account ID for account-side success). If both calls fail, describe reports the first error. Success paths still make exactly one call.

Commit 2 (separable, easy to drop in review): if both checks fail but at least one failure is an API error with HTTP 403, describe reports success. A 403 means the server authenticated the caller and refused the operation; invalid credentials produce a 401, so a 403 proves the login works. This makes describe truthful for non-admin users on account hosts, where Workspaces.List returns 403 and the console cannot serve Me (400). Username stays empty in that case and the output template omits it. The check uses errors.AsType[*apierr.APIError] and the status code, no string matching.

The output templates are unchanged otherwise.

Test plan

  • Unit tests in cmd/auth/describe_test.go: workspace check fails then account check succeeds; account check fails then workspace check succeeds; both fail with non-403 errors reports the first error; no second call without an account_id; both fail with a 403 reports success (account branch, workspace fallback, and workspace branch without fallback)
  • Acceptance test acceptance/cmd/auth/describe/account-host-with-workspace-id: end-to-end reproduction of the issue (workspace client on an account host, Me returns 400, account fallback succeeds)
  • Acceptance test acceptance/cmd/auth/describe/account-permission-denied: non-admin account profile, both checks fail (403 + 400), describe reports success
  • Existing describe unit and acceptance tests pass unchanged (happy paths still make exactly one verification call)
  • ./task fmt-q, ./task lint-q, ./task checks

This pull request and its description were written by Isaac.

getAuthStatus made exactly one verification call based on the client type
MustAnyClient picked (account client -> Workspaces.List, workspace client ->
CurrentUser.Me) and reported "Unable to authenticate" when that call
failed, even when the credentials were valid. Account console profiles that
also carry a workspace_id resolve to a workspace client, and CurrentUser.Me
always fails against the accounts host (#5479).

If the first verification call fails, build the other client type from the
same resolved config (non-interactively, over the same config pointer) and
try its verification call before reporting failure. If both fail, report the
first error. Success paths still make exactly one call.

Co-authored-by: Isaac
A 403 response means the server authenticated the caller and refused the
operation; invalid credentials produce a 401. When both verification
endpoints fail but at least one failure is an HTTP 403 API error, report
success instead of failure.

This makes describe truthful for non-admin users on account hosts, where
Workspaces.List is account-admin-only (returns 403) and the account console
cannot serve CurrentUser.Me (returns 400), so both checks fail even though
the credentials are perfectly valid. Username stays empty in this case; the
output template omits it.

Co-authored-by: Isaac
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/cmd/auth/ - needs approval

Files: cmd/auth/describe.go, cmd/auth/describe_test.go
Suggested: @renaudhartert-db
Also eligible: @hectorcast-db, @parthban-db, @tanmay-db, @Divyansh-db, @tejaskochar-db, @mihaimitrea-db, @chrisst, @rauchy

General files (require maintainer)

9 files changed
Based on git history:

  • @denik -- recent work in ./, cmd/auth/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @renaudhartert-db) can approve all areas.
See OWNERS for ownership rules.

@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Commit: 5d3fa86

Run: 27234296810

Env 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 15 261 930 8:43
🟨​ aws windows 7 15 263 928 15:20
💚​ aws-ucws linux 7 15 357 844 8:58
💚​ aws-ucws windows 7 15 359 842 12:29
💚​ azure linux 1 17 264 928 7:14
💚​ azure windows 1 17 266 926 11:08
💚​ azure-ucws linux 1 17 362 840 11:12
🔄​ azure-ucws windows 2 1 17 362 838 13:02
💚​ gcp linux 1 17 260 931 8:09
💚​ gcp windows 1 17 262 929 11:12
24 interesting tests: 15 SKIP, 7 KNOWN, 2 flaky
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/replace_existing 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_projects/update_display_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/grants/select 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestFsCpFileToDir ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p
🔄​ TestFsCpFileToDir/local_to_uc-volumes 🙈​s 🙈​s ✅​p ✅​p 🙈​s 🙈​s ✅​p 🔄​f 🙈​s 🙈​s
Top 28 slowest tests (at least 2 minutes):
duration env testname
7:05 aws-ucws windows TestAccept
6:16 gcp windows TestAccept
6:16 azure windows TestAccept
6:08 azure-ucws windows TestAccept
4:19 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:17 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:59 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:55 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:33 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:20 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:15 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:12 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:12 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:09 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:06 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:02 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:01 gcp linux TestAccept
2:58 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:58 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:54 azure linux TestAccept
2:53 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:50 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:46 azure-ucws linux TestAccept
2:44 aws-ucws linux TestAccept
2:43 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:41 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:35 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:29 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

auth login writes workspace_id to account-level profile, breaking auth describe

2 participants