Skip to content

Make --profile take precedence over auth environment variables#5702

Draft
radakam wants to merge 4 commits into
mainfrom
cli-5096-fix-profile-not-respected
Draft

Make --profile take precedence over auth environment variables#5702
radakam wants to merge 4 commits into
mainfrom
cli-5096-fix-profile-not-respected

Conversation

@radakam

@radakam radakam commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Changes

When --profile is passed explicitly (or workspace.profile is set in a bundle), the selected profile's host and authentication credentials now take precedence over authentication environment variables (DATABRICKS_HOST, DATABRICKS_TOKEN, and the other auth/credential vars).

  • Add databrickscfg.ResolveNonAuthFromEnv, an SDK config loader that reads all config from the environment except the host and auth credentials.
  • When a profile is explicitly selected, replace the SDK's default loader chain with [ResolveNonAuthFromEnv, ConfigFile, ConfigAttributes] and skip NormalizeDatabricksConfigFromEnv (which would otherwise promote the env host). This is wired through MustWorkspaceClient, MustAccountClient, and bundle/config.Workspace.Client via a shared profileAuthLoaders chain.

Why

The SDK's default loader order is environment first, then config file, and a loader never overwrites an already-set field. So with DATABRICKS_HOST/DATABRICKS_TOKEN set (e.g. via direnv in a project dir), they were loaded first and the profile selected with --profile could not overwrite them — the command silently ran against the env's workspace instead of the profile's (#5096).

Swapping the loader order only works if the host and auth fields are left empty for the config-file loader to fill, hence the dedicated non-auth env loader. The fix is intentionally scoped to host + authentication: non-auth attributes (e.g. cluster_id, workspace_id) keep their existing env precedence.

A trailing config.ConfigAttributes loader runs after the profile so the environment can still fill auth fields the profile leaves empty. This supports the common CI pattern where the host lives in .databrickscfg but DATABRICKS_TOKEN is injected by the runner: the profile wins for any field it sets, and the env fills only what the profile omits.

Tests

  • TestMustWorkspaceClientProfileFlagOverridesAuthEnv: the exact CLI profile not respected #5096 scenario (env points at dev, --profile selects another workspace); asserts the profile's host and token win.
  • TestMustWorkspaceClientProfileFlagFillsAuthFromEnv: a host-only profile combined with DATABRICKS_TOKEN; asserts the profile's host wins and the env fills the missing token.
  • TestMustAccountClientProfileFlagOverridesAuthEnv: same override behavior for the account client path.
  • TestWorkspaceClientProfileOverridesAuthEnv / TestWorkspaceClientProfileFillsAuthFromEnv: cover the workspace.profile (bundle) code path for both override and env-fill behavior.
  • TestResolveNonAuthFromEnvSkipsHostAndAuth: unit test confirming the loader skips host/token but still applies non-auth env vars.
  • Existing precedence tests (--profile > DATABRICKS_CONFIG_PROFILE, env-host-skips-default-profile) still pass.
  • go build ./..., go vet, and the cmd/root + libs/databrickscfg + bundle/config packages pass.

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).
@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: a673c11

Run: 28100625590

Env ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 13 244 1024 7:16
🟨​ aws windows 7 13 246 1022 7:33
💚​ aws-ucws linux 7 13 334 940 5:23
💚​ aws-ucws windows 7 13 336 938 6:06
💚​ azure linux 1 15 247 1022 5:16
❌​ azure windows 2 1 1 15 246 1020 8:14
💚​ azure-ucws linux 1 15 339 936 6:08
💚​ azure-ucws windows 1 15 341 934 4:55
💚​ gcp linux 1 15 246 1024 4:21
💚​ gcp windows 1 15 248 1022 5:05
23 interesting tests: 13 SKIP, 7 KNOWN, 2 FAIL, 1 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_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 ✅​p ✅​p ✅​p ✅​p ✅​p ❌​F ✅​p ✅​p ✅​p ✅​p
🔄​ TestFetchRepositoryInfoAPI_FromRepo/root ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
❌​ TestFetchRepositoryInfoAPI_FromRepo/subdir ✅​p ✅​p ✅​p ✅​p ✅​p ❌​F ✅​p ✅​p ✅​p ✅​p
Top 5 slowest tests (at least 2 minutes):
duration env testname
3:21 gcp windows TestAccept
3:16 aws-ucws windows TestAccept
3:13 aws linux TestSecretsPutSecretStringValue
2:41 azure windows TestAccept
2:31 azure-ucws windows TestAccept

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.
@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
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).
@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
Consolidate the profile-precedence loader chain into a single shared
databrickscfg.ProfileAuthLoaders, used by both cmd/root and bundle config
so the two copies can't drift. Add audience and cloud to the env skip
list (both steer auth but are tagged auth:"-" so HasAuthAttribute misses
them) and document the inclusion criterion. Clarify that the gap-fill of
auth fields from the environment and the env-first precedence of
DATABRICKS_CONFIG_PROFILE are intentional, and that
NormalizeDatabricksConfigFromEnv is deliberately skipped under --profile.

Add an acceptance test covering --profile winning over DATABRICKS_HOST/
DATABRICKS_TOKEN and a host-only profile filling its token from the
environment (#5096).
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