Route NuGet restore through CFS feed (SR21 CFSClean) - #1756
Open
bragi92 wants to merge 1 commit into
Open
Conversation
Pipeline 444 (ContainerInsights-MultiArch-MergedBranches) is flagged under MountainPass SR21 / SFI-ES4.2.4 for CFSClean violations. 1ES telemetry shows the only CFSClean endpoint hit is api.nuget.org, from dotnet.exe during the 'build base' step on build_windows_2019 and build_windows_2022. Changes: - Add NuGet.config at repo root with <clear /> and only the CFS-backed Azure Artifacts feed (microsoft_PublicPackages), which already has a NuGet Gallery upstream. Without this, restore falls back to api.nuget.org. - Drop 'dotnet add package Newtonsoft.json' and 'dotnet add package BouncyCastle' from build/windows/Makefile.ps1. Both are already pinned as PackageReference in CertificateGenerator.csproj (13.0.1 / 1.8.9); the unversioned 'dotnet add package' calls reach api.nuget.org to resolve the latest version and rewrite the csproj, un-pinning the versions at build time. - Add NuGetAuthenticate@1 to both Windows jobs so the credential provider is configured for the feed. The build shells out to dotnet from a script rather than DotNetCoreCLI@2, so nothing wires up feed auth today. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ee239d9a-59a5-409c-bf8f-5a1e5d9a9d58
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 2 pipeline(s) were filtered out due to trigger conditions. |
bragi92
enabled auto-merge (squash)
August 7, 2026 00:19
Contributor
|
Thanks for this pr bragi92 - is this fix working fine e2e? are windows pods coming up fine and sending data successfully? |
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 2 pipeline(s) were filtered out due to trigger conditions. |
Contributor
|
bragi92 - thanks for adding the test cases. The data that should be tested is containerlog isn’t it? Since the other tables are collected by the replicaset? |
Contributor
Author
|
rashmichandrashekar (@rashmichandrashekar) Makes sense. Let me update the tests. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Routes NuGet package restore for the Windows agent build through the CFS-backed Azure Artifacts feed, instead of
api.nuget.org.Why
Pipeline 444 (
ContainerInsights-MultiArch-MergedBranches) is flagged under MountainPass SR21 / SFI-ES4.2.4 — ICM 839785317, story 38937265.1ES policy telemetry (
GetPolicyViolationDetails(adoOrg='github-private', pipelineID='444')) shows the onlyCFSCleanendpoint the pipeline reaches isapi.nuget.org, fromC:\Program Files\dotnet\dotnet.exeduring thebuild basestep onbuild_windows_2019andbuild_windows_2022. Container Insights is in the Non-TCB cohort (HasTCB = false), which only has to satisfy theCFSCleanpolicy — so this is the complete set of required changes.Changes
NuGet.configat repo root —<clear />plus a single source: the CFS-backedmicrosoft_PublicPackagesproject-scoped feed, which already has a NuGet Gallery upstream configured. There was noNuGet.configanywhere in the repo, so restore was defaulting toapi.nuget.org.build/windows/Makefile.ps1— removed:Both packages are already pinned as
PackageReferenceinCertificateGenerator.csproj(Newtonsoft.Json13.0.1,BouncyCastle1.8.9).dotnet add packagewithout a version contacts the package source to resolve latest and then rewrites the csproj — so these calls both caused the violation and silently un-pinned the dependency versions on every build. No behavior change from removing them.NuGetAuthenticate@1added to both Windows jobs — the build shells out todotnetfrom ascript:step rather thanDotNetCoreCLI@2, so nothing configures the credential provider for the feed today.Validation
Build — PR build 122876: all 4 jobs green, both
NuGetAuthenticate@1tasks succeeded. Restore against the CFS feed resolved the pinnedBouncyCastle 1.8.9with 0 errors anddotnet publishproducedCertificateGenerator.exe.Scope of what can regress —
CertificateGenerator.csprojis the only .NET project in the repo, so the rootNuGet.configreaches nothing else. At runtimemain.ps1only callsGenerate-CertificateswhenUSING_AAD_MSI_AUTH != true, so cert-auth mode is the sole path this change can affect (the AKS MSI default skips it entirely). All testing below therefore runs in cert-auth mode (isUsingAADAuth: "false") so the changed codepath actually executes.Binary-level — reproduced the publish locally with this branch's
NuGet.config+Makefile.ps1, then ran the binary: it emitted a valid 2048-bit sha256RSA self-signed cert + RSA key. Output binariesNewtonsoft.Json 13.0.1,BouncyCastle.Crypto 1.8.9,CertificateGenerator.exe.Backdoor deployment
Built this branch via a manual (non-PR) run of pipeline 444 — build 123005 — and deployed
cidev:win-3.6.0-1-g4b845429a-20260807201906onto a Windows Server 2022 node pool, swapping only theama-logs-windowsdaemonset image so the Windows agent is the single changed variable.Pod
Running 1/1, 0 restarts, same cert sequence as the production baseline:Container logs — the data the Windows daemonset itself collects. A Windows workload emitting a marked line every second, compared over equal 10-min steady-state windows on the same node:
Computer == akswinp000000)ciprod:win-3.6.0ContainerLogrowsNode-level
Perf(also daemonset-collected, via cAdvisor on the local kubelet) likewise matched exactly at 305 rows over equal windows.One correction to "Changes" #2 — removing
dotnet add packageis not fully behavior-neutral.dotnet add package Newtonsoft.json(no version) resolves 13.0.4, so the shipped agent moves 13.0.4 → the pinned 13.0.1.BouncyCastleis genuinely unchanged (1.8.9 is latest). Not a security regression: Newtonsoft's only advisory (CVE-2024-21907 / GHSA-5crp-9r3c-p9vr) has vulnerable range< 13.0.1, so 13.0.1 is the patched floor. Deterministic pinning is the intended outcome, but worth stating rather than "no behavior change".Out of scope
CFSClean2(chocolatey,ghcr.iovia trivy) andDefaultDeny(google-analytics, segment.io, Docker Desktop) are not required for the Non-TCB cohort and are intentionally left alone.Resolution criteria
The ICM auto-resolves after zero CFSClean violations across at least 3 runs in a 7-day window, at which point the pipeline is locked into the policy. Deadline is Aug 21, 2026, so this needs to land by ~Aug 13 to leave room for the lock-in window.