Skip to content

Make an explicitly selected profile take precedence over auth environment variables#5702

Merged
radakam merged 8 commits into
mainfrom
cli-5096-fix-profile-not-respected
Jul 3, 2026
Merged

Make an explicitly selected profile take precedence over auth environment variables#5702
radakam merged 8 commits into
mainfrom
cli-5096-fix-profile-not-respected

Conversation

@radakam

@radakam radakam commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Why

With an explicit profile (--profile or a bundle's workspace.profile), auth env vars (DATABRICKS_HOST, DATABRICKS_TOKEN, ...) silently shadowed it: the SDK reads env before the config file and never overwrites an already-set field.

Separately, databricks api without --profile pinned [__settings__].default_profile unconditionally, so a conflicting default profile could still be merged with env auth and fail with "more than one authorization method configured" (the same #5616 class already fixed for MustWorkspaceClient).

Changes

Fixes #5096

When a profile is selected explicitly, use a shared loader chain (databrickscfg.ProfileAuthLoaders) so the profile wins for host/auth/routing, while env still gap-fills only the auth fields the profile leaves empty (e.g. host-only profile + DATABRICKS_TOKEN). Non-auth env vars (e.g. cluster_id) stay env-first via a small ResolveNonAuthFromEnv loader. Wired into MustWorkspaceClient, MustAccountClient, Workspace.Client, and databricks api.

For databricks api without --profile, share the #5616 default-profile guard instead of duplicating it: resolveDefaultProfile is exported as ResolveDefaultProfile and called from cmd/api, so a default_profile is skipped when DATABRICKS_HOST is set (single source of truth with MustWorkspaceClient, no drift).

Explicit design choices:

  • Scope: only an explicit profile changes behavior. DATABRICKS_CONFIG_PROFILE keeps the SDK's env-first precedence.
  • Conflicting auth method: a complete auth method in env (e.g. profile PAT + env OAuth client id/secret) still errors with "more than one authorization method configured".
  • SPOG query params: for an explicit profile we skip NormalizeDatabricksConfigFromEnv, so a SPOG-style DATABRICKS_HOST (?o=/?a=) no longer overrides the profile; the profile's host is authoritative.

Tests

  • Unit + acceptance: --profile/workspace.profile wins over auth env; DATABRICKS_CONFIG_PROFILE stays env-first; host-only profile fills its token from env; conflicting-method error.
  • Acceptance: databricks api without --profile uses env auth and ignores a conflicting default_profile when DATABRICKS_HOST is set (fails pre-fix with "more than one authorization method configured").
  • Guard test that fails if an SDK bump adds a new internal (auth:"-") env-backed attribute that hasn't been classified as auth-steering vs. env-first.

@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 12:00 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 12:00 — with GitHub Actions Inactive
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 29d2b24

Run: 28614249325

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 10 13 230 1044 4:17
💚​ aws windows 10 13 232 1042 4:10
💚​ aws-ucws linux 10 13 314 962 5:08
💚​ aws-ucws windows 10 13 316 960 4:27
🔄​ azure linux 2 2 15 230 1043 5:36
💚​ azure windows 4 15 232 1041 3:52
💚​ azure-ucws linux 4 15 316 959 5:10
💚​ azure-ucws windows 4 15 318 957 3:46
💚​ gcp linux 4 15 229 1045 4:08
💚​ gcp windows 4 15 231 1043 3:51
23 interesting tests: 13 SKIP, 8 RECOVERED, 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 💚​R 💚​R 💚​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 💚​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/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_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/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R 💚​R 💚​R
Top 5 slowest tests (at least 2 minutes):
duration env testname
3:07 aws-ucws windows TestAccept
3:02 aws windows TestAccept
3:02 gcp windows TestAccept
2:58 azure windows TestAccept
2:45 azure-ucws windows TestAccept

@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 12:26 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 12:26 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 13:05 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 24, 2026 13:05 — with GitHub Actions Inactive
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from fe17837 to ae05b0e Compare June 26, 2026 08:50
@radakam radakam changed the title Make --profile take precedence over auth environment variables Make an explicitly selected profile take precedence over auth environment variables Jun 29, 2026
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from 72b1acb to b2c4d95 Compare June 29, 2026 08:23
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 08:23 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 08:23 — with GitHub Actions Inactive
@radakam radakam marked this pull request as ready for review June 29, 2026 08:24
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from b2c4d95 to aeb17ab Compare June 29, 2026 08:56
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 08:57 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 08:57 — with GitHub Actions Inactive
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from aeb17ab to 7ce0ce7 Compare June 29, 2026 09:42
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 09:42 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 09:42 — with GitHub Actions Inactive
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from 7ce0ce7 to e16df4f Compare June 29, 2026 09:53
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 09:53 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 29, 2026 09:53 — with GitHub Actions Inactive
Comment thread cmd/api/api.go
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from ca6bf4e to 8fd0e5f Compare July 2, 2026 13:40
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 13:40 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 13:40 — with GitHub Actions Inactive

@simonfaltum simonfaltum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think there is one more thing for us to fix but otherwise looks good. Approving to unblock

Comment thread libs/databrickscfg/loader.go Outdated
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 14:42 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 14:42 — with GitHub Actions Inactive
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from 6c639fd to 05b591a Compare July 2, 2026 14:49
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 14:49 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 14:49 — with GitHub Actions Inactive
radakam added 7 commits July 2, 2026 17:57
When --profile is set explicitly, host and auth credentials from the
profile now win over DATABRICKS_HOST/DATABRICKS_TOKEN and other auth env
vars. Previously the SDK's env-first loader order silently shadowed the
selected profile (#5096).
Extend the --profile precedence fix (#5096):

- ResolveNonAuthFromEnv now also skips auth_type and discovery_url, which
  are tagged auth:"-" in the SDK and so are invisible to HasAuthAttribute,
  letting DATABRICKS_AUTH_TYPE/DATABRICKS_DISCOVERY_URL shadow the profile.
  It also records the env source so `auth describe` and debug output match
  the SDK loader.
- Workspace.Client uses ResolveNonAuthFromEnv when a profile is set (from
  --profile or workspace.profile) so env auth vars no longer shadow the
  profile for bundle commands.
- Use the reserved .test TLD for new test fixture hosts so the SDK's
  well-known host metadata resolver fast-fails instead of stalling on a
  live network lookup.
A host-only profile combined with DATABRICKS_TOKEN previously failed because
the profile loader chain stopped at the config file. Append
config.ConfigAttributes after the profile so the environment can fill auth
fields the profile does not provide, while the profile still wins for any
field it sets (#5096).
- Centralize the explicit-profile loader chain in databrickscfg.ProfileAuthLoaders
  and extract applyProfileAuthPrecedence so all call sites share one rule.
- Skip host, routing IDs (workspace_id/account_id) and SDK-internal auth-steering
  env attrs; guard the classification with a test that fails on SDK drift.
- Apply profile precedence to `databricks api --profile`.
- Let env gap-fill auth fields a host-only profile leaves empty.
- Add bundle host+profile coverage and acceptance tests; clarify rationale comments.
The no---profile branch in `databricks api` pinned
[__settings__].default_profile unconditionally, so a conflicting default
profile could be merged with env auth (DATABRICKS_HOST/DATABRICKS_TOKEN),
failing with "more than one authorization method configured" (the #5616
class already fixed for MustWorkspaceClient).

Share the guard: export resolveDefaultProfile as ResolveDefaultProfile and
call it from cmd/api, so the default profile is skipped when DATABRICKS_HOST
is set. Adds an acceptance case with env PAT + conflicting default_profile.
The final loader in ProfileAuthLoaders was the SDK's config.ConfigAttributes,
which re-reads every still-empty attribute from the environment after the
profile is loaded. That let host/routing/auth-steering env vars (auth_type,
discovery_url, audience, cloud, workspace_id, account_id) shadow an explicitly
selected profile, e.g. DATABRICKS_AUTH_TYPE=basic forcing basic auth over a
profile's PAT (#5096).

Replace it with resolveAuthGapFromEnv, a filtered env loader that skips
nonAuthEnvSkipAttrs but still gap-fills real auth attrs, so a complete
conflicting env auth method surfaces as an error rather than being silently
dropped. Add an end-to-end ProfileAuthLoaders test covering the steering-env
repro.
@radakam radakam force-pushed the cli-5096-fix-profile-not-respected branch from 05b591a to 8ef7b6a Compare July 2, 2026 17:59
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 17:59 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 17:59 — with GitHub Actions Inactive
A selected profile skips host/routing/auth-steering env vars so they can't
shadow it (#5096), but the host was skipped in both the env-first and the
gap-fill passes. A profile that leaves the host empty (or can't be resolved)
then never fell back to DATABRICKS_HOST and failed with "cannot configure
default credentials".

Treat the host like an auth attribute: skip it only in the env-first pass so
the profile still owns it, then gap-fill it from env after the profile,
mirroring the existing token gap-fill. Routing/auth-steering attrs stay skipped
in both passes.
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 18:53 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is July 2, 2026 18:53 — with GitHub Actions Inactive
@radakam radakam added this pull request to the merge queue Jul 3, 2026
Merged via the queue into main with commit ccdc2f3 Jul 3, 2026
23 checks passed
@radakam radakam deleted the cli-5096-fix-profile-not-respected branch July 3, 2026 07:33
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.

CLI profile not respected

3 participants