Skip to content

[Identity] azure.identity.aio.AzureCliCredential unusable due to malformed command line #12048

@cdunklau

Description

@cdunklau
  • Package Name: azure-identity
  • Package Version: 1.4.0b5
  • Operating System: macOS Catalina 10.15.5
  • Python Version: 3.7.5

Describe the bug

The async flavor of AzureCliCredential doesn't properly construct the args for its az account get-access-token call, so /bin/sh (bash on my system) barfs:

<snip>

  File "/.../venv/lib/python3.7/site-packages/azure/identity/aio/_credentials/azure_cli.py", line 48, in get_token
    output = await _run_command(COMMAND_LINE.format(resource))
  File "/.../venv/lib/python3.7/site-packages/azure/identity/aio/_credentials/azure_cli.py", line 96, in _run_command
    raise ClientAuthenticationError(message=message)
azure.core.exceptions.ClientAuthenticationError: /bin/sh: - : invalid option
Usage:  /bin/sh [GNU long option] [option] ...
        /bin/sh [GNU long option] [option] script-file ...
GNU long options:
        --debug
        --debugger
        --dump-po-strings

<snip>

It looks like this is the culprit:

async def _run_command(command):
if sys.platform.startswith("win"):
args = ("cmd", "/c " + command)
else:
args = ("/bin/sh", "-c " + command)

I'm not intimately familiar with how Windows parses CLAs but that's definitely wrong on *nix, it should be args = ("/bin/sh", "-c", command). Changing to that fixes the problem for me.

Side note, it seems odd to use the shell at all. Is there a particular reason for that, as opposed to just giving the az command line directly, e.g. args = ('az', 'account', 'get-access-token', '--output', 'json', '--resource' 'https://vault.azure.net')? This would also remove the need for the platform-specific code.

To Reproduce

Change the vault name and secret name below, and run it on Mac. Linux probably suffers as well, but I'm not sure if Windows is affected:

import sys
import logging
import asyncio

from azure.identity.aio import AzureCliCredential
from azure.keyvault.secrets.aio import SecretClient


logging.basicConfig(level=logging.DEBUG, stream=sys.stderr)

async def run():
    async with AzureCliCredential() as credential:

        async with SecretClient(
            vault_url="https://REPLACEME.vault.azure.net/",
            credential=credential,
        ) as secret_client:

            secret = await secret_client.get_secret('REPLACEME-SECRET-NAME')
            print(secret.name)
            print(secret.value)

asyncio.run(run())

Observe azure.core.exceptions.ClientAuthenticationError: /bin/sh: - : invalid option

Expected behavior

The above should print the name and value for the secret.

Metadata

Metadata

Assignees

Labels

Azure.IdentityClientThis issue points to a problem in the data-plane of the library.bugThis issue requires a change to an existing behavior in the product in order to be resolved.customer-reportedIssues that are reported by GitHub users external to the Azure organization.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions