Skip to content

Add databricks auth switch command for setting the default profile - #4651

Merged
simonfaltum merged 26 commits into
mainfrom
simonfaltum/auth-switch
Mar 13, 2026
Merged

Add databricks auth switch command for setting the default profile#4651
simonfaltum merged 26 commits into
mainfrom
simonfaltum/auth-switch

Conversation

@simonfaltum

@simonfaltumsimonfaltum commented Mar 4, 2026

Copy link
Copy Markdown
Member

Why

There is no way to set which profile is the active default without renaming it to [DEFAULT]. Users with multiple profiles need a simple way to switch between them.

Changes

Before: no mechanism to designate a default profile. Users had to rename sections in ~/.databrickscfg or always pass --profile.

Now: databricks auth switch lets users select a named profile as the default. The choice is stored in a [__settings__] section with a default_profile key. auth profiles shows a (Default) marker, and auth describe shows the resolved default name.

Why [__settings__] instead of a top-level key?

INI files place keys that appear before any section header into the [DEFAULT] section. The CLI already uses [DEFAULT] as a regular profile section (with host, token, etc.), so adding default_profile there would mix settings with profile credentials, and the profiles command would try to interpret [DEFAULT] as a profile containing that key. A dedicated [__settings__] section avoids this collision and is silently ignored by older SDKs (no host key means it is skipped in profile iteration).

Implementation

  • libs/databrickscfg/ops.go: GetDefaultProfile/GetDefaultProfileFrom with fallback resolution (explicit setting, single-profile auto-default, legacy DEFAULT section). SetDefaultProfile to write the setting. Shared backupAndSaveConfigFile and resolveConfigFilePath helpers to deduplicate existing code.
  • cmd/auth/switch.go: new command with --profile flag (non-interactive) and interactive profile picker showing the current default.
  • cmd/auth/profiles.go: (Default) marker in output and default field in JSON.
  • cmd/auth/describe.go: shows resolved default profile name, e.g. profile: default (my-workspace).
  • cmd/auth/login.go + token.go: auto-set default when creating the very first profile.

Resolution wiring (making the CLI actually use default_profile when no --profile is given) is out of scope. That will be a follow-up change touching cmd/root/auth.go and the bundle config path.

Test plan

  • Unit tests for GetDefaultProfile, GetDefaultProfileFrom, SetDefaultProfile (table-driven, covering: explicit setting, single-profile fallback, DEFAULT fallback, no file, round-trip with SaveToProfile)
  • Unit tests for auth switch command (with --profile, profile not found, non-interactive error, settings section written correctly)
  • Unit tests for hasNoProfiles (fresh machine / ErrNoConfiguration, empty file, existing profiles)
  • Unit test for (Default) marker in auth profiles
  • GetDefaultProfile does not create the config file as a side effect (asserted in test)
  • make checks and make lintfull pass
  • Manual: databricks auth switch --profile <name>, verify ~/.databrickscfg has [__settings__] section
  • Manual: databricks auth profiles shows (Default) marker
  • Manual: databricks auth switch interactive picker shows current default

@simonfaltum
simonfaltum marked this pull request as ready for review March 4, 2026 09:31
@eng-dev-ecosystem-bot

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

Copy link
Copy Markdown
Collaborator

Commit: 55d8373

Run: 22915098021

Env🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
💚​aws linux872687836:32
💚​aws windows872707815:52
💚​aws-ucws linux873656987:10
🔄​aws-ucws windows2773666966:12
🔄​azure linux3192697818:03
💚​azure windows292737794:14
🔄​azure-ucws linux2193696948:00
🔄​azure-ucws windows2193716926:33
💚​gcp linux292677845:22
🔄​gcp windows3192677828:58
18 interesting tests: 7 SKIP, 6 RECOVERED, 5 flaky
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
🔄​TestAccept💚​R💚​R💚​R🔄​f🔄​f💚​R🔄​f💚​R💚​R🔄​f
🔄​TestAccept/bundle/resources/apps/inline_config✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p🔄​f
🔄​TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p🔄​f
🙈​TestAccept/bundle/resources/permissions🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions💚​R💚​R💚​R💚​R🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct💚​R💚​R💚​R💚​R
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform💚​R💚​R💚​R💚​R
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions💚​R💚​R💚​R💚​R🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct💚​R💚​R💚​R💚​R
💚​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform💚​R💚​R💚​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✅​p🔄​f🙈​s🙈​s🔄​f🔄​f🙈​s🙈​s
🔄​TestAccept/ssh/connection💚​R💚​R💚​R💚​R💚​R💚​R💚​R🔄​f💚​R💚​R
Top 22 slowest tests (at least 2 minutes):
durationenvtestname
4:24aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:13azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:00aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:56aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:51azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:45aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:42aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:38aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:35aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:15gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:13gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:13aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:08gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:07gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:44azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:24azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:22azure linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:15azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:15azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:10azure linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:10aws-ucws linuxTestAccept/ssh/connect-serverless-gpu
2:09aws windowsTestSecretsPutSecretStringValue

