-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Describe the bug
Context
- an interactive
az logincommand is being invoked by a Python script that captures its stdout - this invocation of
az loginmust be interactive, as the Python script is bootstrap IaC that creates security contexts that will be the non-interactive security contexts used by later stage automation - the Python script uses the interactive user's security context for subsequent
az clicommands to accomplish its work of setting up the security contexts for Azure DevOps automated pipelines az loginis causing the Python script to throw a JSON parsing error becauseaz loginis emitting the following plain text status message in the stdout stream when the Python script is only expecting properly formatted JSON in stdoutOpening in existing browser session.
- while
az loginhas a console mode user interface when performing an interactive login, the Python script has turned off this console mode user interface by issuingaz config set core.login_experience_v2=offbefore running itsaz logincommand - The Python script executes
az login --output json --allow-no-subscriptions --tenant <tenant_id>to perform the interactive login and it is that syntax that generates the mixed plain text and JSON stdout output. - Having turned off the console mode user interface, and specified the JSON output format on the
az logincommand line, the Python script expects only JSON on stdout, and expects plain text status messages to be emitted on stderr az loginalready emits other plain text status (not error) messages on stderr
Assumption: az login should NEVER emit any plain text out the stdout output stream in certain conditions
- When:
- the console mode user interface has been turned off
- the JSON output format has been specified
- the above two conditions should indicate to
az loginthat while it is being invoked as an interactive (via browser) login, it is still being invoked from an automation context, and mixing plain text and JSON in its stdout stream is inappropriate for reliable automation.
Bug
The bug is that status output in one output format (plain text) is being mixed with the normal output in a different format (JSON) in a context where az login should be able determine that it is not OK to mix the output formats. By turning off the console mode user interface, and by specifying JSON explicitly as an output format on the command line, the execution context for the invocation while still interactive (user based via a browser) is enabling automation, and should not intermix output formats. The bug is that it currently does intermix the output formats, when az login should be aware that it should not.
Potential Fixes
1. Emit the status message on stderr
- this preferred solution is consistent with the fact that other plain text status messages are already being emitted on stderr
2. Do not emit this plain text status message
- The user had to click on a box in the web browser, and thus has taken direct action and presumably is already aware of what they have done.
az cliusers can presumably be expected to be technical enough to find this status message unnecessary.
3. Embed the status message in a JSON object
- If this message MUST be emitted on stdout, then embed the status message in a JSON object, when the JSON output format is requested as shown in this example JSON
{ "status": "Opening in existing browser session." "output": [ { "cloudName": "AzureCloud", "homeTenantId": "<tenant_id>", "id": "<subscription_id>", "isDefault": false, "managedByTenants": [], "name": "<subscription_name>", "state": "Enabled", "tenantId": "<tenant_id>", "user": { "name": "<user_principal_name>", "type": "user" } } ] }
Related command
Relevant Earlier Command
The Python IaC script issues the following command before it issues the az login command that generates the problematic stdout output.
az config set core.login_experience_v2=off
- The intent of this command is to suppress the console mode user interface that the
az logincommand can present to allow the user to select the default subscription via stdin input. - By setting setting this
az cliconfiguration parameter before invokingaz login, the Python IaC script is attempting to ensure that stdout is not used for plain text output.
Problematic Command
The Python IaC script issues the following az login command to generate the problematic stdout output.
az login --output json --allow-no-subscriptions --tenant <tenant_id>
Errors
No Errors
The az cli does not produce an error message, but produces a problematic plain text status message on the stdout stream, when only JSON output was requested and expected.
Example Problematic Output
- the problematic plain text is bolded in the sample output to make it easier to pick out.
stderr
A web browser has been opened at https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with
az login --use-device-code
stdout
Opening in existing browser session.
[ { "cloudName": "AzureCloud", "homeTenantId": "<tenant_id>", "id": "<subscription_id>", "isDefault": false, "managedByTenants": [], "name": "<subscription_name>", "state": "Enabled", "tenantId": "<tenant_id>", "user": { "name": "<user_principal_name>", "type": "user" } } ]
Issue script & Debug output
--debug option not used
Adding the --debug option to the two commands below that the Python IaC script issues that generates the problematic output does not help in understanding this bug.
Command Sequence to Generate problematic output
-
az config set core.login_experience_v2=off
-
az login --output json --tenant <tenant_id> --allow-no-subscriptions
Expected behavior
Context of Expected Behaviour
- when the subscription selector is turned off
- JSON output is explicitly requested on the command line
- an interactive login is being performed
the output emitted on stdout should only contain JSON
Example Fixed Output - Preferred Solution
- This fixed output emits the problematic plain text status message on stderr instead of stdout
- This is consistent with the other plain text status messages clearly already being emitted on stderr
stderr
A web browser has been opened at https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with
az login --use-device-code
Opening in existing browser session.
stdout
[ { "cloudName": "AzureCloud", "homeTenantId": "<tenant_id>", "id": "<subscription_id>", "isDefault": false, "managedByTenants": [], "name": "<subscription_name>", "state": "Enabled", "tenantId": "<tenant_id>", "user": { "name": "<user_principal_name>", "type": "user" } } ]
Environment Summary
az cli Version Information
| Component | Version |
|---|---|
| azure-cli | 2.81.0 |
| core | 2.81.0 |
| telemetry | 1.1.0 |
az cli Extensions
| Component | Version |
|---|---|
| azure-devops | 1.0.2 |
az cli Dependencies:
| Component | Version |
|---|---|
| msal | 1.34.0b1 |
| azure-mgmt-resource | 23.3.0 |
az cli Special Folder Information
| Location | Value |
|---|---|
| Python location | '/opt/az/bin/python3' |
| Config directory | '/home/butler/.azure' |
| Extensions directory | '/home/butler/.azure/cliextensions' |
az cli Python Version
Python (Linux) 3.13.9 (main, Nov 26 2025, 00:44:06) [GCC 13.3.0]
Legal docs and information: aka.ms/AzureCliLegal
Additional context
Potential Fixes
1. Emit the status message on stderr
- this preferred solution is consistent with the fact that other plain text status messages are already being emitted on stderr
2. Do not emit this plain text status message
- The user had to click on a box in the web browser, and thus has taken direct action and presumably is already aware of what they have done.
az cliusers can presumably be expected to be technical enough to find this status message unnecessary.
3. Embed the status message in a JSON object
- If this message MUST be emitted on stdout, then embed the status message in a JSON object, when the JSON output format is requested as shown in this example JSON
{ "status": "Opening in existing browser session." "output": [ { "cloudName": "AzureCloud", "homeTenantId": "<tenant_id>", "id": "<subscription_id>", "isDefault": false, "managedByTenants": [], "name": "<subscription_name>", "state": "Enabled", "tenantId": "<tenant_id>", "user": { "name": "<user_principal_name>", "type": "user" } } ] }