Skip to content

Honor [__settings__].default_profile in api, bundle, and auth token#5214

Open
janniklasrose wants to merge 7 commits into
mainfrom
janniklasrose/auth-default-profile
Open

Honor [__settings__].default_profile in api, bundle, and auth token#5214
janniklasrose wants to merge 7 commits into
mainfrom
janniklasrose/auth-default-profile

Conversation

@janniklasrose
Copy link
Copy Markdown
Contributor

Changes

[__settings__].default_profile is a CLI-level fallback for the active
profile that the SDK does not know about. Until now it was consulted only
on the MustWorkspaceClient / MustAccountClient / MustAnyClient
paths. Several command surfaces silently ignored it:

  • databricks api {get,post,...} built its own *config.Config and only
    honored --profile.
  • Bundle commands (databricks bundle, databricks pipelines) read the
    profile only from --profile / DATABRICKS_CONFIG_PROFILE.
  • databricks auth token (no positional, no flags, no env) jumped
    straight to the interactive picker.

This PR promotes the resolution logic to databrickscfg.ResolveDefaultProfile
and applies it from each affected command:

  • cmd/api/api.go: --profile flag → DATABRICKS_CONFIG_PROFILE env →
    default_profile, then hand off to the SDK.
  • cmd/root/bundle.go (configureProfile): falls back to
    default_profile only when the bundle declares no workspace.host and
    no workspace.profile. The host-empty guard preserves SDK host-based
    resolution when the bundle pins its own host.
  • cmd/auth/token.go (resolveNoArgsToken): inserts a Step 2.5 between
    the env-var check and the interactive picker. If the named profile
    doesn't exist, falls through to the picker (advisory, not fatal).

Why

Users reasonably expect "I set my default to tmp — every CLI invocation
should default to tmp." The previous behavior was inconsistent across
command surfaces and surprised users.

The bundle host-empty guard is the only subtle bit worth flagging:
applying default_profile before the SDK sees a bundle's pinned
workspace.host could silently route the user to a profile pointing at a
different host. The guard lets the existing multi-profile-match path
(resolveProfileAmbiguity) handle host conflicts as before.

Tests

  • libs/databrickscfg/ops_test.go: matrix tests for ResolveDefaultProfile
    (file present/absent, settings present/absent, parse error, reserved
    __settings__ self-reference, default home-file lookup).

  • cmd/root/bundle_test.go: four TestBundleConfigureWithDefaultProfile_*
    unit tests covering the positive case, --profile override,
    DATABRICKS_CONFIG_PROFILE override, and the bundle-host-wins guard.

  • Acceptance tests:

    • acceptance/cmd/api/default-profile/
    • acceptance/auth/bundle_default_profile/ (with a bundle-with-host
      sub-case)
    • acceptance/cmd/auth/token/default-profile/ (with a missing-default
      fall-through case)

    Each new acceptance test covers the positive case (default_profile
    honored) and the negative case (--profile overrides).

This PR was written by Claude Code.

@janniklasrose janniklasrose requested a review from simonfaltum May 8, 2026 11:23
@janniklasrose janniklasrose force-pushed the janniklasrose/auth-default-profile branch from b86d7bb to a606de7 Compare May 8, 2026 12:48
Copy link
Copy Markdown
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Sync'ed with Jan on a nit comment on slack

The CLI-only default_profile setting was previously consulted only on
MustWorkspaceClient / MustAccountClient paths. `databricks api`, bundle
commands without an explicit workspace.host, and `databricks auth token`
all silently ignored it.

Promote the resolution logic to a shared helper
(databrickscfg.ResolveDefaultProfile) and apply it from each affected
command. For bundle commands, fall back to default_profile only when
the bundle does not pin its own workspace.host or workspace.profile —
otherwise applying it could silently route the user to a profile that
points at a different host than the bundle expects.

Co-authored-by: Isaac
- Changelog now notes that DATABRICKS_HOST still takes precedence over
  default_profile for `databricks auth token` (matches resolveNoArgsToken
  Step 1).
- Switch the auth token acceptance fixture from
  https://myworkspace.cloud.databricks.com to https://myworkspace.test
  per the repo's RFC 2606 convention; same for the secondary "other"
  profile in that file. Avoids reintroducing DNS/network flakiness.

Co-authored-by: Isaac
When a bundle declares workspace.profile but no workspace.host and the
user has [__settings__].default_profile set, the bundle's pinned profile
must win. configureProfile's guard (Workspace.Profile == "") covers this
case but had no test — verified by temporarily removing the guard, which
flipped the asserted profile from PROFILE-2 to PROFILE-1.

Co-authored-by: Isaac
The previous unit test for the Workspace.Profile == "" guard sat
alongside other configureProfile unit tests, but per
.agent/rules/testing.md, cmd/... behavior is a strong candidate for
acceptance tests, and the existing acceptance/auth/bundle_default_profile/
already covers the related host-empty guard end-to-end. Extending it
keeps the related cases together.

The new sub-case spawns a child bundle directory with workspace.profile
pinned and asserts the bundle's profile (not [__settings__].default_profile)
is what gets used.

Co-authored-by: Isaac
sethome exported HOME (and USERPROFILE) as the relative path the caller
passed in (typically "./home"). The SDK expands `~/.databrickscfg`
against $HOME at lookup time, so the moment a test cd's into a child
directory, the cfg "disappears": helpers like
databrickscfg.GetConfiguredDefaultProfile silently return "" because
the relative path no longer points at a real file. That made it easy
to write tests that look like they exercise default_profile resolution
but actually only succeed because the cfg lookup short-circuits.

Resolve $1 to an absolute path with `cd && pwd` (portable on
macOS/Linux/Windows-MSYS) before exporting. With this fix, the
acceptance/auth/bundle_default_profile "workspace.profile pinned"
sub-case correctly fails when the Workspace.Profile == "" guard in
cmd/root/bundle.go configureProfile is removed; previously it passed
either way.

Output for the same directory's "Bundle with workspace.host" sub-case
also changes: with the cfg now reachable from the bundle subdir, the
SDK's host-based lookup finds the matching profile and validate
succeeds instead of failing with "default auth: cannot configure
default credentials".

Co-authored-by: Isaac
@janniklasrose janniklasrose force-pushed the janniklasrose/auth-default-profile branch from 8351385 to 81d9297 Compare May 18, 2026 10:45
81d9297 changed sethome to export an absolute HOME so the SDK can
locate ~/.databrickscfg after a test cd's. The SDK now reports paths
relative to the absolute HOME, which surfaces in user-visible output as
[TEST_TMP_DIR]/home/.databrickscfg (or [HOME]/.zshrc where the test
registers a HOME replacement). The four committed outputs predated the
fix and still expected the relative ./home form; regenerated with
./task test-update.

Co-authored-by: Isaac
The previous fix resolved $home with `cd && pwd` to give HOME and
USERPROFILE an absolute path. On Git Bash (MSYS), plain `pwd` returns
Unix-style /c/... paths that the native Windows Go binary can't open,
so the SDK silently fails to load ~/.databrickscfg and tests like
cmd/api/default-profile (no auth resolves) and cmd/api/workspace-id-none
(profile not read; SDK back-fills WorkspaceID from host metadata) fail
on Windows only.

Use `pwd -W` for USERPROFILE on MSYS/Cygwin to emit the mixed C:/...
form Windows file APIs accept. HOME keeps the Unix-style path bash
itself wants.

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