From 34e41a21d595b04022d76b7834a52aeb112e1542 Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Wed, 8 Jul 2026 13:00:47 -0700 Subject: [PATCH 1/4] Use WIF-based Entra auth for OneLocBuild ceapex feed access Cherry-pick of onelocbuild-wif-migration (main) to release/9.0. Replace PAT-based authentication with Entra token acquired via AzureCLI@2 and the dnceng-onelocbuild-ceapex service connection. Related: AzDO#10151 --- eng/common/core-templates/job/onelocbuild.yml | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index edefa789d36..2b0e647d49e 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -8,6 +8,11 @@ parameters: CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + # Service connection for WIF-based Entra authentication to ceapex feeds (replaces CeapexPat). + # When set, uses AzureCLI@2 to obtain an Entra token instead of a PAT. + # Set to '' to fall back to PAT-based auth via CeapexPat parameter. + CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' + SourcesDirectory: $(System.DefaultWorkingDirectory) CreatePr: true AutoCompletePr: false @@ -73,7 +78,21 @@ jobs: displayName: Generate LocProject.json condition: ${{ parameters.condition }} - - task: OneLocBuild@2 + # Acquire Entra token for ceapex feed access when using WIF-based auth + - ${{ if ne(parameters.CeapexServiceConnection, '') }}: + - task: AzureCLI@2 + displayName: 'Acquire Entra token for ceapex feed access' + inputs: + azureSubscription: ${{ parameters.CeapexServiceConnection }} + scriptType: 'pscore' + scriptLocation: 'inlineScript' + inlineScript: | + $token = az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv + if (-not $token) { Write-Error "Failed to acquire AzDO token"; exit 1 } + Write-Host "##vso[task.setvariable variable=CeapexEntraToken;issecret=true]${token}" + condition: ${{ parameters.condition }} + + - task: OneLocBuild@3 displayName: OneLocBuild env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -89,7 +108,10 @@ jobs: ${{ if eq(parameters.RepoType, 'gitHub') }}: isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth - patVariable: ${{ parameters.CeapexPat }} + ${{ if ne(parameters.CeapexServiceConnection, '') }}: + patVariable: $(CeapexEntraToken) + ${{ if eq(parameters.CeapexServiceConnection, '') }}: + patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} gitHubPatVariable: "${{ parameters.GithubPat }}" From 23404d9812151d31606aed1b2a456d93571979fd Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Wed, 15 Jul 2026 11:27:41 -0700 Subject: [PATCH 2/4] Address Copilot review: reuse shared get-federated-access-token.yml template for ceapex token --- eng/common/core-templates/job/onelocbuild.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index 2b0e647d49e..fe4a5b9ddec 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -80,17 +80,11 @@ jobs: # Acquire Entra token for ceapex feed access when using WIF-based auth - ${{ if ne(parameters.CeapexServiceConnection, '') }}: - - task: AzureCLI@2 - displayName: 'Acquire Entra token for ceapex feed access' - inputs: - azureSubscription: ${{ parameters.CeapexServiceConnection }} - scriptType: 'pscore' - scriptLocation: 'inlineScript' - inlineScript: | - $token = az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv - if (-not $token) { Write-Error "Failed to acquire AzDO token"; exit 1 } - Write-Host "##vso[task.setvariable variable=CeapexEntraToken;issecret=true]${token}" - condition: ${{ parameters.condition }} + - template: /eng/common/templates/steps/get-federated-access-token.yml + parameters: + federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} + outputVariableName: 'CeapexEntraToken' + condition: ${{ parameters.condition }} - task: OneLocBuild@3 displayName: OneLocBuild From cf84f64ca9e52b5480f25d07691e61400d013023 Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Wed, 15 Jul 2026 12:45:36 -0700 Subject: [PATCH 3/4] Address Copilot review: gate WIF to dnceng/internal only, revert OneLocBuild@3 to @2 to reduce rollout risk --- eng/common/core-templates/job/onelocbuild.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index fe4a5b9ddec..8a843e2b28c 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -9,8 +9,9 @@ parameters: GithubPat: $(BotAccount-dotnet-bot-repo-PAT) # Service connection for WIF-based Entra authentication to ceapex feeds (replaces CeapexPat). - # When set, uses AzureCLI@2 to obtain an Entra token instead of a PAT. - # Set to '' to fall back to PAT-based auth via CeapexPat parameter. + # When set, dnceng/internal builds acquire a federated Entra token instead of using a PAT. + # All other projects (e.g. DevDiv, public), where this dnceng-scoped service connection does not + # exist, and any pipeline that sets this to '' fall back to PAT-based auth via the CeapexPat parameter. CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' SourcesDirectory: $(System.DefaultWorkingDirectory) @@ -78,15 +79,16 @@ jobs: displayName: Generate LocProject.json condition: ${{ parameters.condition }} - # Acquire Entra token for ceapex feed access when using WIF-based auth - - ${{ if ne(parameters.CeapexServiceConnection, '') }}: + # Acquire an Entra token for ceapex feed access via WIF (dnceng/internal only). + # All other projects use PAT-based auth, since the ceapex service connection is scoped to dnceng/internal. + - ${{ if and(ne(parameters.CeapexServiceConnection, ''), eq(variables['System.TeamProject'], 'internal')) }}: - template: /eng/common/templates/steps/get-federated-access-token.yml parameters: federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} outputVariableName: 'CeapexEntraToken' condition: ${{ parameters.condition }} - - task: OneLocBuild@3 + - task: OneLocBuild@2 displayName: OneLocBuild env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -102,9 +104,9 @@ jobs: ${{ if eq(parameters.RepoType, 'gitHub') }}: isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth - ${{ if ne(parameters.CeapexServiceConnection, '') }}: + ${{ if and(ne(parameters.CeapexServiceConnection, ''), eq(variables['System.TeamProject'], 'internal')) }}: patVariable: $(CeapexEntraToken) - ${{ if eq(parameters.CeapexServiceConnection, '') }}: + ${{ if or(eq(parameters.CeapexServiceConnection, ''), ne(variables['System.TeamProject'], 'internal')) }}: patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} From e2d827641edf5d08b8f78f70efe6b44146c6a2f7 Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Wed, 15 Jul 2026 12:52:49 -0700 Subject: [PATCH 4/4] Address Copilot review: call core-templates get-federated-access-token step directly with is1ESPipeline passthrough --- eng/common/core-templates/job/onelocbuild.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index 8a843e2b28c..79386ab0863 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -82,8 +82,9 @@ jobs: # Acquire an Entra token for ceapex feed access via WIF (dnceng/internal only). # All other projects use PAT-based auth, since the ceapex service connection is scoped to dnceng/internal. - ${{ if and(ne(parameters.CeapexServiceConnection, ''), eq(variables['System.TeamProject'], 'internal')) }}: - - template: /eng/common/templates/steps/get-federated-access-token.yml + - template: /eng/common/core-templates/steps/get-federated-access-token.yml parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} outputVariableName: 'CeapexEntraToken' condition: ${{ parameters.condition }}