Skip to content

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

Description

  • 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.

Activity

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

Metadata

Metadata

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