Add --allow-untrusted-root flag to nuget sign and dotnet nuget sign - #7201
Merged
kartheekp-ms merged 5 commits intoMar 23, 2026
Merged
Conversation
elantiguamsft
added a commit
to elantiguamsft/Home
that referenced
this pull request
Mar 10, 2026
Add a new --allow-untrusted-signing flag to nuget sign and dotnet nuget sign that allows signing NuGet packages with certificates whose root CA is not installed in a trusted root certificate store. When this flag is set, the UntrustedRoot X509 chain status is treated as a warning instead of a fatal error. The certificate chain is still fully built and validated for structure. Implementation PR: NuGet/NuGet.Client#7201 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
martinrrm
previously approved these changes
Mar 17, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an opt-in capability for nuget sign and dotnet nuget sign to proceed with signing when the signing certificate’s chain reports UntrustedRoot, by downgrading that specific chain status from error to warning when explicitly enabled.
Changes:
- Add
AllowUntrustedRootplumbing throughSignArgs/SignPackageRequestand certificate discovery/validation so store filtering doesn’t exclude untrusted-root certs. - Introduce a new
CertificateChainUtility.GetCertificateChainoverload that acceptsallowUntrustedRootand adjusts chain status severity accordingly. - Add unit/functional tests plus CLI help text and localization updates for the new option.
Reviewed changes
Copilot reviewed 43 out of 45 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/NuGet.Core.Tests/NuGet.Packaging.Test/SigningTests/CertificateChainUtilityTests.cs | Adds a unit test covering the allow-untrusted-root chain behavior. |
| test/NuGet.Core.FuncTests/NuGet.XPlat.FuncTest/XplatSignTests.cs | Adds xplat arg parsing tests for the new sign option. |
| test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetSignCommandTest.cs | Adds nuget.exe SignCommand→SignArgs mapping tests for the new flag. |
| src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateChainUtility.cs | Adds overload and adjusts chain-status classification based on allowUntrustedRoot. |
| src/NuGet.Core/NuGet.Packaging/Signing/Authoring/SignPackageRequest.cs | Adds AllowUntrustedRoot and threads it into signing chain construction. |
| src/NuGet.Core/NuGet.Packaging/PublicAPI/net8.0/PublicAPI.Unshipped.txt | Declares new public API surface (property + overload). |
| src/NuGet.Core/NuGet.Packaging/PublicAPI/net472/PublicAPI.Unshipped.txt | Declares new public API surface (property + overload). |
| src/NuGet.Core/NuGet.Commands/SignCommand/SignCommandRunner.cs | Passes AllowUntrustedRoot into signing request and cert discovery options. |
| src/NuGet.Core/NuGet.Commands/SignCommand/SignArgs.cs | Adds AllowUntrustedRoot to command args model. |
| src/NuGet.Core/NuGet.Commands/SignCommand/CertificateProvider.cs | Ensures store-discovered certs aren’t filtered out solely for UntrustedRoot when enabled. |
| src/NuGet.Core/NuGet.Commands/SignCommand/CertificateFindOptions.cs | Adds AllowUntrustedRoot to certificate source options. |
| src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt | Declares SignArgs.AllowUntrustedRoot public API. |
| src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt | Declares SignArgs.AllowUntrustedRoot public API. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx | Adds localized description string for the new xplat sign option. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs | Adds strongly-typed accessor for the new resource string. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/Signing/SignCommand.cs | Registers the new xplat sign CLI option and maps it into SignArgs. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.zh-Hant.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.zh-Hans.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.tr.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ru.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.pt-BR.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.pl.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ko.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ja.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.it.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.fr.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.es.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.de.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.cs.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.resx | Adds localized description string for the new nuget.exe sign option. |
| src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs | Adds strongly-typed accessor for the new resource string. |
| src/NuGet.Clients/NuGet.CommandLine/Commands/SignCommand.cs | Adds the new nuget.exe sign option property and maps it into SignArgs. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.zh-Hant.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.zh-Hans.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.tr.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.ru.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.pt-BR.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.pl.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.ko.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.ja.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.it.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.fr.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.es.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.de.xlf | Adds localization entry for the new sign option description. |
| src/NuGet.Clients/NuGet.CommandLine/xlf/NuGetCommand.cs.xlf | Adds localization entry for the new sign option description. |
Files not reviewed (2)
- src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs: Language not supported
- src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs: Language not supported
dtivel
requested changes
Mar 20, 2026
Add AllowUntrustedRoot property to SignArgs, CertificateSourceOptions, and SignPackageRequest. Add a new public overload of GetCertificateChain that accepts allowUntrustedRoot parameter, making UntrustedRoot chain status a warning instead of an error during certificate discovery and signing chain validation. Wire up the option through both classic nuget.exe SignCommand (--AllowUntrustedSigning) and dotnet nuget sign (--allow-untrusted-signing). Works on net472 without requiring CustomRootTrust. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CertificateChainUtilityTests: verify GetCertificateChain with allowUntrustedRoot=true returns a chain (UntrustedRoot as warning) - NuGetSignCommandTest: verify -AllowUntrustedSigning parses to SignArgs.AllowUntrustedRoot=true, and default is false - XplatSignTests: verify --allow-untrusted-signing parses to SignArgs.AllowUntrustedRoot=true, and default is false Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align CLI flag naming with existing dotnet nuget trust --allow-untrusted-root per reviewer feedback. Renames: - dotnet CLI: --allow-untrusted-signing -> --allow-untrusted-root - nuget.exe: -AllowUntrustedSigning -> -AllowUntrustedRoot - Resource keys: SignCommandAllowUntrustedSigningDescription -> SignCommandAllowUntrustedRootDescription Internal API property names (AllowUntrustedRoot on SignArgs, SignPackageRequest, CertificateSourceOptions) are unchanged - they were already correct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add full XML doc comments to the new GetCertificateChain overload including param/returns/remarks/exception documentation matching the existing overload pattern. Clarify that allowUntrustedRoot only affects signature certificate chains (no effect for timestamp chains). Replace var with explicit types in the AllowUntrustedRoot test per code review feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
elantiguamsft
force-pushed
the
feature/allow-untrusted-signing
branch
from
March 20, 2026 17:34
f6f19d7 to
a1cc8fb
Compare
…ledException race) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dtivel
approved these changes
Mar 20, 2026
dtivel
left a comment
Contributor
There was a problem hiding this comment.
LGTM. Thanks, @elantiguamsft!
kartheekp-ms
pushed a commit
to NuGet/Home
that referenced
this pull request
Mar 20, 2026
…14798) * Add proposal: --allow-untrusted-signing flag for nuget sign commands Add a new --allow-untrusted-root flag to nuget sign and dotnet nuget sign that allows signing NuGet packages with certificates whose root CA is not installed in a trusted root certificate store. When this flag is set, the UntrustedRoot X509 chain status is treated as a warning instead of a fatal error. The certificate chain is still fully built and validated for structure. Implementation PR: NuGet/NuGet.Client#7201 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix inaccurate references to nuget verify --allow-untrusted-root flag Replace incorrect claims about a nuget verify --allow-untrusted-root CLI flag with accurate references to the allowUntrustedRoot attribute on certificate elements in nuget.config's trustedSigners section. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename --allow-untrusted-signing to --allow-untrusted-root Align CLI flag naming with existing dotnet nuget trust --allow-untrusted-root per reviewer feedback from @kartheekp-ms. The 'signing' word is redundant since the command context already implies signing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kartheekp-ms
approved these changes
Mar 20, 2026
This was referenced Mar 24, 2026
Merged
3 tasks
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.
Feature
Fixes:
NuGet/Home#14798
Description
Add an
--allow-untrusted-root/-AllowUntrustedRootflag todotnet nuget signandnuget.exe signthat allows signing with certificates whose root CA is not in a trusted root store.Problem
When signing NuGet packages with certificates issued by a root CA that isn't installed in
LocalMachine\RootorCurrentUser\Root,CertificateChainUtility.GetCertificateChainfails with anUntrustedRootchain status error. Installing root CAs into the trusted root store requires admin elevation (triggering a UAC prompt or failing in non-elevated CI containers), which is a significant friction point for build pipelines and developer machines.Solution
Add a new
allowUntrustedRootparameter that movesUntrustedRootfrom the error status flags to the warning status flags inGetChainStatusFlags. This uses the same mechanism NuGet already applies to self-issued certificates (see CertificateChainUtility.cs line 155), extending it to CA-issued certificates when explicitly opted in.The flag is threaded through the full stack:
SignPackageRequest.AllowUntrustedRootproperty; newGetCertificateChainoverload acceptingbool allowUntrustedRootSignArgs.AllowUntrustedRoot;CertificateSourceOptions.AllowUntrustedRoot; wired throughCertificateProvider.IsValid()so certs with untrusted roots aren't filtered out during store discovery-AllowUntrustedRootoption--allow-untrusted-rootoptionKey design decisions
false— no behavioral change unless explicitly enabledX509ChainTrustMode.CustomRootTrust(.NET 5+)UntrustedRootfor self-issued certificatesPR Checklist