Skip to content

air: request only userName from SCIM Me when resolving the launch directory - #7153

Merged
stevenchen-db merged 5 commits into
mainfrom
schen/air-overlap-user-lookup
Oct 21, 2026
Merged

stevenchen-db merged 5 commits into
mainfrom
schen/air-overlap-user-lookup

Conversation

@stevenchen-db

@stevenchen-db stevenchen-db commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Changes

air run now asks SCIM Me for only userName (attributes=userName) when it resolves the launch directory.

Why

The launch directory needs only the user name, but the full SCIM Me response also resolves groups and entitlements. On a test workspace the trimmed call took 50ms at the median versus 94ms for the full one (40 calls each), and air run --dry-run dropped from 150ms to 101ms at the median (25 runs per build, alternating).

Tests

  • New unit test asserts the Me request sends attributes=userName and the launch directory is unchanged.
  • go test ./cmd/air/ and go test ./acceptance -run TestAccept/air pass; ./task fmt, ./task checks, and ./task lint are clean.
  • air run --dry-run against a real workspace sends GET /api/2.0/preview/scim/v2/Me?attributes=userName and resolves the same launch directory as before.

This pull request and its description were written by Isaac.

`air run` resolves the user with SCIM Me before it can build the command path
that config validation needs, so the two calls ran back to back.

- Ask SCIM Me for only `userName`; the full response also resolves groups and
  entitlements.
- When the workspace's own OAuth token names a user, start validation on that
  user's path while SCIM Me is in flight. SCIM's answer still decides the
  launch directory: if it differs from the token, validation reruns on SCIM's
  path before anything is created, uploaded, or submitted.

Co-authored-by: Isaac <no-reply@databricks.com>
@stevenchen-db
stevenchen-db requested review from a team as code owners October 21, 2026 18:54
@github-actions github-actions Bot added the AIR Databricks AI Runtime CLI label Oct 21, 2026
stevenchen-db and others added 3 commits October 21, 2026 18:56
Co-authored-by: Isaac <no-reply@databricks.com>
Leaves userWorkspaceDir and its tests unchanged: the token's guess is checked
against its answer, so an override is handled like any other mismatch.

Co-authored-by: Isaac <no-reply@databricks.com>
…ides

Only databricks-cli and oauth-m2m serve Token from the cache request headers
use; azure-cli and similar providers would fetch a fresh token just to read
it. A configured directory override is used as the guess, so override users
still validate once.

Co-authored-by: Isaac <no-reply@databricks.com>
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: ecdd14c

Run: 39668484604

Env 🔄​flaky ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 281 15 4:10
🔄​ aws-windows-latest-4core-16gb 2 281 13 7:26
✅​ azure linux-2core-8gb 280 15 3:55
✅​ azure-windows-latest-4core-16gb 282 13 3:26
✅​ gcp linux-2core-8gb 281 15 4:24
✅​ gcp-windows-latest-4core-16gb 283 13 3:41
Test Name aws-windows-latest-4core-16gb
🔄​ TestFsCpDirToDirFileNotOverwritten 🔄​f
🔄​ TestFsCpDirToDirFileNotOverwritten/uc-volumes_to_uc-volumes 🔄​f
Top 3 slowest tests (at least 2 minutes):
duration env testname
6:29 aws-windows-latest-4core-16gb TestAccept
3:29 gcp-windows-latest-4core-16gb TestAccept
3:22 azure-windows-latest-4core-16gb TestAccept

The overlap saved ~30ms on top of the trimmed call but carried most of the
change's complexity, so keep just `attributes=userName`.

Co-authored-by: Isaac <no-reply@databricks.com>
@stevenchen-db stevenchen-db changed the title air: trim the SCIM Me call and overlap it with config validation air: request only userName from SCIM Me when resolving the launch directory Oct 21, 2026
@stevenchen-db
stevenchen-db added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 59e8aa3 Oct 21, 2026
28 checks passed
@stevenchen-db
stevenchen-db deleted the schen/air-overlap-user-lookup branch October 21, 2026 22:02
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 59e8aa3

Run: 39683612026

