Skip to content

Commit 461a417

Browse files
committed
Disable broker on Intel-based Macs
Broker on macOS is supported only on Apple Silicon (arm64). On Intel Macs (x86_64 / i386) MSAL Python will now force-disable broker in ClientApplication._decide_broker, regardless of whether a broker is installed on the device or whether the app opted in via enable_broker_on_mac=True. Apple Silicon Macs and all non-Mac platforms are unaffected. The check sits in the single broker-decision chokepoint and reuses the existing 'broker unavailable, falling back to non-broker' warning path. Tests: - tests/test_application.py::TestBrokerDisabledOnIntelMac covers the three architecture branches (arm64, x86_64, i386) by patching sys.platform and platform.machine, matching the existing broker-test pattern in this file. CI runs on ubuntu-latest only, so the mock is the only way to exercise the darwin branch. - tests/intel_mac_broker_smoke_test.py is a credential-free, no-UI manual smoke test that runs in a few seconds on real hardware (especially useful on an Intel Mac, which CI cannot cover).
1 parent 6b652f4 commit 461a417

3 files changed

Lines changed: 124 additions & 0 deletions

File tree

msal/application.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import time
44
import logging
5+
import platform
56
import sys
67
import warnings
78
from threading import Lock
@@ -763,6 +764,18 @@ def _decide_broker(self, allow_broker, enable_pii_log):
763764
and not self.authority.is_adfs
764765
and not self.authority._is_b2c
765766
)
767+
if (
768+
self._enable_broker
769+
and sys.platform == "darwin"
770+
and platform.machine() in ("x86_64", "i386")
771+
):
772+
# Broker on macOS is supported only on Apple Silicon (arm64).
773+
# Intel Macs are excluded by product policy, regardless of whether
774+
# a broker is actually installed on the device.
775+
self._enable_broker = False
776+
logger.warning(
777+
"Broker is not supported on Intel-based Macs. "
778+
"We will fallback to non-broker.")
766779
if self._enable_broker:
767780
try:
768781
_init_broker(enable_pii_log)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""Manual smoke test for the Intel-Mac broker-disable gate.
2+
3+
This script is intentionally credential-free and runs in a few seconds.
4+
It exercises the production decision logic in ``ClientApplication._decide_broker``
5+
on real hardware (no mocks), which is the one thing the unit tests in
6+
``test_application.py::TestBrokerDisabledOnIntelMac`` cannot do — CI runs on
7+
``ubuntu-latest`` only, so ``sys.platform`` is patched there.
8+
9+
How to run::
10+
11+
pip install --force-reinstall "msal[broker]" # or your local checkout
12+
python tests/intel_mac_broker_smoke_test.py
13+
14+
Expected outcomes:
15+
16+
* Apple Silicon Mac (``arm64``) with ``pymsalruntime`` installed:
17+
``_enable_broker`` is ``True``.
18+
* Intel Mac (``x86_64`` / ``i386``):
19+
``_enable_broker`` is ``False`` even though the opt-in was passed and even
20+
if a broker is installed on the device.
21+
* Non-Mac (Windows, Linux):
22+
``enable_broker_on_mac`` is ignored — ``_enable_broker`` is ``False``.
23+
24+
The script asserts the expected outcome for the host it runs on and exits
25+
non-zero if the gate misbehaves.
26+
"""
27+
import platform
28+
import sys
29+
30+
import msal
31+
32+
33+
_CLIENT_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" # Azure CLI, public
34+
_AUTHORITY = "https://login.microsoftonline.com/organizations"
35+
36+
37+
def _expected_broker_state():
38+
if sys.platform != "darwin":
39+
return False, "non-Mac platform — enable_broker_on_mac is a no-op"
40+
if platform.machine() in ("x86_64", "i386"):
41+
return False, "Intel Mac — broker disabled by product policy"
42+
return True, "Apple Silicon Mac — broker should be enabled"
43+
44+
45+
def main():
46+
print(f"sys.platform = {sys.platform!r}")
47+
print(f"platform.machine() = {platform.machine()!r}")
48+
49+
expected, why = _expected_broker_state()
50+
print(f"Expected _enable_broker = {expected} ({why})")
51+
52+
app = msal.PublicClientApplication(
53+
_CLIENT_ID,
54+
authority=_AUTHORITY,
55+
enable_broker_on_mac=True,
56+
enable_broker_on_windows=True,
57+
enable_broker_on_linux=True,
58+
)
59+
actual = bool(app._enable_broker)
60+
print(f"Actual _enable_broker = {actual}")
61+
62+
if actual != expected:
63+
print(
64+
"FAIL: Intel-Mac gate misbehaved. "
65+
"See ClientApplication._decide_broker in msal/application.py.",
66+
file=sys.stderr,
67+
)
68+
sys.exit(1)
69+
print("PASS")
70+
71+
72+
if __name__ == "__main__":
73+
main()

tests/test_application.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,44 @@ def test_app_did_not_register_redirect_uri_should_error_out(self):
11411141
self.assertEqual(result.get("error"), "broker_error")
11421142

11431143

1144+
@patch("sys.platform", new="darwin") # Pretend running on Mac.
1145+
@patch("msal.authority.tenant_discovery", new=Mock(return_value={
1146+
"authorization_endpoint": "https://contoso.com/placeholder",
1147+
"token_endpoint": "https://contoso.com/placeholder",
1148+
"issuer": "https://contoso.com/placeholder",
1149+
}))
1150+
@patch("msal.application._init_broker", new=Mock()) # Pretend pymsalruntime installed and working
1151+
class TestBrokerDisabledOnIntelMac(unittest.TestCase):
1152+
"""Broker is disabled on Intel-based Macs regardless of opt-in."""
1153+
1154+
@patch("msal.application.platform.machine", new=Mock(return_value="arm64"))
1155+
def test_broker_should_be_enabled_on_apple_silicon_mac(self):
1156+
app = msal.PublicClientApplication(
1157+
"client_id",
1158+
authority="https://login.microsoftonline.com/common",
1159+
enable_broker_on_mac=True,
1160+
)
1161+
self.assertTrue(app._enable_broker)
1162+
1163+
@patch("msal.application.platform.machine", new=Mock(return_value="x86_64"))
1164+
def test_broker_should_be_disabled_on_x86_64_mac(self):
1165+
app = msal.PublicClientApplication(
1166+
"client_id",
1167+
authority="https://login.microsoftonline.com/common",
1168+
enable_broker_on_mac=True,
1169+
)
1170+
self.assertFalse(app._enable_broker)
1171+
1172+
@patch("msal.application.platform.machine", new=Mock(return_value="i386"))
1173+
def test_broker_should_be_disabled_on_i386_mac(self):
1174+
app = msal.PublicClientApplication(
1175+
"client_id",
1176+
authority="https://login.microsoftonline.com/common",
1177+
enable_broker_on_mac=True,
1178+
)
1179+
self.assertFalse(app._enable_broker)
1180+
1181+
11441182
class MismatchingScopeTestCase(unittest.TestCase):
11451183
"""Test cache behavior when HTTP response scope differs from requested scope"""
11461184

0 commit comments

Comments
 (0)