Skip to content
Open
2 changes: 2 additions & 0 deletions src/Accounts/Accounts/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
-->

## Upcoming Release
* Replaced hardcoded cloud-to-scope mappings in SSH credential factory with a static scope, enabling SSH authentication across all clouds.
* Deprecated the `-SshAuthScope` parameter in `Set-AzEnvironment` and `Add-AzEnvironment`. The SSH authentication scope is now determined automatically.
Comment on lines +22 to +23
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

These ChangeLog entries are fairly implementation-focused (e.g., “cloud-to-scope mappings in SSH credential factory”). Since the ChangeLog is user-facing, consider rephrasing in terms of user impact (e.g., SSH certificate auth now works across Azure clouds without configuring -SshAuthScope, and -SshAuthScope is deprecated).

Suggested change
* Replaced hardcoded cloud-to-scope mappings in SSH credential factory with a static scope, enabling SSH authentication across all clouds.
* Deprecated the `-SshAuthScope` parameter in `Set-AzEnvironment` and `Add-AzEnvironment`. The SSH authentication scope is now determined automatically.
* Improved SSH (Secure Shell) certificate authentication for Az SSH cmdlets across all Azure clouds.
- SSH certificate authentication now works across all Azure clouds without configuring the `-SshAuthScope` parameter.
- The `-SshAuthScope` parameter in `Set-AzEnvironment` and `Add-AzEnvironment` is deprecated, and the SSH authentication scope is now determined automatically.

Copilot uses AI. Check for mistakes.

## Version 5.3.3
* Updated MSAL to 4.82.1 to fix an issue with ARM endpoint discovery.
Expand Down
2 changes: 1 addition & 1 deletion src/Accounts/Accounts/Environment/AddAzureRMEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public string DataLakeAudience
public string MicrosoftGraphUrl { get; set; }

[Parameter(ParameterSetName = EnvironmentPropertiesParameterSet, Mandatory = false, ValueFromPipelineByPropertyName = true,
HelpMessage = "The scope for authentication when SSH to an Azure VM.")]
HelpMessage = "This parameter is deprecated and will be removed in a future release. The SSH authentication scope is now determined automatically and does not need to be configured.")]
public string SshAuthScope { get; set; }
Comment on lines 228 to 230
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

-SshAuthScope is now documented as deprecated, but the cmdlet still persists the value into the environment (AzureSshAuthScope). Since the SSH credential flow no longer reads this endpoint, consider emitting a warning when the parameter is supplied (and/or ignoring it) to avoid users thinking it will affect SSH auth.

Copilot uses AI. Check for mistakes.

protected override bool RequireDefaultContext()
Expand Down
2 changes: 1 addition & 1 deletion src/Accounts/Accounts/Environment/SetAzureRMEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public string DataLakeAudience
public string MicrosoftGraphUrl { get; set; }

[Parameter(ParameterSetName = EnvironmentPropertiesParameterSet, Mandatory = false, ValueFromPipelineByPropertyName = true,
HelpMessage = "The scope for authentication when SSH to an Azure VM.")]
HelpMessage = "This parameter is deprecated and will be removed in a future release. The SSH authentication scope is now determined automatically and does not need to be configured.")]
public string SshAuthScope { get; set; }
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

-SshAuthScope is now documented as deprecated, but the cmdlet still persists the value into the environment (AzureSshAuthScope). Since the SSH credential flow no longer reads this endpoint, consider emitting a warning when the parameter is supplied (and/or ignoring it) to avoid users thinking it will affect SSH auth.

Suggested change
public string SshAuthScope { get; set; }
[Obsolete("This parameter is deprecated and is ignored. SSH authentication scope is determined automatically.")]
public string SshAuthScope
{
get
{
// This parameter is deprecated and intentionally ignored.
// Returning null ensures that any existing code paths that read this
// property will not use a user supplied value.
return null;
}
set
{
if (!string.IsNullOrEmpty(value))
{
// Emit a warning so users know this parameter no longer affects SSH authentication.
WriteWarning("The SshAuthScope parameter is deprecated and is ignored. SSH authentication scope is now determined automatically and does not need to be configured.");
}
}
}

Copilot uses AI. Check for mistakes.

protected override bool RequireDefaultContext()
Expand Down
2 changes: 1 addition & 1 deletion src/Accounts/Accounts/help/Add-AzEnvironment.md
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ Accept wildcard characters: False
```

### -SshAuthScope
The scope for authentication when SSH to an Azure VM.
This parameter is deprecated and will be removed in a future release. The SSH authentication scope is now determined automatically and does not need to be configured.

```yaml
Type: System.String
Expand Down
2 changes: 1 addition & 1 deletion src/Accounts/Accounts/help/Set-AzEnvironment.md
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ Accept wildcard characters: False
```

### -SshAuthScope
The scope for authentication when SSH to an Azure VM.
This parameter is deprecated and will be removed in a future release. The SSH authentication scope is now determined automatically and does not need to be configured.

```yaml
Type: System.String
Expand Down
17 changes: 4 additions & 13 deletions src/Accounts/Authentication/Factories/SshCredentialFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Models;
using Microsoft.Azure.Commands.Common.Authentication.Properties;
using Microsoft.Azure.Commands.Common.Exceptions;
using Microsoft.Identity.Client.SSHCertificates;
using Microsoft.WindowsAzure.Commands.Utilities.Common;

Expand All @@ -30,13 +29,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Factories
{
public class SshCredentialFactory : ISshCredentialFactory
{
// kept for backward-compatibility
private readonly Dictionary<string, string> CloudToScope = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
{
{ EnvironmentName.AzureCloud, AzureEnvironmentConstants.AzureSshAuthScope },
{ EnvironmentName.AzureChinaCloud, AzureEnvironmentConstants.ChinaSshAuthScope },
{ EnvironmentName.AzureUSGovernment, AzureEnvironmentConstants.USGovernmentSshAuthScope },
};
private const string AadSshLoginForLinuxServerAppId = "ce6ff14a-7fdc-4685-bbe0-f6afdfcfa8e0";

private string CreateJwk(RSAParameters rsaKeyInfo, out string keyId)
{
Expand Down Expand Up @@ -70,8 +63,7 @@ public SshCredential GetSshCredential(IAzureContext context, RSAParameters rsaKe
}

var publicClient = tokenCacheProvider.CreatePublicClient(context.Environment.ActiveDirectoryAuthority, context.Tenant.Id);
string scope = GetAuthScope(context.Environment)
?? throw new AzPSKeyNotFoundException(string.Format(Resources.ErrorSshAuthScopeNotSet, context.Environment.Name));
string scope = GetAuthScope();
List<string> scopes = new List<string>() { scope };
var jwk = CreateJwk(rsaKeyInfo, out string keyId);

Expand All @@ -90,10 +82,9 @@ public SshCredential GetSshCredential(IAzureContext context, RSAParameters rsaKe
return resultToken;
}

private string GetAuthScope(IAzureEnvironment environment)
private string GetAuthScope()
{
return environment.GetProperty(AzureEnvironment.ExtendedEndpoint.AzureSshAuthScope)
?? CloudToScope.GetValueOrDefault(environment.Name.ToLower(), null);
return $"{AadSshLoginForLinuxServerAppId}/.default";
}
}
}