Skip to content

Commit b82a295

Browse files
Pass --force-refresh to CLI auth token command
Pass --force-refresh to the Databricks CLI auth token command when the CLI supports it (>= v0.296.0), bypassing the CLI's internal token cache. The SDK manages its own token caching. When the SDK considers its token stale and shells out to `databricks auth token`, the CLI may return a cached token that is about to expire from the SDK's perspective. The --force-refresh flag guarantees a freshly minted token. With the version detection infrastructure from the parent commit, adding --force-refresh is a one-constant, one-if change. See: databricks/cli#4767
1 parent 563fc02 commit b82a295

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Release v0.106.0
44

55
### New Features and Improvements
6+
* Pass `--force-refresh` to Databricks CLI `auth token` command so the SDK always receives a freshly minted token instead of a potentially stale one from the CLI's internal cache.
67

78
### Security
89

databricks/sdk/credentials_provider.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,9 @@ def _validate_token_scopes(self, token: oauth.Token):
10601060
# --profile support added in CLI v0.207.1: https://github.com/databricks/cli/pull/855
10611061
_CLI_VERSION_FOR_PROFILE = CliVersion(0, 207, 1)
10621062

1063+
# --force-refresh support added in CLI v0.296.0: https://github.com/databricks/cli/pull/4767
1064+
_CLI_VERSION_FOR_FORCE_REFRESH = CliVersion(0, 296, 0)
1065+
10631066
@staticmethod
10641067
def _parse_cli_version(output: str) -> CliVersion:
10651068
"""Parse the JSON output of `databricks version --output json`.
@@ -1134,7 +1137,25 @@ def _resolve_cli_command(cli_path: str, cfg: "Config") -> List[str]:
11341137

11351138
@staticmethod
11361139
def _build_cli_command(cli_path: str, cfg: "Config", version: CliVersion) -> List[str]:
1137-
"""Build the `auth token` command.
1140+
"""Build the full CLI command, including capability-gated flags.
1141+
1142+
Delegates the profile/host decision to _build_core_cli_command and
1143+
appends --force-refresh when supported.
1144+
"""
1145+
cmd = DatabricksCliTokenSource._build_core_cli_command(cli_path, cfg, version)
1146+
if version >= DatabricksCliTokenSource._CLI_VERSION_FOR_FORCE_REFRESH:
1147+
cmd.append("--force-refresh")
1148+
else:
1149+
logger.warning(
1150+
f"Databricks CLI {version} does not support --force-refresh "
1151+
f"(requires >= {DatabricksCliTokenSource._CLI_VERSION_FOR_FORCE_REFRESH}). "
1152+
"The CLI's token cache may provide stale tokens."
1153+
)
1154+
return cmd
1155+
1156+
@staticmethod
1157+
def _build_core_cli_command(cli_path: str, cfg: "Config", version: CliVersion) -> List[str]:
1158+
"""Build the base `auth token` command without capability-gated flags.
11381159
11391160
Falls back to --host when --profile is either not configured or not
11401161
supported by the installed CLI. Raises ValueError describing which

tests/test_credentials_provider.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,42 @@ def _make_cfg(*, profile=None, host=None, account_id=None):
486486
_CV(0, 0, 0),
487487
[_CLI, "auth", "token", "--host", _HOST],
488488
),
489+
(
490+
"host with force-refresh",
491+
_make_cfg(host=_HOST),
492+
_CV(0, 296, 0),
493+
[_CLI, "auth", "token", "--host", _HOST, "--force-refresh"],
494+
),
495+
(
496+
"account host with force-refresh",
497+
_make_cfg(host=_ACCT_HOST, account_id="acct-123"),
498+
_CV(0, 296, 0),
499+
[_CLI, "auth", "token", "--host", _ACCT_HOST, "--account-id", "acct-123", "--force-refresh"],
500+
),
501+
(
502+
"profile with force-refresh",
503+
_make_cfg(profile="my-profile", host=_HOST),
504+
_CV(0, 296, 0),
505+
[_CLI, "auth", "token", "--profile", "my-profile", "--force-refresh"],
506+
),
507+
(
508+
"profile supports profile but not force-refresh",
509+
_make_cfg(profile="my-profile", host=_HOST),
510+
_CV(0, 207, 1),
511+
[_CLI, "auth", "token", "--profile", "my-profile"],
512+
),
513+
(
514+
"profile-only with force-refresh",
515+
_make_cfg(profile="my-profile"),
516+
_CV(0, 296, 0),
517+
[_CLI, "auth", "token", "--profile", "my-profile", "--force-refresh"],
518+
),
519+
(
520+
"zero version, host only, no force-refresh",
521+
_make_cfg(host=_HOST),
522+
_CV(0, 0, 0),
523+
[_CLI, "auth", "token", "--host", _HOST],
524+
),
489525
],
490526
)
491527
def test_build_cli_command(name, cfg, version, expected):
@@ -568,6 +604,17 @@ def test_resolve_cli_command_wraps_missing_config_error(mocker):
568604
credentials_provider.DatabricksCliTokenSource._resolve_cli_command(_CLI, cfg)
569605

570606

607+
def test_build_cli_command_force_refresh_unsupported_logs_warning(caplog):
608+
import logging
609+
610+
cfg = _make_cfg(host=_HOST)
611+
with caplog.at_level(logging.WARNING, logger="databricks.sdk.credentials_provider"):
612+
credentials_provider.DatabricksCliTokenSource._build_cli_command(_CLI, cfg, _CV(0, 295, 0))
613+
assert any(
614+
"does not support --force-refresh" in rec.message and rec.levelname == "WARNING" for rec in caplog.records
615+
)
616+
617+
571618
# Tests for cloud-agnostic hosts and removed cloud checks
572619
class TestCloudAgnosticHosts:
573620
"""Tests that credential providers work with cloud-agnostic hosts after removing is_azure/is_gcp checks."""

0 commit comments

Comments
 (0)