Skip to content

Device code auth - #7093

Open
maksim-zuev-db wants to merge 8 commits into
mainfrom
device-code
Open

maksim-zuev-db wants to merge 8 commits into
mainfrom
device-code

Conversation

@maksim-zuev-db

@maksim-zuev-db maksim-zuev-db commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Changes

Implementation of device code auth flow. The backend implementation is still not finalized in production, so this change introduces --use-device-code flag as experimental, hidden under DATABRICKS_CLI_DEVICE_CODE env variable.

Why

The Device Code flow enables users to authenticate with the Databricks CLI on machines that don't have browser access (e.g. headless servers, SSH sessions, web terminals). Instead of the standard browser-redirect OAuth flow, the user authenticates on a separate device (e.g. their phone or laptop) by entering a short code.

Tests

  • Unit tests cover the protocol logic and the auth login helpers, including
    edge cases like expiry, retries and cancellation.
  • Acceptance tests run the CLI end to end against libs/testserver, which now
    models Databricks' device code flow. Confirmation codes are piped through
    stdin. The tests cover the successful login and each error scenario.
  • Manual tests: only dev environments support device code now.

@maksim-zuev-db
maksim-zuev-db requested review from a team as code owners October 16, 2026 15:50
@maksim-zuev-db
maksim-zuev-db marked this pull request as draft October 16, 2026 15:51
@eng-dev-ecosystem-bot

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

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 556ea93

Run: 39790399942

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 281 20 4:12
✅​ aws-windows-latest-4core-16gb 283 18 4:04
✅​ azure linux-2core-8gb 280 20 4:11
✅​ azure-windows-latest-4core-16gb 282 18 3:40
✅​ gcp linux-2core-8gb 281 20 4:14
✅​ gcp-windows-latest-4core-16gb 283 18 6:25
Top 3 slowest tests (at least 2 minutes):
duration env testname
6:18 gcp-windows-latest-4core-16gb TestAccept
3:57 aws-windows-latest-4core-16gb TestAccept
3:33 azure-windows-latest-4core-16gb TestAccept

Comment thread cmd/auth/login.go Outdated
Comment thread cmd/auth/login_device_code.go Outdated
// workspace hosts, which must not change the default profile name.
probe := *authArguments
probe.Host = auth.ExtractHostQueryParams(probe.Host).Host
if needsAccountIDPrompt(probe.Host, probe.DiscoveryURL) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a weird function to call here. Based on the name it feels like a function that's designed to be used for prompting for information.

Is this the right option?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed the function, as it checked account/unified host under the hood