Env ❌​FAIL 🔄​flaky ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 1451 1199 178:03
✅​ aws-windows-latest-4core-16gb 1376 1224 192:50
🔄​ azure linux-2core-8gb 4 1296 1251 99:11
✅​ azure-windows-latest-4core-16gb 1225 1276 120:33
✅​ gcp linux-2core-8gb 1289 1255 109:55
❌​ gcp-windows-latest-4core-16gb 58 1156 1280 118:12
62 interesting tests: 58 FAIL, 4 flaky
Test Name azure linux-2core-8gb gcp-windows-latest-4core-16gb
❌​ TestAccept ✅​p ❌​F
❌​ TestAccept/bundle/apps/job_permissions ✅​p ❌​F
❌​ TestAccept/bundle/apps/job_permissions/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/apps/job_permissions/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_doesnot_exist ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_doesnot_exist/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_doesnot_exist/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_not_deployed ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_not_deployed/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/artifacts/artifact_path_with_volume/volume_not_deployed/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/debug/fetch-repository-info ✅​p ❌​F
❌​ TestAccept/bundle/debug/fetch-repository-info/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/debug/fetch-repository-info/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=true/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=true/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deploy/files/no-snapshot-sync ✅​p ❌​F
❌​ TestAccept/bundle/deploy/files/no-snapshot-sync/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deploy/files/no-snapshot-sync/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deploy/mlops-stacks ✅​p ❌​F
❌​ TestAccept/bundle/deploy/mlops-stacks/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deploy/mlops-stacks/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deploy/spark-jar-task ✅​p ❌​F
❌​ TestAccept/bundle/deploy/spark-jar-task/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deploy/spark-jar-task/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/alert ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/alert/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/catalog ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/catalog/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/cluster ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/cluster/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/dashboard/recreation ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/dashboard/recreation/DMS=/READPLAN= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/dashboard/recreation/DMS=/READPLAN=1 ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/experiment ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/experiment/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/generate-and-bind ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/generate-and-bind/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/job-abort-bind ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/job-abort-bind/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/job-spark-python-task ✅​p ❌​F
❌​ TestAccept/bundle/deployment/bind/job/job-spark-python-task/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/deployment/unbind/permissions ✅​p ❌​F
❌​ TestAccept/bundle/deployment/unbind/permissions/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/destroy/jobs-and-pipeline ✅​p ❌​F
❌​ TestAccept/bundle/destroy/jobs-and-pipeline/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/destroy/jobs-and-pipeline/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-name-target ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-name-target/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-name-target/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-not-scoped ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-not-scoped/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/destroy/root-path-not-scoped/DMS=true ✅​p ❌​F
❌​ TestAccept/bundle/destroy/sibling-target ✅​p ❌​F
❌​ TestAccept/bundle/destroy/sibling-target/DMS= ✅​p ❌​F
❌​ TestAccept/bundle/destroy/sibling-target/DMS=true ✅​p ❌​F
🔄​ TestAccept/bundle/resources/dashboards/change-embed-credentials 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/dashboards/change-embed-credentials/DMS=true 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/permissions/dashboards/create 🔄​f 🙈​s
🔄​ TestAccept/bundle/resources/permissions/dashboards/create/DMS= 🔄​f
Top 50 slowest tests (at least 2 minutes):
duration env testname
31:15 aws-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=
29:22 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=1
24:20 aws linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=true
20:44 aws-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=true
20:24 aws linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=
20:07 aws linux-2core-8gb TestAccept/bundle/deploy/spark-jar-task/DMS=
17:49 aws-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=
15:20 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
15:09 aws linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=
15:01 aws-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=true
14:32 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
14:01 aws linux-2core-8gb TestAccept/bundle/invariant/no_drift/DMS=true/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
13:01 gcp linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=
11:58 aws linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=true
11:54 aws linux-2core-8gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
11:33 aws linux-2core-8gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
10:56 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
10:39 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
10:21 aws linux-2core-8gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=1
10:20 aws linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/simple/DMS=true
10:18 aws linux-2core-8gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
10:08 azure-windows-latest-4core-16gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=1
9:58 gcp-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=true
9:54 gcp linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=
9:46 aws linux-2core-8gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
9:40 aws linux-2core-8gb TestAccept/bundle/deploy/spark-jar-task/DMS=true
9:37 aws-windows-latest-4core-16gb TestAccept/bundle/deploy/spark-jar-task/DMS=
9:26 gcp-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DMS=true
9:04 aws-windows-latest-4core-16gb TestAccept/bundle/deploy/spark-jar-task/DMS=true
8:56 gcp linux-2core-8gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=true
8:44 aws linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/update-after-create/DMS=true
8:30 gcp-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started/DMS=
8:28 aws linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/update-after-create/DMS=
8:08 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=1
7:51 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=1
7:50 aws linux-2core-8gb TestAccept/bundle/config-remote-sync/multiple_resources/DMS=true
7:41 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
7:36 aws linux-2core-8gb TestAccept/bundle/invariant/no_drift/DMS=true/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
7:35 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/no_drift/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
7:35 aws-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/deploy/data_security_mode/DMS=true
7:33 gcp-windows-latest-4core-16gb TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DMS=true
7:30 aws linux-2core-8gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
7:27 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
7:27 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/delete_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
7:23 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/destroy_idempotent/DMS=/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=
7:23 gcp linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DMS=
7:22 aws linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/data_security_mode/DMS=true
7:20 aws linux-2core-8gb TestAccept/bundle/resources/clusters/resize-terminated-fallback/DMS=true
7:18 gcp linux-2core-8gb TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DMS=true
7:18 aws-windows-latest-4core-16gb TestAccept/bundle/invariant/no_drift/DMS=true/INPUT_CONFIG=cluster_libraries.yml.tmpl/READPLAN=

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AIR Databricks AI Runtime CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants