diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 645c58d43caf..41d76abbbfaf 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed `AzureCliCredential` fails in non-interactive environments due to hardcoded `/bin/sh` PATH resolution on MacOS and Linux. + ### Other Changes - Removed unused jetty, redisson, and lettuce-core dependencies. diff --git a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientBase.java b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientBase.java index d8c3bd0a8103..0b454f9db894 100644 --- a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientBase.java +++ b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientBase.java @@ -606,6 +606,7 @@ AccessToken getTokenFromAzureCLIAuthentication(StringBuilder azCommand) { } ProcessBuilder builder = new ProcessBuilder(starter, switcher, azCommand.toString()); + ensureCliPath(builder); // Redirects stdin to dev null, helps to avoid messages sent in by the cmd process to upgrade etc. builder.redirectInput(ProcessBuilder.Redirect.from(IdentityUtil.NULL_FILE)); @@ -679,6 +680,22 @@ AccessToken getTokenFromAzureCLIAuthentication(StringBuilder azCommand) { return token; } + /** + * Ensures that the process environment PATH contains common Azure CLI installation directories + * when invoking CLI commands in non-interactive environments. + * Azure CLI is commonly installed via Homebrew on macOS and Linux, which places the `az` executable + * under locations such as {@code /usr/local/bin} (Intel) or {@code /opt/homebrew/bin} (Apple Silicon). + */ + private void ensureCliPath(ProcessBuilder builder) { + if (!isWindowsPlatform()) { + Map env = builder.environment(); + String path = env.getOrDefault("PATH", ""); + if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { + env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); + } + } + } + AccessToken getTokenFromAzureDeveloperCLIAuthentication(StringBuilder azdCommand) { AccessToken token; try { @@ -693,6 +710,7 @@ AccessToken getTokenFromAzureDeveloperCLIAuthentication(StringBuilder azdCommand } ProcessBuilder builder = new ProcessBuilder(starter, switcher, azdCommand.toString()); + ensureCliPath(builder); // Redirects stdin to dev null, helps to avoid messages sent in by the cmd process to upgrade etc. builder.redirectInput(ProcessBuilder.Redirect.from(IdentityUtil.NULL_FILE));