Skip to content

Add discovery login via login.databricks.com#4702

Open
simonfaltum wants to merge 12 commits intomainfrom
simonfaltum/login-discovery
Open

Add discovery login via login.databricks.com#4702
simonfaltum wants to merge 12 commits intomainfrom
simonfaltum/login-discovery

Conversation

@simonfaltum
Copy link
Member

Why

When users run databricks auth login without specifying a host, the CLI had no fallback. Users had to know their workspace URL upfront. This adds a discovery flow via login.databricks.com where users authenticate in the browser, select a workspace, and the CLI automatically discovers the workspace URL.

Changes

Before: databricks auth login without --host prompted for a host URL or failed.
Now: databricks auth login without --host opens login.databricks.com in the browser. After the user authenticates and selects a workspace, the CLI saves the profile with the discovered host, account ID, and workspace ID.

Implementation details:

  • shouldUseDiscovery() detects when no host is available from flags, args, or existing profile
  • discoveryLogin() orchestrates the browser-based flow using the SDK's discovery OAuth support
  • IntrospectToken() (in libs/auth) calls the workspace introspection endpoint to extract account/workspace IDs (best-effort, non-fatal on failure)
  • splitScopes() deduplicates scope parsing across login paths
  • Error messages include actionable tips (e.g., "you can specify a workspace directly with: databricks auth login --host ")
  • Discovery dependencies (PersistentAuth, OAuthArgument, IntrospectToken) are injectable via package-level vars for testability

Test plan

  • Unit tests for shouldUseDiscovery (table-driven, 6 cases)
  • Unit tests for splitScopes (empty, single, whitespace, empty entries)
  • Unit tests for IntrospectToken (success, zero workspace ID, HTTP errors, malformed JSON, auth header, endpoint path)
  • Integration test for discoveryLogin with introspection failure (verifies profile is still saved)
  • Integration test for discoveryLogin with introspection success (verifies metadata extraction)
  • go test ./cmd/auth/... ./libs/auth/... passes

simonfaltum and others added 3 commits March 11, 2026 09:43
Add IntrospectToken() which calls /api/2.0/tokens/introspect to extract
account_id and workspace_id from workspace tokens. This will be used by
the discovery login flow to enrich profiles with metadata.

Note: go.mod contains a temporary replace directive pointing to the local
SDK worktree with discovery changes. This will be reverted before the PR.
Extract shouldUseDiscovery() routing function and test it directly with
table-driven tests instead of executing the full cobra command, which
hangs waiting for an OAuth browser callback that never arrives in tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…essages

Extract splitScopes helper to deduplicate scope parsing. Save scopes to
profile in discoveryLogin (was previously dropped). Add actionable error
messages with --host tip for setup failures and config file path for save
failures. Make discoveryLogin testable by introducing package-level vars
for PersistentAuth, OAuthArgument, and IntrospectToken. Fix typo in
introspect test data. Use http.MethodGet constant and drain response body
on error for TCP connection reuse.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Mar 11, 2026

Commit: 85fa40c

Run: 23000947301

Env 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 1 7 268 781 7:03
🟨​ aws windows 7 1 7 270 779 6:00
🔄​ aws-ucws linux 2 7 7 364 696 7:10
🔄​ aws-ucws windows 2 7 7 366 694 5:58
💚​ azure linux 2 9 271 779 6:04
💚​ azure windows 2 9 273 777 5:56
🔄​ azure-ucws linux 2 1 9 369 692 7:46
🔄​ azure-ucws windows 3 1 9 370 690 7:55
💚​ gcp linux 2 9 267 782 5:23
💚​ gcp windows 2 9 269 780 5:23
17 interesting tests: 7 KNOWN, 7 SKIP, 3 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 🔄​f 🔄​f 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R
🙈​ 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/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/recreate 🙈​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/ssh/connect-serverless-gpu 🙈​s 🙈​s 🔄​f 🔄​f 🙈​s 🙈​s 🔄​f 🔄​f 🙈​s 🙈​s
🔄​ TestAccept/ssh/connection 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R
🔄​ TestSyncEnsureRemotePathIsUsableIfRepoExists ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p
Top 20 slowest tests (at least 2 minutes):
duration env testname
4:23 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:12 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:47 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:39 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:26 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:22 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:07 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:02 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:46 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:40 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:38 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:34 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:21 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:15 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:15 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:15 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:15 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:10 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:09 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:02 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

Group same-type function parameters and use strconv.FormatInt instead of
fmt.Sprintf for integer conversion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract repeated discovery fallback tip to discoveryFallbackTip const
- Reuse splitScopes in token.go instead of inline split+trim (also fixes
  missing empty-entry filtering)
- Rename TestDiscoveryLogin_IntrospectionSuccessExtractsMetadata to
  TestIntrospectToken_SuccessExtractsMetadata (it tests IntrospectToken
  directly, not discoveryLogin)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SDKs are not yet ready to handle account_id on workspace profiles
as part of the cache key. Saving it now would break existing auth flows.
Keeping the introspection call so workspace_id is still extracted.

Co-authored-by: Isaac
…mismatch

Reject --configure-cluster and --configure-serverless when discovery login
is used (no host available), since these flags require a known workspace.

Warn when the introspected account_id differs from the existing profile's
account_id to surface potential misconfigurations early.

Also use the discoveryFallbackTip constant instead of hardcoded strings.

Co-authored-by: Isaac
Test that a warning is logged when the introspected account_id differs
from the existing profile's account_id, and that no warning is emitted
when they match.

Co-authored-by: Isaac
- Remove TestIntrospectToken_ServerError (same code path as _HTTPError)
- Merge TestIntrospectToken_VerifyAuthHeader and _VerifyEndpoint into one
- Remove TestIntrospectToken_SuccessExtractsMetadata from login_test.go
  (duplicate of introspect_test.go:TestIntrospectToken_Success)

Co-authored-by: Isaac
Follow the codebase convention of using the context-aware env package
for environment variable access.

Co-authored-by: Isaac
The existing non-discovery login path also used os.Getenv for
DATABRICKS_CONFIG_FILE. Replaced with the context-aware env package
to follow codebase conventions and enable test overrides.

Co-authored-by: Isaac
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.

2 participants