Comment thread libs/auth/u2m/device_code.go Outdated
Comment on lines +56 to +66
func CheckDeviceCodeSupported(ctx context.Context, workspaceHost string) error {
supplier := &BasicOAuthEndpointSupplier{Client: httpclient.NewApiClient(httpclient.ClientConfig{})}
endpoints, err := supplier.GetWorkspaceOAuthEndpoints(ctx, workspaceHost)
if err != nil {
return fmt.Errorf("fetching OAuth endpoints: %w", err)
}
if endpoints.DeviceAuthorizationEndpoint == "" {
return ErrDeviceCodeNotSupported
}
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this function if we made the same check at line 83 in DeviceCodeChallenge?

I assume we would fail a bit later in the flow but would that cause problems? On the other end, we can avoid making a (potentially unnecessary) API call.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to fail fast. Otherwise the login flow starts creating a profile, asks for the name. After entering it fails because the host is unsupported, but we were able to check this at earlier steps.

// confirmation code leaves the device code valid, so the user can re-enter
// it up to maxConfirmationAttempts times. Only workspace hosts are supported.
// The caller is responsible for storing the returned token.
func (a *PersistentAuth) DeviceCodeChallenge(confirm ConfirmFunc) (*oauth2.Token, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to pass the function as an argument? What would be the downside of calling the function directly?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libs/auth/u2m is a library and doesn't depend on cmdio, so the prompt UX stays in cmd/auth (promptForConfirmationCode). The function argument also lets the unit tests in device_code_test.go script the retry and error cases (8+ call sites) without stdin.

Comment thread acceptance/cmd/auth/login/use-device-code/output.txt Outdated
Comment thread acceptance/cmd/auth/login/use-device-code/output.txt Outdated
maksim-zuev-db and others added 7 commits October 22, 2026 11:04
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
The server answers a rate-limited device code token request with
invalid_request too, but with HTTP 429. Entering the confirmation code
again cannot fix that, so end the login for any error other than
HTTP 400 with invalid_request.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
The device code host check uses it to reject account and unified hosts, not to decide whether to prompt. Keep needsAccountIDPrompt as a local variable where setHostAndAccountId decides to prompt.

Co-authored-by: Isaac <no-reply@databricks.com>
CheckDeviceCodeSupported fetched the OIDC endpoints with its own client and repeated the check DeviceCodeChallenge makes. Make it a PersistentAuth method that runs the same deviceCodeConfig as DeviceCodeChallenge, so the up-front check and the login cannot disagree.

Co-authored-by: Isaac <no-reply@databricks.com>
Group the cases so that a failing test name points at the broken step: preconditions, the successful login (with a host, from a saved profile and with --scopes), unsupported hosts, an unallowed client, and missing or wrong confirmation codes. Only the nominal test prints the device code requests, because the requested scope is what it checks; the unsupported host test checks that no device authorization request is made.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Commit: 556ea934b | Workflow run

Regression test report

Selected 5 changed tests (limit=20, 0 not selected)

5 tests: regression=5 unreleased=0 coverage=0 failing=0

test branch main (66fce77) latest (v1.22.1)
TestAccept/cmd/auth/login/use-device-code-client-not-allowed ✅ ❌ ❌
TestAccept/cmd/auth/login/use-device-code-nominal ✅ ❌ ❌
TestAccept/cmd/auth/login/use-device-code-precondition ✅ ❌ ❌
TestAccept/cmd/auth/login/use-device-code-unsupported-host ✅ ❌ ❌
TestAccept/cmd/auth/login/use-device-code-wrong-code ✅ ❌ ❌
TestAccept/cmd/auth/login/use-device-code-client-not-allowed: branch ✅ | main (66fce77) ❌ | latest (v1.22.1) ❌

main (66fce77):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-client-not-allowed/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-client-not-allowed2944204845/002/output.txt
        @@ -1,3 +1,26 @@
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code --client-id custom-client-id
        -Error: device authorization: Client is not allowed to use device code login (error code: unauthorized_client)
        +Error: unknown flag: --use-device-code
        +
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +

latest (v1.22.1): same output as main (66fce77)

TestAccept/cmd/auth/login/use-device-code-nominal: branch ✅ | main (66fce77) ❌ | latest (v1.22.1) ❌

main (66fce77):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-nominal/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-nominal2173342866/002/output.txt
        @@ -2,55 +2,29 @@
         === Login with a host
         
         >>> [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Profile test was successfully saved
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
         
        ->>> [CLI] auth token --profile test
        -json.access_token = "oauth-token";
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
         
        ->>> [CLI] auth profiles
        -Name            Host                    Valid
        -test (Default)  [DATABRICKS_URL]  YES
         
        -=== Login again with the host from the saved profile
        -
        ->>> [CLI] auth login --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        -
        -And enter the code:
        -WDJB-MJHT
        -
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Profile test was successfully saved
        -
        ->>> [CLI] auth token --profile test
        -json.access_token = "oauth-token";
        -
        ->>> print_requests.py --oneline //oidc/v1/device/auth //oidc/v1/token
        -{"method": "POST", "path": "/oidc/v1/device/auth", "raw_body": "client_id=databricks-cli&scope=offline_access+all-apis"}
        -{"method": "POST", "path": "/oidc/v1/token", "raw_body": "client_id=databricks-cli&confirmation_code=FTFAQQKY&device_code=device-code-1&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code"}
        -{"method": "POST", "path": "/oidc/v1/device/auth", "raw_body": "client_id=databricks-cli&scope=offline_access+all-apis"}
        -{"method": "POST", "path": "/oidc/v1/token", "raw_body": "client_id=databricks-cli&confirmation_code=FTFAQQKY&device_code=device-code-2&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code"}
        -
        -=== Login with custom scopes
        -
        ->>> [CLI] auth login --host [DATABRICKS_URL] --profile scoped --use-device-code --scopes sql
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        -
        -And enter the code:
        -WDJB-MJHT
        -
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Profile scoped was successfully saved
        -
        ->>> print_requests.py --oneline //oidc/v1/device/auth //oidc/v1/token
        -{"method": "POST", "path": "/oidc/v1/device/auth", "raw_body": "client_id=databricks-cli&scope=offline_access+sql"}
        -{"method": "POST", "path": "/oidc/v1/token", "raw_body": "client_id=databricks-cli&confirmation_code=FTFAQQKY&device_code=device-code-3&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code"}
        +Exit code: 1
        
    acceptance_test.go:1278: Missing output file: out.databrickscfg

latest (v1.22.1): same output as main (66fce77)

TestAccept/cmd/auth/login/use-device-code-precondition: branch ✅ | main (66fce77) ❌ | latest (v1.22.1) ❌

main (66fce77):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-precondition/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-precondition409024379/002/output.txt
        @@ -2,15 +2,107 @@
         === Device code login is disabled by default
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Error: --use-device-code is experimental. Set DATABRICKS_CLI_DEVICE_CODE=true to enable it
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Inputs device code login cannot honor are rejected
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code --resource https://resource.test
        -Error: --use-device-code cannot be combined with --resource
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code --skip-workspace
        -Error: --use-device-code cannot be combined with --skip-workspace
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --profile scoped --use-device-code
        -Error: --use-device-code cannot be used with profile scoped because its login is scoped to resources. Log in without --use-device-code
        +Error: unknown flag: --use-device-code
        +
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        
FAIL

latest (v1.22.1):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-precondition/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-precondition508583321/002/output.txt
        @@ -2,15 +2,107 @@
         === Device code login is disabled by default
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Error: --use-device-code is experimental. Set DATABRICKS_CLI_DEVICE_CODE=true to enable it
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Inputs device code login cannot honor are rejected
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code --resource https://resource.test
        -Error: --use-device-code cannot be combined with --resource
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code --skip-workspace
        -Error: --use-device-code cannot be combined with --skip-workspace
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --profile scoped --use-device-code
        -Error: --use-device-code cannot be used with profile scoped because its login is scoped to resources. Log in without --use-device-code
        +Error: unknown flag: --use-device-code
        +
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
TestAccept/cmd/auth/login/use-device-code-unsupported-host: branch ✅ | main (66fce77) ❌ | latest (v1.22.1) ❌

main (66fce77):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-unsupported-host/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-unsupported-host1376506641/002/output.txt
        @@ -2,29 +2,170 @@
         === No host
         
         >>> musterr [CLI] auth login --profile new-profile --use-device-code
        -Error: --use-device-code requires a workspace host. Pass it as an argument or with --host
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Account host
         
         >>> musterr [CLI] auth login --host https://accounts.cloud.databricks.test --profile test --use-device-code
        -Error: --use-device-code is only supported for workspace hosts
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --profile account --use-device-code
        -Error: --use-device-code is only supported for workspace hosts
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Unified host
         
         >>> DATABRICKS_DISCOVERY_URL=[DATABRICKS_URL]/oidc/accounts/spog-acct-123/.well-known/oauth-authorization-server musterr [CLI] auth login --host [DATABRICKS_URL] --use-device-code
        -Error: --use-device-code is only supported for workspace hosts
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Workspace without device code login
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Error: device code login is not enabled for this workspace
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         >>> musterr [CLI] auth login --profile workspace --use-device-code
        -Error: device code login is not enabled for this workspace
        +Error: unknown flag: --use-device-code
         
        +Usage:
        +  databricks auth login [PROFILE] [flags]
        +
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Device authorization requests
         
         >>> print_requests.py //oidc/v1/device/auth
        +File [OUTPUT_DIR]/out.requests.txt not found
        +
        +Exit code: 1

latest (v1.22.1): same output as main (66fce77)

TestAccept/cmd/auth/login/use-device-code-wrong-code: branch ✅ | main (66fce77) ❌ | latest (v1.22.1) ❌

main (66fce77):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-wrong-code/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-wrong-code386731191/002/output.txt
        @@ -2,38 +2,85 @@
         === Login fails when no confirmation code is provided
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Error: reading confirmation code: EOF
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
         
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Login fails after 3 wrong confirmation codes
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (2 attempts left).
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (1 attempt left).
        -Confirmation code: Error: Invalid confirmation code (error code: invalid_request). Start login from scratch
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
         
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Login succeeds after re-entering the confirmation code
         
         >>> [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (2 attempts left).
        -Confirmation code: Confirmation code: Profile test was successfully saved
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
        +Exit code: 1

latest (v1.22.1):

acceptance_test.go:1307: Diff:
        --- cmd/auth/login/use-device-code-wrong-code/output.txt
        +++ /tmp/TestAcceptcmdauthloginuse-device-code-wrong-code2227428307/002/output.txt
        @@ -2,38 +2,85 @@
         === Login fails when no confirmation code is provided
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Error: reading confirmation code: EOF
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
         
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Login fails after 3 wrong confirmation codes
         
         >>> musterr [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (2 attempts left).
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (1 attempt left).
        -Confirmation code: Error: Invalid confirmation code (error code: invalid_request). Start login from scratch
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
         
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
         === Login succeeds after re-entering the confirmation code
         
         >>> [CLI] auth login --host [DATABRICKS_URL] --profile test --use-device-code
        -Using a browser on another device, visit:
        -[DATABRICKS_URL]/device/verification
        +Error: unknown flag: --use-device-code
         
        -And enter the code:
        -WDJB-MJHT
        +Usage:
        +  databricks auth login [PROFILE] [flags]
         
        -Once finished, enter the confirmation code provided in your browser.
        -Confirmation code: Invalid confirmation code (error code: invalid_request). Enter the confirmation code again (2 attempts left).
        -Confirmation code: Confirmation code: Profile test was successfully saved
        +Flags:
        +      --client-id string       OAuth client ID to use for U2M authentication
        +      --configure-cluster      Prompts to configure cluster
        +      --configure-serverless   Prompts to configure serverless
        +  -h, --help                   help for login
        +      --resource stringArray   RFC 8707 resource indicator to scope the login to (repeatable). Requires --host.
        +      --scopes string          Comma-separated list of OAuth scopes to request (defaults to 'all-apis')
        +      --skip-workspace         Skip workspace selection for account-level access
        +      --timeout duration       Timeout for completing login challenge in the browser (default 1h0m0s)
        +
        +Global Flags:
        +      --account-id string     Databricks Account ID
        +      --debug                 enable debug logging
        +      --host string           Databricks Host
        +  -o, --output type           output type: text or json (default text)
        +  -p, --profile string        ~/.databrickscfg profile
        +  -t, --target string         bundle target to use (if applicable)
        +      --workspace-id string   Databricks Workspace ID
        +
        +
        +Exit code: 1
        
FAIL

The prompt's handling of a timed-out context is covered by unit tests,
and keeping stdin open in the acceptance test cost 5 seconds per run.

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

This branch has not been deployed

No deployments
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.

3 participants