simonfaltumand others added 8 commits March 6, 2026 21:35
Introduce a [databricks-cli-settings] section in ~/.databrickscfg with a
default_profile key. The new `auth switch` command lets users select a
named profile as the default, and `auth profiles` shows a (Default) marker
next to it.
The default profile resolution uses fallback logic: explicit setting first,
then single-profile auto-default, then legacy DEFAULT section.
The login flow auto-sets the default when creating the very first profile
so new users get a working default out of the box.
Resolution wiring (making the CLI use default_profile when no --profile
is given) is out of scope for this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
hasNoProfiles now treats ErrNoConfiguration (no config file) as "no
profiles" instead of returning false. This ensures the first profile
created on a fresh machine is auto-set as the default.
GetDefaultProfile now uses a read-only file loader (loadConfigFile)
that returns ("", nil) when the file doesn't exist, instead of
loadOrCreateConfigFile which would create the file as a side effect.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
auth switch now declares cobra.NoArgs so positional arguments produce
a clear error instead of being silently ignored.
The interactive profile picker label now shows the current default
profile name (e.g. "Current default: e2-dogfood. Select a new default")
so users know what they're changing from.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When no --profile flag is set, auth describe now shows the resolved
default profile name in parentheses, e.g. "profile: default (e2-dogfood)"
instead of just "profile: default".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rtion
Extract resolveConfigFilePath helper to share tilde expansion logic
between loadConfigFile and loadOrCreateConfigFile.
In switch.go interactive path, use the already-loaded config file from
the profiler to resolve the current default instead of re-reading from disk.
Remove duplicate assertion in TestProfilesDefaultMarker.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The auth login acceptance tests now expect the [__databricks-settings__]
section in out.databrickscfg and (Default) marker in auth profiles output,
since first-profile login auto-sets the default.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When no --profile flag or DATABRICKS_CONFIG_PROFILE env var is set,
the CLI now honors the explicit default_profile setting from
[__databricks-settings__] before the SDK falls back to the DEFAULT
section.
Also aligns auth describe to only show the configured default (not
fallback heuristics like single-profile auto-default).
@simonfaltum
simonfaltumforce-pushed the simonfaltum/auth-switch branch from fd6b688 to 3f72a7fCompareMarch 6, 2026 20:37
Comment threadcmd/auth/login.go Outdated
1. Extract "default_profile" to a named constant (defaultProfileKey).
2. Simplify GetConfiguredDefaultProfileFrom using Section().Key()
which returns an empty string when the section/key is missing,
removing the need for explicit error handling.
3. Rename profile -> displayProfile in auth describe to clarify
it is only used for display, not as a real profile name downstream.
4. Replace os.Getenv("DATABRICKS_CONFIG_FILE") with env.Get(ctx, ...)
in login.go, token.go, switch.go, and configure.go for testability.
5. Remove existingProfile == nil guard from isOnlyProfile in login.go.
Re-logging into the only profile should still set it as default.
6. Apply default_profile resolution in MustAccountClient, matching
the existing logic in MustWorkspaceClient.
7. Add acceptance tests:
- auth switch nominal: verifies [__settings__] is created, retained,
and updated across two consecutive switches.
- auth describe default-profile: verifies auth describe picks up
the configured default profile without --profile flag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@eng-dev-ecosystem-bot

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

Copy link
Copy Markdown
Collaborator

Commit: 277512f

Run: 23046262953

Env🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
🟨​aws linux7172687877:12
🟨​aws windows7172707856:26
🔄​aws-ucws linux2773647028:02
🔄​aws-ucws windows2773667007:54
💚​azure linux292717854:54
💚​azure windows292737837:06
🔄​azure-ucws linux21936969810:33
🔄​azure-ucws windows2193716969:08
💚​gcp linux292677886:27
💚​gcp windows292697866:10
16 interesting tests: 7 KNOWN, 7 SKIP, 2 flaky
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
🟨​TestAccept🟨​K🟨​K🔄​f💚​R💚​R💚​R💚​R💚​R💚​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🔄​f💚​R💚​R🔄​f🔄​f💚​R💚​R
Top 19 slowest tests (at least 2 minutes):
durationenvtestname
5:06azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:14gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:12gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:57aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:48aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:22aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:22azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:19aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:19azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:16aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:15aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:11gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:09gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:08azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:42azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:41aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:40aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:27azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:17azure linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform

Comment threadacceptance/cmd/auth/describe/default-profile/script
Comment threadacceptance/cmd/auth/describe/default-profile/output.txt
Comment threadacceptance/cmd/auth/switch/nominal/script Outdated
Comment threadcmd/auth/describe.go Outdated
}
}
details.Configuration["profile"] = &config.AttrConfig{Value: profile, Source: config.Source{Type: config.SourceDynamicConfig}}
details.Configuration["profile"] = &config.AttrConfig{Value: displayProfile, Source: config.Source{Type: config.SourceDynamicConfig}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this code path in use at all?

If the default profile is resolved earlier in the chain, details.Configuration["profile"] will be set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: this diff no longer changes anything.

Comment threadcmd/auth/switch.go Outdated
Comment threadcmd/auth/token.go Outdated
Comment threadcmd/root/auth.go
1. Extract auto-set-default helpers (IsFirstProfile, SetDefaultProfileQuietly)
in libs/databrickscfg/ops.go to consolidate the duplicated "set default on
first profile" pattern across login.go, token.go, and configure.go.
2. Extract resolveDefaultProfile helper in cmd/root/auth.go to deduplicate
the identical default profile resolution in MustWorkspaceClient and
MustAccountClient.
3. Remove dead GetConfiguredDefaultProfile call in cmd/auth/describe.go.
When a default_profile is configured, it is already resolved by
MustWorkspaceClient/MustAccountClient before getAuthDetails runs.
4. Eliminate double config file load in cmd/auth/switch.go by using
GetDefaultProfile directly instead of Get + GetDefaultProfileFrom.
5. Use grep in switch acceptance test to show only __settings__ section
instead of dumping the full config.
Comment threadcmd/auth/describe.go Outdated
}
}
details.Configuration["profile"] = &config.AttrConfig{Value: profile, Source: config.Source{Type: config.SourceDynamicConfig}}
details.Configuration["profile"] = &config.AttrConfig{Value: displayProfile, Source: config.Source{Type: config.SourceDynamicConfig}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: this diff no longer changes anything.

Comment threadcmd/auth/login.go Outdated
- Remove initial config dump from acceptance test (use grep for __settings__)
- Revert no-op describe.go diff (variable rename was cosmetic)
- Move auto-default-profile logic into SaveToProfile, removing duplicate
isFirst+SetDefaultProfileQuietly pattern from login.go, token.go, and
configure.go
- Remove now-unused IsFirstProfile and SetDefaultProfileQuietly exports
- Log warning in resolveDefaultProfile when config file load fails
Co-authored-by: Isaac
Resolved conflicts in cmd/root/auth.go and libs/databrickscfg/ops.go.
Consolidated duplicate backup/save functions into writeConfigFile.
Kept auth-switch's resolveDefaultProfile and auto-set-default logic,
and main's DeleteProfile and SelectProfile.
Co-authored-by: Isaac
When `auth logout --delete` removes a profile that is the configured
default (in [__settings__].default_profile), the pointer is now cleared
so that the CLI does not reference a non-existent profile.
Adds ClearDefaultProfile to databrickscfg/ops.go, unit tests, and an
acceptance test verifying the behavior for both default and non-default
profile deletions.
Co-authored-by: Isaac
@simonfaltum
simonfaltum added this pull request to the merge queueMar 13, 2026
Merged via the queue into main with commit f121e12Mar 13, 2026
18 checks passed
@simonfaltum
simonfaltum deleted the simonfaltum/auth-switch branch March 13, 2026 11:12
rauchy pushed a commit that referenced this pull request Mar 17, 2026
…4651)
## Why
There is no way to set which profile is the active default without
renaming it to `[DEFAULT]`. Users with multiple profiles need a simple
way to switch between them.
## Changes
Before: no mechanism to designate a default profile. Users had to rename
sections in `~/.databrickscfg` or always pass `--profile`.
Now: `databricks auth switch` lets users select a named profile as the
default. The choice is stored in a `[__settings__]` section with a
`default_profile` key. `auth profiles` shows a `(Default)` marker, and
`auth describe` shows the resolved default name.
### Why `[__settings__]` instead of a top-level key?
INI files place keys that appear before any section header into the
`[DEFAULT]` section. The CLI already uses `[DEFAULT]` as a regular
profile section (with `host`, `token`, etc.), so adding
`default_profile` there would mix settings with profile credentials, and
the profiles command would try to interpret `[DEFAULT]` as a profile
containing that key. A dedicated `[__settings__]` section avoids this
collision and is silently ignored by older SDKs (no `host` key means it
is skipped in profile iteration).
### Implementation
- **`libs/databrickscfg/ops.go`**:
`GetDefaultProfile`/`GetDefaultProfileFrom` with fallback resolution
(explicit setting, single-profile auto-default, legacy DEFAULT section).
`SetDefaultProfile` to write the setting. Shared
`backupAndSaveConfigFile` and `resolveConfigFilePath` helpers to
deduplicate existing code.
- **`cmd/auth/switch.go`**: new command with `--profile` flag
(non-interactive) and interactive profile picker showing the current
default.
- **`cmd/auth/profiles.go`**: `(Default)` marker in output and `default`
field in JSON.
- **`cmd/auth/describe.go`**: shows resolved default profile name, e.g.
`profile: default (my-workspace)`.
- **`cmd/auth/login.go` + `token.go`**: auto-set default when creating
the very first profile.
Resolution wiring (making the CLI actually use `default_profile` when no
`--profile` is given) is out of scope. That will be a follow-up change
touching `cmd/root/auth.go` and the bundle config path.
## Test plan
- [x] Unit tests for `GetDefaultProfile`, `GetDefaultProfileFrom`,
`SetDefaultProfile` (table-driven, covering: explicit setting,
single-profile fallback, DEFAULT fallback, no file, round-trip with
`SaveToProfile`)
- [x] Unit tests for `auth switch` command (with `--profile`, profile
not found, non-interactive error, settings section written correctly)
- [x] Unit tests for `hasNoProfiles` (fresh machine /
ErrNoConfiguration, empty file, existing profiles)
- [x] Unit test for `(Default)` marker in `auth profiles`
- [x] `GetDefaultProfile` does not create the config file as a side
effect (asserted in test)
- [x] `make checks` and `make lintfull` pass
- [x] Manual: `databricks auth switch --profile <name>`, verify
`~/.databrickscfg` has `[__settings__]` section
- [x] Manual: `databricks auth profiles` shows `(Default)` marker
- [x] Manual: `databricks auth switch` interactive picker shows current
default
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
deco-sdk-taggingBot added a commit that referenced this pull request Mar 18, 2026
## Release v0.295.0
### Notable Changes
* Databricks Asset Bundles have been renamed to Declarative Automation Bundles (DABs). This is a non-breaking change; no code or configuration modifications are required. See the [FAQ](https://docs.databricks.com/aws/en/dev-tools/bundles/faqs#why-was-databricks-asset-bundles-renamed-to-declarative-automation-bundles).
* Add `bundle.engine` config setting to select the deployment engine (`terraform` or [`direct`](https://docs.databricks.com/aws/en/dev-tools/bundles/direct)). The `bundle.engine` setting takes precedence over the `DATABRICKS_BUNDLE_ENGINE` environment variable. When the configured engine doesn't match existing deployment state, a warning is issued and the existing engine is used ([#4749](#4749), [#4782](#4782))
### CLI
* Add `databricks auth switch` command for setting the default profile ([#4651](#4651))
* Add positional argument support to `auth logout` ([#4744](#4744))
* Strip trailing slash from host in `auth login`, `auth token`, and `configure` commands ([#4633](#4633))
### Bundles
* Standardize `personal_schemas` enum across bundle templates ([#4401](#4401))
* engine/direct: Fix permanent drift on experiment name field ([#4627](#4627))
* engine/direct: Fix permissions state path to match input config schema ([#4703](#4703))
* Add default project name and success message to default-scala template ([#4661](#4661))
* Skip enum validation for unresolved variable references ([#4752](#4752))
* engine/direct: Support references to/from grants ([#4774](#4774))
denik pushed a commit that referenced this pull request May 20, 2026
…4651)
## Why
There is no way to set which profile is the active default without
renaming it to `[DEFAULT]`. Users with multiple profiles need a simple
way to switch between them.
## Changes
Before: no mechanism to designate a default profile. Users had to rename
sections in `~/.databrickscfg` or always pass `--profile`.
Now: `databricks auth switch` lets users select a named profile as the
default. The choice is stored in a `[__settings__]` section with a
`default_profile` key. `auth profiles` shows a `(Default)` marker, and
`auth describe` shows the resolved default name.
### Why `[__settings__]` instead of a top-level key?
INI files place keys that appear before any section header into the
`[DEFAULT]` section. The CLI already uses `[DEFAULT]` as a regular
profile section (with `host`, `token`, etc.), so adding
`default_profile` there would mix settings with profile credentials, and
the profiles command would try to interpret `[DEFAULT]` as a profile
containing that key. A dedicated `[__settings__]` section avoids this
collision and is silently ignored by older SDKs (no `host` key means it
is skipped in profile iteration).
### Implementation
- **`libs/databrickscfg/ops.go`**:
`GetDefaultProfile`/`GetDefaultProfileFrom` with fallback resolution
(explicit setting, single-profile auto-default, legacy DEFAULT section).
`SetDefaultProfile` to write the setting. Shared
`backupAndSaveConfigFile` and `resolveConfigFilePath` helpers to
deduplicate existing code.
- **`cmd/auth/switch.go`**: new command with `--profile` flag
(non-interactive) and interactive profile picker showing the current
default.
- **`cmd/auth/profiles.go`**: `(Default)` marker in output and `default`
field in JSON.
- **`cmd/auth/describe.go`**: shows resolved default profile name, e.g.
`profile: default (my-workspace)`.
- **`cmd/auth/login.go` + `token.go`**: auto-set default when creating
the very first profile.
Resolution wiring (making the CLI actually use `default_profile` when no
`--profile` is given) is out of scope. That will be a follow-up change
touching `cmd/root/auth.go` and the bundle config path.
## Test plan
- [x] Unit tests for `GetDefaultProfile`, `GetDefaultProfileFrom`,
`SetDefaultProfile` (table-driven, covering: explicit setting,
single-profile fallback, DEFAULT fallback, no file, round-trip with
`SaveToProfile`)
- [x] Unit tests for `auth switch` command (with `--profile`, profile
not found, non-interactive error, settings section written correctly)
- [x] Unit tests for `hasNoProfiles` (fresh machine /
ErrNoConfiguration, empty file, existing profiles)
- [x] Unit test for `(Default)` marker in `auth profiles`
- [x] `GetDefaultProfile` does not create the config file as a side
effect (asserted in test)
- [x] `make checks` and `make lintfull` pass
- [x] Manual: `databricks auth switch --profile <name>`, verify
`~/.databrickscfg` has `[__settings__]` section
- [x] Manual: `databricks auth profiles` shows `(Default)` marker
- [x] Manual: `databricks auth switch` interactive picker shows current
default
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
denik pushed a commit that referenced this pull request May 20, 2026
## Release v0.295.0
### Notable Changes
* Databricks Asset Bundles have been renamed to Declarative Automation Bundles (DABs). This is a non-breaking change; no code or configuration modifications are required. See the [FAQ](https://docs.databricks.com/aws/en/dev-tools/bundles/faqs#why-was-databricks-asset-bundles-renamed-to-declarative-automation-bundles).
* Add `bundle.engine` config setting to select the deployment engine (`terraform` or [`direct`](https://docs.databricks.com/aws/en/dev-tools/bundles/direct)). The `bundle.engine` setting takes precedence over the `DATABRICKS_BUNDLE_ENGINE` environment variable. When the configured engine doesn't match existing deployment state, a warning is issued and the existing engine is used ([#4749](#4749), [#4782](#4782))
### CLI
* Add `databricks auth switch` command for setting the default profile ([#4651](#4651))
* Add positional argument support to `auth logout` ([#4744](#4744))
* Strip trailing slash from host in `auth login`, `auth token`, and `configure` commands ([#4633](#4633))
### Bundles
* Standardize `personal_schemas` enum across bundle templates ([#4401](#4401))
* engine/direct: Fix permanent drift on experiment name field ([#4627](#4627))
* engine/direct: Fix permissions state path to match input config schema ([#4703](#4703))
* Add default project name and success message to default-scala template ([#4661](#4661))
* Skip enum validation for unresolved variable references ([#4752](#4752))
* engine/direct: Support references to/from grants ([#4774](#4774))
Sign up for freeto 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.

4 participants

@simonfaltum@eng-dev-ecosystem-bot@pietern@denik