Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions msal/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import time
import logging
import platform
import sys
import warnings
from threading import Lock
Expand Down Expand Up @@ -815,6 +816,21 @@ def _decide_broker(self, allow_broker, enable_pii_log):
and not self.authority.is_adfs
and not self.authority._is_b2c
)
if (
Comment thread
ashok672 marked this conversation as resolved.
self._enable_broker
and sys.platform == "darwin"
and platform.machine() != "arm64"
):
# Broker on macOS is supported only on Apple Silicon (arm64).
# Anything else on darwin -- Intel Macs, and an x86_64 Python
# running under Rosetta -- is excluded by product policy,
# regardless of whether a broker is installed on the device.
# This is an allowlist so that an unrecognized architecture
# errs on the side of not using the broker.
self._enable_broker = False
logger.warning(
"Broker on macOS is supported only on Apple Silicon (arm64). "
"We will fallback to non-broker.")
Comment thread
ashok672 marked this conversation as resolved.
Comment thread
Copilot marked this conversation as resolved.
if self._enable_broker:
try:
_init_broker(enable_pii_log)
Expand Down Expand Up @@ -2167,17 +2183,17 @@ def __init__(

1. You can set any combination of the following opt-in parameters to true:

+--------------------------+-----------------------------------+------------------------------------------------------------------------------------+
| Opt-in flag | If app will run on | App has registered this as a Desktop platform redirect URI in Azure Portal |
+==========================+===================================+====================================================================================+
| enable_broker_on_windows | Windows 10+ | ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id |
+--------------------------+-----------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_wsl | WSL | ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id |
+--------------------------+-----------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_mac | Mac with Company Portal installed | msauth.com.msauth.unsignedapp://auth |
+--------------------------+-----------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_linux | Linux with Intune installed | ``https://login.microsoftonline.com/common/oauth2/nativeclient`` (MUST be enabled) |
+--------------------------+-----------------------------------+------------------------------------------------------------------------------------+
+--------------------------+-------------------------------------------------+------------------------------------------------------------------------------------+
| Opt-in flag | If app will run on | App has registered this as a Desktop platform redirect URI in Azure Portal |
+==========================+=================================================+====================================================================================+
| enable_broker_on_windows | Windows 10+ | ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id |
+--------------------------+-------------------------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_wsl | WSL | ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id |
+--------------------------+-------------------------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_mac | Apple Silicon Mac with Company Portal installed | msauth.com.msauth.unsignedapp://auth |
+--------------------------+-------------------------------------------------+------------------------------------------------------------------------------------+
| enable_broker_on_linux | Linux with Intune installed | ``https://login.microsoftonline.com/common/oauth2/nativeclient`` (MUST be enabled) |
+--------------------------+-------------------------------------------------+------------------------------------------------------------------------------------+

2. Install broker dependency,
e.g. ``pip install msal[broker]>=1.33,<2``.
Expand Down Expand Up @@ -2214,7 +2230,10 @@ def __init__(
New in MSAL Python 1.25.0.

:param boolean enable_broker_on_mac:
This setting is only effective if your app is running on Mac.
This setting is only effective if your app is running on
an Apple Silicon (arm64) Mac.
Broker is not supported on Intel-based Macs, where this setting
is ignored and MSAL will fall back to non-broker.
This parameter defaults to None, which means MSAL will not utilize a broker.

New in MSAL Python 1.31.0.
Expand Down
72 changes: 72 additions & 0 deletions tests/intel_mac_broker_smoke_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Manual smoke test for the Intel-Mac broker-disable gate.

This script is intentionally credential-free and runs in a few seconds.
It exercises the production decision logic in ``ClientApplication._decide_broker``
on real hardware (no mocks), which is the one thing the unit tests in
``test_application.py::TestBrokerDisabledOnIntelMac`` cannot do — CI runs on
``ubuntu-latest`` only, so ``sys.platform`` is patched there.

How to run::

pip install --force-reinstall "msal[broker]" # or your local checkout
python tests/intel_mac_broker_smoke_test.py

Expected outcomes:

* Apple Silicon Mac (``arm64``) with ``pymsalruntime`` installed:
``_enable_broker`` is ``True``.
* Intel Mac (``x86_64`` / ``i386``), or any other non-``arm64`` machine
(including an ``x86_64`` Python running under Rosetta):
``_enable_broker`` is ``False`` even though the opt-in was passed and even
if a broker is installed on the device.
* Non-Mac (Windows, Linux):
``enable_broker_on_mac`` is ignored — ``_enable_broker`` is ``False``.

The script asserts the expected outcome for the host it runs on and exits
non-zero if the gate misbehaves.
"""
import platform
import sys

import msal


_CLIENT_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" # Azure CLI, public
_AUTHORITY = "https://login.microsoftonline.com/organizations"


def _expected_broker_state():
if sys.platform != "darwin":
return False, "non-Mac platform — enable_broker_on_mac is a no-op"
if platform.machine() != "arm64":
return False, "not Apple Silicon — broker disabled by product policy"
return True, "Apple Silicon Mac — broker should be enabled"


def main():
print(f"sys.platform = {sys.platform!r}")
print(f"platform.machine() = {platform.machine()!r}")

expected, why = _expected_broker_state()
print(f"Expected _enable_broker = {expected} ({why})")

app = msal.PublicClientApplication(
_CLIENT_ID,
authority=_AUTHORITY,
enable_broker_on_mac=True, # Only opt in on Mac; this script validates the Mac gate.
)
actual = bool(app._enable_broker)
print(f"Actual _enable_broker = {actual}")

if actual != expected:
print(
"FAIL: Intel-Mac gate misbehaved. "
"See ClientApplication._decide_broker in msal/application.py.",
file=sys.stderr,
)
sys.exit(1)
print("PASS")


if __name__ == "__main__":
main()
50 changes: 50 additions & 0 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,7 @@ def test_client_id_should_be_a_valid_scope(self):


@patch("sys.platform", new="darwin") # Pretend running on Mac.
@patch("msal.application.platform.machine", new=Mock(return_value="arm64")) # Pretend Apple Silicon, because broker is not supported on Intel-based Macs.
@patch("msal.authority.tenant_discovery", new=Mock(return_value={
"authorization_endpoint": "https://contoso.com/placeholder",
"token_endpoint": "https://contoso.com/placeholder",
Expand Down Expand Up @@ -1663,6 +1664,7 @@ def test_should_fallback_when_pymsalruntime_failed_to_initialize_broker(self):


@patch("sys.platform", new="darwin") # Pretend running on Mac.
@patch("msal.application.platform.machine", new=Mock(return_value="arm64")) # Pretend Apple Silicon, because broker is not supported on Intel-based Macs.
@patch("msal.authority.tenant_discovery", new=Mock(return_value={
"authorization_endpoint": "https://contoso.com/placeholder",
"token_endpoint": "https://contoso.com/placeholder",
Expand Down Expand Up @@ -1748,6 +1750,54 @@ def test_app_did_not_register_redirect_uri_should_error_out(self):
self.assertEqual(result.get("error"), "broker_error")


@patch("sys.platform", new="darwin") # Pretend running on Mac.
@patch("msal.authority.tenant_discovery", new=Mock(return_value={
"authorization_endpoint": "https://contoso.com/placeholder",
"token_endpoint": "https://contoso.com/placeholder",
"issuer": "https://contoso.com/placeholder",
}))
@patch("msal.application._init_broker", new=Mock()) # Pretend pymsalruntime installed and working
class TestBrokerDisabledOnIntelMac(unittest.TestCase):
"""Broker is disabled on Intel-based Macs regardless of opt-in."""

@patch("msal.application.platform.machine", new=Mock(return_value="arm64"))
def test_broker_should_be_enabled_on_apple_silicon_mac(self):
app = msal.PublicClientApplication(
"client_id",
authority="https://login.microsoftonline.com/common",
enable_broker_on_mac=True,
)
self.assertTrue(app._enable_broker)

@patch("msal.application.platform.machine", new=Mock(return_value="x86_64"))
def test_broker_should_be_disabled_on_x86_64_mac(self):
app = msal.PublicClientApplication(
"client_id",
authority="https://login.microsoftonline.com/common",
enable_broker_on_mac=True,
)
self.assertFalse(app._enable_broker)

@patch("msal.application.platform.machine", new=Mock(return_value="i386"))
def test_broker_should_be_disabled_on_i386_mac(self):
app = msal.PublicClientApplication(
"client_id",
authority="https://login.microsoftonline.com/common",
enable_broker_on_mac=True,
)
self.assertFalse(app._enable_broker)

@patch("msal.application.platform.machine", new=Mock(return_value="unexpected"))
def test_broker_should_be_disabled_on_unrecognized_machine(self):
"""The gate is an allowlist, so an unknown architecture stays broker-free."""
app = msal.PublicClientApplication(
"client_id",
authority="https://login.microsoftonline.com/common",
enable_broker_on_mac=True,
)
self.assertFalse(app._enable_broker)


class MismatchingScopeTestCase(unittest.TestCase):
"""Test cache behavior when HTTP response scope differs from requested scope"""

Expand Down
Loading