Skip to content

Return clear error when auth token is used with M2M profile#4594

Merged
simonfaltum merged 3 commits intomainfrom
simonfaltum/m2m-token-error
Feb 26, 2026
Merged

Return clear error when auth token is used with M2M profile#4594
simonfaltum merged 3 commits intomainfrom
simonfaltum/m2m-token-error

Conversation

@simonfaltum
Copy link
Member

@simonfaltum simonfaltum commented Feb 25, 2026

Summary

Fixes #1939

When databricks auth token --profile <m2m-profile> is used with a profile that has client_id/client_secret configured (M2M / service principal auth), the command currently either:

  1. Silently returns the wrong token — a cached U2M token for the same host, identifying the user instead of the service principal
  2. Triggers an interactive browser login — pushing the user into U2M auth with no explanation

This PR adds early detection of M2M profiles and returns a clear error:

Error: profile "my-sp" uses M2M authentication (client_id/client_secret).
`databricks auth token` only supports U2M (user-to-machine) authentication tokens.
To authenticate as a service principal, use the Databricks SDK directly

Changes

  • Added ClientID field to profile.Profile struct (populated from .databrickscfg)
  • Added check in loadToken that detects M2M profiles before attempting U2M token lookup
  • After host-based profile resolution, existingProfile is reloaded so the M2M guard also covers --host invocations that resolve to a single M2M profile
  • Works for all three profile resolution paths: --profile flag, positional argument, and host-based matching

Test plan

  • M2M profile returns clear error — explicit --profile targeting M2M profile
  • M2M profile detected via positional arg — positional arg resolves to M2M profile
  • M2M profile detected via host resolution--host uniquely matches an M2M profile
  • All existing TestToken_loadToken cases pass (no regressions)
  • make checks passes
  • make lintfull passes

Previously, `databricks auth token --profile <m2m-profile>` would
silently return the wrong token (a cached U2M token for the same host)
or trigger an interactive browser login. This was confusing because the
command gave no indication that M2M profiles are unsupported.

Now the command detects when the resolved profile has a client_id
configured and returns an explicit error explaining that `auth token`
only supports U2M authentication.

Fixes #1939
@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Feb 25, 2026

Commit: 6b78d45

Run: 22396332401

Env 🟨​KNOWN 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 1 7 268 767 6:08
🟨​ aws windows 7 1 7 270 765 5:46
💚​ aws-ucws linux 8 7 364 683 6:38
💚​ aws-ucws windows 8 7 366 681 4:22
💚​ azure linux 2 9 271 765 5:23
💚​ azure windows 2 9 273 763 4:52
💚​ azure-ucws linux 2 9 369 679 6:05
💚​ azure-ucws windows 2 9 371 677 4:18
💚​ gcp linux 2 9 267 768 5:06
💚​ gcp windows 2 9 269 766 4:26
15 interesting tests: 7 KNOWN, 7 SKIP, 1 RECOVERED
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/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/connection 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 20 slowest tests (at least 2 minutes):
duration env testname
3:21 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:13 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:13 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:10 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:08 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:05 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:51 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:51 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:49 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:46 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:43 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:43 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:16 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:14 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:12 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:11 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:09 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:08 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:05 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:03 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

The M2M guard checked existingProfile, but that variable was not
updated when a profile was resolved later via host matching. This
meant `--host <url>` that uniquely matched an M2M profile would
bypass the check and fall through to the U2M token lookup.

Now existingProfile is updated in both branches of the host-matching
block (single match and interactive selection), and a new test covers
the host-resolved path.
Replace ClientID string with HasClientCredentials bool that requires
both client_id and client_secret in the profile. Fix gofmt alignment.
@simonfaltum simonfaltum added this pull request to the merge queue Feb 26, 2026
Merged via the queue into main with commit 278e906 Feb 26, 2026
18 checks passed
@simonfaltum simonfaltum deleted the simonfaltum/m2m-token-error branch February 26, 2026 14:29
deco-sdk-tagging bot added a commit that referenced this pull request Feb 26, 2026
## Release v0.290.1

### CLI
* Return clear error when `auth token` is used with M2M profile ([#4594](#4594))
* Pin `apps init` to Appkit `template-v0.11.0` by default ([#4585](#4585))
* Pin Agent Skills installer to v0.1.1 ([#4609](#4609))

### Bundles
* direct: Use async Update API for Apps update ([#4607](#4607))
* Proactively create the resource path for dashboards ([#4608](#4608))
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.

databricks auth token command doesn't support oauth-m2m flow

3 participants