Repository navigation
Update nuget network policy for release failure - #740
Merged
Nikola Metulev (nmetulev) merged 2 commits intoAug 12, 2026
Merged
Conversation
Zach Teutsch (zateutsch)
marked this pull request as ready for review
August 12, 2026 06:26
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the release pipeline’s network policy to restore NuGet publishing.
Changes:
- Replaces
CFSCleanwithCFSClean2. - Documents why the policy change is required.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Contributor
Build Metrics ReportBinary Sizes
Test Results❌ 4553 passed, 1 failed, 5 skipped out of 4559 tests in 622.4s (-91.1s vs. baseline) Test Coverage✅ 89.1% line coverage, 82.4% branch coverage · ✅ no change vs. baseline CLI Startup Time44ms median (x64, Updated 2026-08-12 06:45:20 UTC · commit |
Nikola Metulev (nmetulev)
deleted the
zateutsch/fix-nuget-release-network-policy
branch
August 12, 2026 17:39
Zach Teutsch (zateutsch)
added a commit
that referenced
this pull request
Aug 12, 2026
Nuget failing due to a policy mismatch.
Nikola Metulev (nmetulev)
pushed a commit
that referenced
this pull request
Aug 18, 2026
…750) ## Why 1ES network isolation policy is **pipeline-wide** — it can't be scoped to a stage or job — and `CFSClean` sinkholes `api.nuget.org`. #740 worked around the blocked nuget.org push by moving the whole release pipeline to `CFSClean2`, but that also dropped CFS feed enforcement from the Build stage, which is the part that actually restores packages. We asked 1ES (netiso). Their answer: > You cannot publish to NuGet under CFSClean (until ESRP Release task support NuGet, which they are working on this quarter). If your pipeline publishes to NuGet and does not consume from it, you are eligible for an S360 exception. ## What this does Splits the nuget.org push into its own pipeline so the exception is scoped to a pipeline that *only* publishes: | Pipeline | Policy | Does | |---|---|---| | `.pipelines/release.yml` | `Permissive,CFSClean` (restored) | build, test, ESRP sign, GitHub/npm/WinGet/MSLearn releases | | `.pipelines/release-nuget.yml` (new) | `Permissive,CFSClean2` | downloads the signed `nuget-packages` artifact and pushes it — restores nothing | The new pipeline triggers on completion of the **`Release_GitHub` stage** of `WinDevCLI - Release` for `rel/v*`. Scoping to that stage matters: a bare completion trigger fires only when the *entire* run succeeds, which would have made publishing depend on `Release_WinGet` (whose PAT expires every 90 days), `Release_Npm` and `Release_MSLearn`. The stage filter reproduces the `dependsOn: Release_GitHub` the stage had before the move. ## Signature gate The `Release_NuGet` stage previously sat behind `${{ if eq(parameters.DoEsrp, 'true') }}`. The split loses that gate, and the `nuget-packages` artifact is published whether or not ESRP signing ran — so a `DoEsrp: false` run could have pushed **unsigned** packages to nuget.org. The new pipeline verifies signatures before pushing. Checked against real packages: | Input | Result | |---|---| | Unsigned `.nupkg` (fresh `dotnet pack`) | `NU3004: The package is not signed` → exit 1 → step throws | | Microsoft-signed `.nupkg` | Author + Repository signatures listed → exit 0 | It also fails if the artifact contains no `.nupkg` at all, so an empty or misnamed artifact fails loudly instead of silently pushing nothing. **Known limitation:** `dotnet nuget verify --all` proves a package carries a trusted signature, not that *we* signed it — a package with only a nuget.org repository signature also passes. Pinning `--certificate-fingerprint` would close that, at the cost of a constant that breaks releases whenever ESRP rotates the cert. The case this gate exists for — `DoEsrp: false` producing unsigned output — is caught, and anything foreign reaching `artifacts/nuget/` implies the build is already compromised. ## Also - Sets `useDotNetTask: false` on the push. `DotNetCoreCLI@2` can't use the encrypted API key from the service connection — present in every working public example of an external nuget.org push (aspire, teams.net, playwright-dotnet, Agents-M365Copilot) and missing here. - `scripts/start-release.ps1` now tells the release owner to monitor both pipelines. Previously it said "Monitor the release pipeline", singular, so a failure in the new pipeline would be invisible to whoever cut the release. ## Follow-ups (not in this PR) - **Register `release-nuget.yml`** as a new ADO pipeline under `\Windows Developer CLI`, then file the S360 exception against *that* pipeline. - **Move to `EsrpRelease`** once it supports NuGet — same shape as the existing npm publish — and drop the exception. - **SFI-ES4.2.4 Wave 10** will retire `Permissive` from the policy mix. Both pipelines will need a default-deny base (`Preferred`/`Good`/`Okay`) plus add-ons. Deliberately kept separate: `release.yml` has egress CI never exercises (`aka.ms` and `github.com` in the WinGet stage, GitHub Models for release notes, ESRP), so that migration should be driven by the netiso dashboard rather than bundled here. ## Testing All three pipeline YAMLs parse. The release-job cross-pipeline artifact input and the `stages:` trigger filter were verified against the 1ES/ADO schemas, and the ADO pipeline path (`\Windows Developer CLI\WinDevCLI - Release`) was read from the ADO API rather than guessed. The signature gate and the release banner were both exercised locally. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Zach Teutsch <88554871+zateutsch@users.noreply.github.com> Copilot-Session: 5c9d1699-fd50-4ecc-af11-2567ff772a4f
This was referenced Sep 24, 2026
This was referenced Oct 2, 2026
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.
Nuget failing due to a policy mismatch.