@@ -14,31 +14,20 @@ import (
1414
1515var ResolveProfileFromHost = profileFromHostLoader {}
1616
17- // ResolveNonAuthFromEnv reads config from environment variables, except for the
18- // host and any auth credential. It runs before the config file loader when a
19- // profile is explicitly selected, so the profile wins over auth env vars: the
20- // SDK's default chain reads env before the config file and never overwrites a
21- // set field, which would otherwise let env vars shadow the profile (#5096).
17+ // ResolveNonAuthFromEnv reads non-auth, non-host config from environment
18+ // variables. See ProfileAuthLoaders for how it fits into the chain.
2219var ResolveNonAuthFromEnv = nonAuthEnvLoader {}
2320
24- // ProfileAuthLoaders is the loader chain to use when a profile is explicitly
25- // selected (--profile or a bundle's workspace.profile), and the single source
26- // of truth for that precedence rule. The profile must win for host, routing and
27- // auth over the matching env vars (DATABRICKS_HOST, DATABRICKS_TOKEN, ...),
28- // which the SDK's default env-first chain would otherwise let shadow it (#5096).
21+ // ProfileAuthLoaders is the loader chain for an explicitly selected profile
22+ // (--profile or a bundle's workspace.profile). Unlike the SDK's default
23+ // env-first chain, the profile wins over auth env vars (#5096):
2924//
30- // This only governs an explicitly selected profile. One picked up from
31- // DATABRICKS_CONFIG_PROFILE keeps env-first precedence: reordering two
32- // environment signals (DATABRICKS_CONFIG_PROFILE vs DATABRICKS_HOST) is the
33- // SDK's domain; we only override when the profile is named out-of-band.
34- //
35- // Order:
36- // 1. ResolveNonAuthFromEnv: non-auth, non-routing env attrs (e.g. cluster_id),
37- // keeping env-wins precedence for those.
25+ // 1. ResolveNonAuthFromEnv: non-auth env attrs (e.g. cluster_id), env-wins.
3826// 2. ConfigFile: the selected profile (host, routing, auth).
39- // 3. ConfigAttributes: gap-fills only fields the profile left empty (e.g. a
40- // host-only profile + DATABRICKS_TOKEN, a common CI pattern); it never
41- // overwrites a profile value, so the profile still wins.
27+ // 3. ConfigAttributes: gap-fills only fields the profile left empty.
28+ //
29+ // A profile from DATABRICKS_CONFIG_PROFILE keeps env-first precedence; only an
30+ // out-of-band profile name triggers this chain.
4231var ProfileAuthLoaders = []config.Loader {
4332 ResolveNonAuthFromEnv ,
4433 config .ConfigFile ,
@@ -91,25 +80,12 @@ func findMatchingProfile(configFile *config.File, matcher func(*ini.Section) boo
9180 return matching [0 ], nil
9281}
9382
94- // nonAuthEnvSkipAttrs lists SDK config attributes nonAuthEnvLoader must not read
95- // from the environment, beyond those caught by HasAuthAttribute. They identify
96- // the target workspace/account (host, routing IDs) or steer the auth method but
97- // are tagged auth:"-" (collapsed to Internal), so HasAuthAttribute misses them;
98- // leaving them to env would let an env var shadow the selected profile (#5096).
99- // Skipping only changes precedence: the trailing ConfigAttributes loader still
100- // gap-fills any the profile leaves empty.
101- //
102- // - host: no `auth` tag at all.
103- // - workspace_id / account_id: routing identifiers; an env var must not route
104- // the profile's credentials elsewhere.
105- // - auth_type: forces a specific auth method.
106- // - discovery_url: redirects OIDC discovery.
107- // - audience: selects the OIDC/workload-identity token audience.
108- // - cloud: steers cloud-specific auth (Azure/GCP/AWS).
109- //
110- // Non-auth attrs tagged auth:"-" (oauth_callback_port, debug_headers, ...) are
111- // intentionally not skipped; TestNonAuthEnvSkipAttrsCoverSDKInternalEnvAttrs
112- // guards that every auth-steering internal attribute stays classified.
83+ // nonAuthEnvSkipAttrs lists env attributes nonAuthEnvLoader must skip on top of
84+ // those HasAuthAttribute catches: host/routing (host, workspace_id, account_id)
85+ // and auth-steering fields tagged auth:"-" (auth_type, discovery_url, audience,
86+ // cloud), which HasAuthAttribute misses. Reading these from env would shadow the
87+ // selected profile (#5096). TestNonAuthEnvSkipAttrsCoverSDKInternalEnvAttrs
88+ // guards against SDK drift.
11389var nonAuthEnvSkipAttrs = map [string ]bool {
11490 "host" : true ,
11591 "workspace_id" : true ,
@@ -128,12 +104,11 @@ func (nonAuthEnvLoader) Name() string {
128104
129105func (nonAuthEnvLoader ) Configure (cfg * config.Config ) error {
130106 for _ , attr := range config .ConfigAttributes {
131- // Leave the host and authentication settings for the config file
132- // (i.e. the selected profile) to provide.
107+ // Host and auth come from the profile (config file), not env.
133108 if nonAuthEnvSkipAttrs [attr .Name ] || attr .HasAuthAttribute () {
134109 continue
135110 }
136- // Match the SDK loader semantics: don 't overwrite a value previously set .
111+ // Don 't overwrite an already-set value (SDK loader semantics) .
137112 if ! attr .IsZero (cfg ) {
138113 continue
139114 }
@@ -144,8 +119,7 @@ func (nonAuthEnvLoader) Configure(cfg *config.Config) error {
144119 if err := attr .SetS (cfg , v ); err != nil {
145120 return err
146121 }
147- // Record the source so `databricks auth describe` and debug output
148- // attribute the value to the environment, matching the SDK loader.
122+ // Record the source so `auth describe` attributes the value to env.
149123 cfg .SetAttrSource (& attr , config.Source {Type : config .SourceEnv , Name : envName })
150124 }
151125 return nil
0 commit comments