From 1c008b815083407bbdcb366ac2a7e7d2fc79571c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 23:45:27 +0000 Subject: [PATCH 01/13] Initial plan From aa2bfbdd3c2b6b9864ec467cf08447ba6e8e4dcb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 23:47:02 +0000 Subject: [PATCH 02/13] Allow Azure Arc managed identity selectors --- msal/managed_identity.py | 22 +++++++++++--------- tests/test_mi.py | 45 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/msal/managed_identity.py b/msal/managed_identity.py index b2fc446c..b2f20712 100644 --- a/msal/managed_identity.py +++ b/msal/managed_identity.py @@ -452,13 +452,8 @@ def _obtain_token( ) arc_endpoint = _get_arc_endpoint() if arc_endpoint: - if ManagedIdentity.is_user_assigned(managed_identity): - raise ManagedIdentityError( # Note: Azure Identity for Python raised exception too - "Invalid managed_identity parameter. " - "Azure Arc supports only system-assigned managed identity, " - "See also " - "https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-service") - return _obtain_token_on_arc(http_client, arc_endpoint, resource) + return _obtain_token_on_arc( + http_client, arc_endpoint, resource, managed_identity) return _obtain_token_on_azure_vm(http_client, managed_identity, resource) @@ -643,12 +638,19 @@ def _obtain_token_on_service_fabric( class ArcPlatformNotSupportedError(ManagedIdentityError): pass -def _obtain_token_on_arc(http_client, endpoint, resource): +def _obtain_token_on_arc(http_client, endpoint, resource, managed_identity=None): # https://learn.microsoft.com/en-us/azure/azure-arc/servers/managed-identity-authentication logger.debug("Obtaining token via managed identity on Azure Arc") + params = {"api-version": "2020-06-01", "resource": resource} + if managed_identity: + _adjust_param(params, managed_identity, types_mapping={ + ManagedIdentity.CLIENT_ID: "client_id", + ManagedIdentity.RESOURCE_ID: "mi_res_id", + ManagedIdentity.OBJECT_ID: "object_id", + }) resp = http_client.get( endpoint, - params={"api-version": "2020-06-01", "resource": resource}, + params=params.copy(), headers={"Metadata": "true"}, ) www_auth = "www-authenticate" # Header in lower case @@ -674,7 +676,7 @@ def _obtain_token_on_arc(http_client, endpoint, resource): secret = f.read() response = http_client.get( endpoint, - params={"api-version": "2020-06-01", "resource": resource}, + params=params.copy(), headers={"Metadata": "true", "Authorization": "Basic {}".format(secret)}, ) try: diff --git a/tests/test_mi.py b/tests/test_mi.py index e9fc6d00..73e1f81f 100644 --- a/tests/test_mi.py +++ b/tests/test_mi.py @@ -477,6 +477,50 @@ def test_arc_error_should_be_normalized(self, mocked_stat): if sys.platform in _supported_arc_platforms_and_their_prefixes: self.fail("Should not raise ArcPlatformNotSupportedError") + def _assert_user_assigned_selector(self, managed_identity, selector_name, selector_value): + app = ManagedIdentityClient(managed_identity, http_client=requests.Session()) + with patch.object(app._http_client, "get", side_effect=[ + self.challenge, + MinimalResponse( + status_code=200, + text='{"access_token": "AT", "expires_in": "1234", "resource": "R"}', + ), + ]) as mocked_method: + try: + result = app.acquire_token_for_client(resource="R") + self.assertEqual("AT", result["access_token"]) + expected_params = { + "api-version": "2020-06-01", + "resource": "R", + selector_name: selector_value, + } + self.assertEqual(expected_params, mocked_method.call_args_list[0].kwargs["params"]) + self.assertEqual(expected_params, mocked_method.call_args_list[1].kwargs["params"]) + except ArcPlatformNotSupportedError: + if sys.platform in _supported_arc_platforms_and_their_prefixes: + self.fail("Should not raise ArcPlatformNotSupportedError") + + def test_arc_user_assigned_client_id_should_be_forwarded(self, mocked_stat): + self._assert_user_assigned_selector( + UserAssignedManagedIdentity(client_id="client-id"), + "client_id", + "client-id", + ) + + def test_arc_user_assigned_resource_id_should_be_forwarded_as_mi_res_id(self, mocked_stat): + self._assert_user_assigned_selector( + UserAssignedManagedIdentity(resource_id="resource-id"), + "mi_res_id", + "resource-id", + ) + + def test_arc_user_assigned_object_id_should_be_forwarded(self, mocked_stat): + self._assert_user_assigned_selector( + UserAssignedManagedIdentity(object_id="object-id"), + "object_id", + "object-id", + ) + class GetManagedIdentitySourceTestCase(unittest.TestCase): @@ -531,4 +575,3 @@ def test_cloud_shell(self): def test_default_to_vm(self): self.assertEqual(get_managed_identity_source(), DEFAULT_TO_VM) - From 2e1f3417dab319f7cbb888905f771cb29cd89a97 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary Date: Thu, 16 Jul 2026 15:34:53 +0100 Subject: [PATCH 03/13] Bump version to 1.38.0rc2 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 593fce2a-8559-422e-92e2-46fb29c251a4 --- msal/sku.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/sku.py b/msal/sku.py index 5e58eda9..6e4e9528 100644 --- a/msal/sku.py +++ b/msal/sku.py @@ -2,5 +2,5 @@ """ # The __init__.py will import this. Not the other way around. -__version__ = "1.37.0" +__version__ = "1.38.0rc2" SKU = "MSAL.Python" From e4769c1fd03c0011f3cdf9c9975b9b50bbda51ca Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 11:09:16 -0700 Subject: [PATCH 04/13] Fix pipeline container --- .Pipelines/pipeline-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index e4d709b2..1724f8c0 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -36,6 +36,7 @@ pr: none variables: CDP_DEFINITION_BUILD_COUNT: $[counter('', 0)] system.debug: ${{ parameters.debug }} + WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # https://aka.ms/obpipelines/containers resources: repositories: From c6faa486fa44e96667c3fe5bbaab6a19c1779ca2 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 11:27:34 -0700 Subject: [PATCH 05/13] Fix pipeline host --- .Pipelines/pipeline-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index 1724f8c0..da70b44c 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -65,6 +65,7 @@ extends: tsaEnabled: true featureFlags: EnableCDPxPAT: false + WindowsHostVersion: '1ESWindows2022' stages: From 8b3ee01c53006e1f45489623e9914b3ac5396031 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 11:53:22 -0700 Subject: [PATCH 06/13] Fix pipeline artifact management --- .Pipelines/pipeline-publish.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index da70b44c..b04f71dc 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -137,7 +137,8 @@ extends: - task: DownloadPipelineArtifact@2 displayName: 'Download build artifact' inputs: - artifactName: drop_Build_BuildDist + buildType: 'current' + itemPattern: '**/drop_build_builddist/*' targetPath: $(Pipeline.Workspace)/python-dist - task: UsePythonVersion@0 @@ -213,7 +214,8 @@ extends: - task: DownloadPipelineArtifact@2 displayName: 'Download python-dist artifact' inputs: - artifactName: drop_Build_BuildDist + buildType: 'current' + itemPattern: '**/drop_build_builddist/*' targetPath: $(Pipeline.Workspace)/python-dist - task: EsrpRelease@12 @@ -227,7 +229,7 @@ extends: intent: 'PackageDistribution' contenttype: 'PyPi' contentsource: 'Folder' - folderlocation: '$(Pipeline.Workspace)/python-dist' + folderlocation: '$(Pipeline.Workspace)/python-dist/drop_build_builddist' waitforreleasecompletion: true owners: 'ryauld@microsoft.com,avdunn@microsoft.com' approvers: 'avdunn@microsoft.com,bogavril@microsoft.com' From 5a5e790cac59509ed06fa49db78d0b6de78c0bd3 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 12:26:04 -0700 Subject: [PATCH 07/13] Fix pipline artifact uploads --- .Pipelines/pipeline-publish.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index b04f71dc..a24e80a5 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -113,6 +113,12 @@ extends: cp -r dist/* $(ob_outputDirectory)/ displayName: 'Copy dist to output directory' + - task: PublishPipelineArtifact@1 + displayName: 'Publish build artifacts' + inputs: + targetPath: '$(ob_outputDirectory)' + artifactName: 'drop_build_builddist' + # ======================================================================== # Stage 5a - Publish to test.pypi.org (Preview / RC) # ======================================================================== @@ -138,7 +144,7 @@ extends: displayName: 'Download build artifact' inputs: buildType: 'current' - itemPattern: '**/drop_build_builddist/*' + artifactName: 'drop_build_builddist' targetPath: $(Pipeline.Workspace)/python-dist - task: UsePythonVersion@0 @@ -215,7 +221,7 @@ extends: displayName: 'Download python-dist artifact' inputs: buildType: 'current' - itemPattern: '**/drop_build_builddist/*' + artifactName: 'drop_build_builddist' targetPath: $(Pipeline.Workspace)/python-dist - task: EsrpRelease@12 @@ -229,7 +235,7 @@ extends: intent: 'PackageDistribution' contenttype: 'PyPi' contentsource: 'Folder' - folderlocation: '$(Pipeline.Workspace)/python-dist/drop_build_builddist' + folderlocation: '$(Pipeline.Workspace)/python-dist' waitforreleasecompletion: true owners: 'ryauld@microsoft.com,avdunn@microsoft.com' approvers: 'avdunn@microsoft.com,bogavril@microsoft.com' From 9a0a7dbe9f42d881bcc6a662daee188d8c6ac8d0 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 12:33:57 -0700 Subject: [PATCH 08/13] Fix pipeline Linux task --- .Pipelines/pipeline-publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index a24e80a5..349e7178 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -117,7 +117,7 @@ extends: displayName: 'Publish build artifacts' inputs: targetPath: '$(ob_outputDirectory)' - artifactName: 'drop_build_builddist' + artifactName: 'drop_Build_BuildDist' # ======================================================================== # Stage 5a - Publish to test.pypi.org (Preview / RC) @@ -144,7 +144,7 @@ extends: displayName: 'Download build artifact' inputs: buildType: 'current' - artifactName: 'drop_build_builddist' + artifactName: 'drop_Build_BuildDist' targetPath: $(Pipeline.Workspace)/python-dist - task: UsePythonVersion@0 @@ -221,7 +221,7 @@ extends: displayName: 'Download python-dist artifact' inputs: buildType: 'current' - artifactName: 'drop_build_builddist' + artifactName: 'drop_Build_BuildDist' targetPath: $(Pipeline.Workspace)/python-dist - task: EsrpRelease@12 From 9bd0017f471f72124e1678112afdd44dbe650f9f Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 12:43:24 -0700 Subject: [PATCH 09/13] Refactor the Linux stuff --- .Pipelines/pipeline-publish.yml | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index 349e7178..a1bd2060 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -87,38 +87,30 @@ extends: displayName: 'Build sdist + wheel (Python 3.12)' pool: type: linux - isCustom: true - vmImage: 'ubuntu-22.04' variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + LinuxContainerImage: 'onebranch.azurecr.io/linux/ubuntu-2204:latest' steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.12' - displayName: 'Use Python 3.12' + - script: | + apt-get update && apt-get install -y python3 python3-pip python3-venv + displayName: 'Install Python 3' - script: | - python -m pip install --upgrade pip build twine + python3 -m pip install --upgrade pip build twine displayName: 'Install build toolchain' - script: | - python -m build + python3 -m build displayName: 'Build sdist and wheel' - script: | - python -m twine check dist/* + python3 -m twine check dist/* displayName: 'Verify distribution (twine check)' - script: | cp -r dist/* $(ob_outputDirectory)/ displayName: 'Copy dist to output directory' - - task: PublishPipelineArtifact@1 - displayName: 'Publish build artifacts' - inputs: - targetPath: '$(ob_outputDirectory)' - artifactName: 'drop_Build_BuildDist' - # ======================================================================== # Stage 5a - Publish to test.pypi.org (Preview / RC) # ======================================================================== @@ -144,7 +136,7 @@ extends: displayName: 'Download build artifact' inputs: buildType: 'current' - artifactName: 'drop_Build_BuildDist' + itemPattern: '**/drop_Build_BuildDist/*' targetPath: $(Pipeline.Workspace)/python-dist - task: UsePythonVersion@0 @@ -221,7 +213,7 @@ extends: displayName: 'Download python-dist artifact' inputs: buildType: 'current' - artifactName: 'drop_Build_BuildDist' + itemPattern: '**/drop_Build_BuildDist/*' targetPath: $(Pipeline.Workspace)/python-dist - task: EsrpRelease@12 @@ -235,7 +227,7 @@ extends: intent: 'PackageDistribution' contenttype: 'PyPi' contentsource: 'Folder' - folderlocation: '$(Pipeline.Workspace)/python-dist' + folderlocation: '$(Pipeline.Workspace)/python-dist/drop_Build_BuildDist' waitforreleasecompletion: true owners: 'ryauld@microsoft.com,avdunn@microsoft.com' approvers: 'avdunn@microsoft.com,bogavril@microsoft.com' From 858f41ab6f2cfba639b59ce3aa52e88de6b92b06 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 13:21:53 -0700 Subject: [PATCH 10/13] Fix pipeline python install --- .Pipelines/pipeline-publish.yml | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index a1bd2060..a2cef2cc 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -84,32 +84,32 @@ extends: condition: eq(dependencies.E2ETests.result, 'Succeeded') jobs: - job: BuildDist - displayName: 'Build sdist + wheel (Python 3.12)' + displayName: 'Build sdist + wheel' pool: - type: linux + type: windows variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' - LinuxContainerImage: 'onebranch.azurecr.io/linux/ubuntu-2204:latest' steps: - - script: | - apt-get update && apt-get install -y python3 python3-pip python3-venv - displayName: 'Install Python 3' + - script: python --version + displayName: 'Check Python version' - - script: | - python3 -m pip install --upgrade pip build twine + - script: python -m pip install --upgrade pip build twine displayName: 'Install build toolchain' - - script: | - python3 -m build + - script: python -m build displayName: 'Build sdist and wheel' - - script: | - python3 -m twine check dist/* + - script: python -m twine check dist\* displayName: 'Verify distribution (twine check)' - - script: | - cp -r dist/* $(ob_outputDirectory)/ + - task: CopyFiles@2 displayName: 'Copy dist to output directory' + inputs: + SourceFolder: '$(Build.SourcesDirectory)\dist' + Contents: | + *.whl + *.tar.gz + TargetFolder: '$(ob_outputDirectory)' # ======================================================================== # Stage 5a - Publish to test.pypi.org (Preview / RC) @@ -136,8 +136,8 @@ extends: displayName: 'Download build artifact' inputs: buildType: 'current' - itemPattern: '**/drop_Build_BuildDist/*' - targetPath: $(Pipeline.Workspace)/python-dist + artifactName: 'drop_Build_BuildDist' + targetPath: $(Pipeline.Workspace)\python-dist - task: UsePythonVersion@0 inputs: @@ -213,8 +213,8 @@ extends: displayName: 'Download python-dist artifact' inputs: buildType: 'current' - itemPattern: '**/drop_Build_BuildDist/*' - targetPath: $(Pipeline.Workspace)/python-dist + artifactName: 'drop_Build_BuildDist' + targetPath: $(Pipeline.Workspace)\python-dist - task: EsrpRelease@12 displayName: 'Publish to PyPI via ESRP' @@ -227,7 +227,7 @@ extends: intent: 'PackageDistribution' contenttype: 'PyPi' contentsource: 'Folder' - folderlocation: '$(Pipeline.Workspace)/python-dist/drop_Build_BuildDist' + folderlocation: '$(Pipeline.Workspace)\python-dist' waitforreleasecompletion: true owners: 'ryauld@microsoft.com,avdunn@microsoft.com' approvers: 'avdunn@microsoft.com,bogavril@microsoft.com' From 1e4f06304a0a6c0d3a08a3710b78ae2a59dd3c1f Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 13:45:40 -0700 Subject: [PATCH 11/13] Fix pipeline python install --- .Pipelines/pipeline-publish.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index a2cef2cc..ffb5b4af 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -66,6 +66,8 @@ extends: featureFlags: EnableCDPxPAT: false WindowsHostVersion: '1ESWindows2022' + networkisolation: + policy: Permissive stages: @@ -93,15 +95,12 @@ extends: - script: python --version displayName: 'Check Python version' - - script: python -m pip install --upgrade pip build twine + - script: python -m pip install --upgrade pip build displayName: 'Install build toolchain' - script: python -m build displayName: 'Build sdist and wheel' - - script: python -m twine check dist\* - displayName: 'Verify distribution (twine check)' - - task: CopyFiles@2 displayName: 'Copy dist to output directory' inputs: From 21be29d1c077f1b664fbc69f4ca8adb2eeefd238 Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 14:05:35 -0700 Subject: [PATCH 12/13] Remove unnecessary Python install --- .Pipelines/pipeline-publish.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index ffb5b4af..17de5b40 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -66,8 +66,6 @@ extends: featureFlags: EnableCDPxPAT: false WindowsHostVersion: '1ESWindows2022' - networkisolation: - policy: Permissive stages: @@ -95,10 +93,7 @@ extends: - script: python --version displayName: 'Check Python version' - - script: python -m pip install --upgrade pip build - displayName: 'Install build toolchain' - - - script: python -m build + - script: python setup.py sdist bdist_wheel displayName: 'Build sdist and wheel' - task: CopyFiles@2 From e49fb76d7b5b401cfd6d16eba9ce93837cb088fe Mon Sep 17 00:00:00 2001 From: avdunn Date: Thu, 16 Jul 2026 14:29:02 -0700 Subject: [PATCH 13/13] Update release owners --- .Pipelines/pipeline-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.Pipelines/pipeline-publish.yml b/.Pipelines/pipeline-publish.yml index 17de5b40..18d4767d 100644 --- a/.Pipelines/pipeline-publish.yml +++ b/.Pipelines/pipeline-publish.yml @@ -223,7 +223,7 @@ extends: contentsource: 'Folder' folderlocation: '$(Pipeline.Workspace)\python-dist' waitforreleasecompletion: true - owners: 'ryauld@microsoft.com,avdunn@microsoft.com' + owners: 'avdunn@microsoft.com,bogavril@microsoft.com' approvers: 'avdunn@microsoft.com,bogavril@microsoft.com' serviceendpointurl: 'https://api.esrp.microsoft.com' mainpublisher: 'ESRPRELPACMAN'