diff --git a/scripts/release/standalone/build_binary_tar_gz.py b/scripts/release/standalone/build_binary_tar_gz.py index 1007351c4e5..cc38a55f5e3 100644 --- a/scripts/release/standalone/build_binary_tar_gz.py +++ b/scripts/release/standalone/build_binary_tar_gz.py @@ -76,7 +76,7 @@ AZURE_CLI_CORE_DIR = SRC_DIR / "azure-cli-core" REQUIREMENTS_FILES = { "linux": SRC_DIR / "azure-cli" / "requirements.py3.Linux.txt", - "macos": SRC_DIR / "azure-cli" / "requirements.py3.Darwin.txt", + "macos": SRC_DIR / "azure-cli" / "requirements.py3.Darwin.Broker.txt", } # Package configuration diff --git a/src/azure-cli-core/azure/cli/core/_profile.py b/src/azure-cli-core/azure/cli/core/_profile.py index afd66504e2b..a56235abafc 100644 --- a/src/azure-cli-core/azure/cli/core/_profile.py +++ b/src/azure-cli-core/azure/cli/core/_profile.py @@ -975,8 +975,10 @@ def _create_identity_instance(cli_ctx, authority, tenant_id=None, client_id=None # On Windows, use core.enable_broker_on_windows=false to disable broker (WAM) for authentication. enable_broker_on_windows = cli_ctx.config.getboolean('core', 'enable_broker_on_windows', fallback=True) + # On macOS, broker authentication is opt-in. Use core.enable_broker_on_mac=true to enable it. + enable_broker_on_mac = cli_ctx.config.getboolean('core', 'enable_broker_on_mac', fallback=False) from .telemetry import set_broker_info - set_broker_info(enable_broker_on_windows) + set_broker_info(enable_broker_on_windows, enable_broker_on_mac) # PREVIEW: In Azure Stack environment, use core.instance_discovery=false to disable MSAL's instance discovery. instance_discovery = cli_ctx.config.getboolean('core', 'instance_discovery', True) @@ -985,4 +987,5 @@ def _create_identity_instance(cli_ctx, authority, tenant_id=None, client_id=None encrypt=encrypt, use_msal_http_cache=use_msal_http_cache, enable_broker_on_windows=enable_broker_on_windows, + enable_broker_on_mac=enable_broker_on_mac, instance_discovery=instance_discovery) diff --git a/src/azure-cli-core/azure/cli/core/auth/identity.py b/src/azure-cli-core/azure/cli/core/auth/identity.py index 91629e89441..b2c04043277 100644 --- a/src/azure-cli-core/azure/cli/core/auth/identity.py +++ b/src/azure-cli-core/azure/cli/core/auth/identity.py @@ -58,7 +58,7 @@ class Identity: # pylint: disable=too-many-instance-attributes _service_principal_store_instance = None def __init__(self, authority, tenant_id=None, client_id=None, encrypt=False, use_msal_http_cache=True, - enable_broker_on_windows=None, instance_discovery=None): + enable_broker_on_windows=None, enable_broker_on_mac=None, instance_discovery=None): """ :param authority: Authentication authority endpoint. For example, - AAD: https://login.microsoftonline.com @@ -74,6 +74,7 @@ def __init__(self, authority, tenant_id=None, client_id=None, encrypt=False, use self._encrypt = encrypt self._use_msal_http_cache = use_msal_http_cache self._enable_broker_on_windows = enable_broker_on_windows + self._enable_broker_on_mac = enable_broker_on_mac self._instance_discovery = instance_discovery # Build the authority in MSAL style @@ -111,9 +112,10 @@ def _msal_app_kwargs(self): @property def _msal_public_app_kwargs(self): """kwargs for creating PublicClientApplication.""" - # enable_broker_on_windows can only be used on PublicClientApplication. + # enable_broker_on_windows and enable_broker_on_mac can only be used on PublicClientApplication. return {**self._msal_app_kwargs, "enable_broker_on_windows": self._enable_broker_on_windows, + "enable_broker_on_mac": self._enable_broker_on_mac, "enable_pii_log": True} @property diff --git a/src/azure-cli-core/azure/cli/core/telemetry.py b/src/azure-cli-core/azure/cli/core/telemetry.py index b0ce7d8d7cf..1bb248f7bdf 100644 --- a/src/azure-cli-core/azure/cli/core/telemetry.py +++ b/src/azure-cli-core/azure/cli/core/telemetry.py @@ -77,6 +77,7 @@ def __init__(self, correlation_id=None, application=None): self.user_agent = None # authentication-related self.enable_broker_on_windows = None + self.enable_broker_on_mac = None self.msal_telemetry = None self.login_experience_v2 = None self.agentic_session = False @@ -238,6 +239,7 @@ def _get_azure_cli_properties(self): set_custom_properties(result, 'SecretNames', ','.join(self.secret_names or [])) # authentication-related set_custom_properties(result, 'EnableBrokerOnWindows', str(self.enable_broker_on_windows)) + set_custom_properties(result, 'EnableBrokerOnMac', str(self.enable_broker_on_mac)) set_custom_properties(result, 'MsalTelemetry', self.msal_telemetry) set_custom_properties(result, 'LoginExperienceV2', str(self.login_experience_v2)) set_custom_properties(result, 'AgenticSession', str(self.agentic_session)) @@ -485,9 +487,10 @@ def set_region_identified(region_input, region_identified): # region authentication-related @decorators.suppress_all_exceptions() -def set_broker_info(enable_broker_on_windows): - # Log the value of `enable_broker_on_windows` +def set_broker_info(enable_broker_on_windows, enable_broker_on_mac=None): + # Log the value of `enable_broker_on_windows` and `enable_broker_on_mac` _session.enable_broker_on_windows = enable_broker_on_windows + _session.enable_broker_on_mac = enable_broker_on_mac @decorators.suppress_all_exceptions() diff --git a/src/azure-cli-core/azure/cli/core/tests/test_profile.py b/src/azure-cli-core/azure/cli/core/tests/test_profile.py index 9254ca1744d..4aea607d8c6 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_profile.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_profile.py @@ -11,7 +11,7 @@ from copy import deepcopy from unittest import mock -from azure.cli.core._profile import (Profile, SubscriptionFinder, _attach_token_tenant, +from azure.cli.core._profile import (Profile, SubscriptionFinder, _attach_token_tenant, _create_identity_instance, _transform_subscription_for_multiapi, _TENANT_LEVEL_ACCOUNT_NAME) from azure.cli.core.azclierror import AuthenticationError @@ -1441,6 +1441,28 @@ def test_logout_all(self, logout_all_users_mock, logout_all_service_principal_mo logout_all_users_mock.assert_called_once() logout_all_service_principal_mock.assert_called_once() + @mock.patch('azure.cli.core.auth.identity.Identity', autospec=True) + def test_create_identity_instance_broker_on_mac_default_opt_in(self, identity_mock): + # Verify that broker on macOS is opt-in: default is False unless user sets + # core.enable_broker_on_mac=true. See CLIPS#55. + cli = DummyCli() + _create_identity_instance(cli, authority='https://login.microsoftonline.com') + _, kwargs = identity_mock.call_args + self.assertEqual(kwargs['enable_broker_on_mac'], False) + # Windows broker remains opt-out (default True). + self.assertEqual(kwargs['enable_broker_on_windows'], True) + + @mock.patch('azure.cli.core.auth.identity.Identity', autospec=True) + def test_create_identity_instance_broker_on_mac_opt_in_enabled(self, identity_mock): + cli = DummyCli() + cli.config.set_value('core', 'enable_broker_on_mac', 'true') + try: + _create_identity_instance(cli, authority='https://login.microsoftonline.com') + finally: + cli.config.remove_option('core', 'enable_broker_on_mac') + _, kwargs = identity_mock.call_args + self.assertEqual(kwargs['enable_broker_on_mac'], True) + @mock.patch('azure.cli.core._profile.SubscriptionFinder._create_subscription_client', autospec=True) @mock.patch('azure.cli.core.auth.identity.Identity.get_user_credential', autospec=True) def test_refresh_accounts_one_user_account(self, get_user_credential_mock, create_subscription_client_mock): diff --git a/src/azure-cli-core/setup.py b/src/azure-cli-core/setup.py index bc0c5828e34..6f3e4936d37 100644 --- a/src/azure-cli-core/setup.py +++ b/src/azure-cli-core/setup.py @@ -56,8 +56,8 @@ 'knack~=0.14.0', 'microsoft-security-utilities-secret-masker~=1.0.0b4', 'msal-extensions==1.3.1', - 'msal[broker]==1.36.0; sys_platform == "win32"', - 'msal==1.36.0; sys_platform != "win32"', + 'msal[broker]==1.36.0; sys_platform == "win32" or sys_platform == "darwin"', + 'msal==1.36.0; sys_platform != "win32" and sys_platform != "darwin"', 'packaging>=20.9', # pkginfo>=1.12.0 reads the spec-defined wheel METADATA / unpacked .dist-info # layout produced by modern wheel/setuptools (no metadata.json). Required so diff --git a/src/azure-cli/requirements.py3.Darwin.Broker.txt b/src/azure-cli/requirements.py3.Darwin.Broker.txt new file mode 100644 index 00000000000..772322b300e --- /dev/null +++ b/src/azure-cli/requirements.py3.Darwin.Broker.txt @@ -0,0 +1,3 @@ +-r requirements.py3.Darwin.txt +msal[broker]==1.36.0 +pymsalruntime==0.20.6 \ No newline at end of file