Direct-only NuGet audit vs scheduled vulnerability listing for CI noise control
0 reputation · 19 Feb 2022, 13:40 UTC
0 reputation · 19 Feb 2022, 13:40 UTC
A design goal is to keep vulnerability alerts actionable in .NET SDK projects without flooding CI with transitive advisory noise.
Two documented approaches are available. Build-time NuGet Audit can be configured with NuGetAuditMode set to direct, which limits failures and warnings to direct package references. An alternative is on-demand vulnerability listing that produces a point-in-time report outside the build, leaving build behavior unchanged.
The constraint is to retain timely detection of newly introduced direct risks while avoiding alert fatigue from transitive dependencies, and to avoid silent gaps when advisory data is unavailable.
What coverage difference exists between direct-only audit and scheduled on-demand listing for newly added transitive risks? How does NuGetAuditSuppressions maintenance affect long-term signal quality in direct mode? Can both approaches be combined without duplicating alerts for the same advisory?
35275 reputation · 19 Feb 2022, 20:43 UTC
The primary difference between direct-only auditing and scheduled listing is the actionability of the failure. Direct-only auditing identifies vulnerabilities in packages explicitly listed in your project file, meaning the remediation is a simple version bump in the .csproj or packages.config.
In direct mode, NuGetAuditSuppressions maintenance is generally lower-volume but higher-stakes. Since you are only suppressing direct risks, each entry represents a conscious decision to accept a risk for a package you explicitly chose to include. Over time, this maintains a higher signal-to-noise ratio compared to full audits, where suppressions often accumulate for transitive packages that the developer cannot realistically update.
You can combine both strategies by decoupling Build Enforcement from Security Reporting. This prevents duplicate alerts from blocking the pipeline while ensuring visibility.
NuGetAuditMode to direct. This ensures that any new direct vulnerability breaks the build immediately, forcing an actionable fix.dotnet list package --vulnerable. Pipe this output to a security dashboard or a notification channel rather than failing the build.Because the CI build only triggers on direct risks and the scheduled job is a reporting mechanism, you avoid "double-failing" a build for the same advisory. The scheduled report serves as the source of truth for transitive risks that require monitoring or upstream pressure.
To verify the current state of your dependencies and identify the gap between these two methods, run the following command in your project root:
dotnet list package --vulnerable
Compare this full list against the warnings generated during a build with NuGetAuditMode=direct to see exactly which transitive risks are being silenced in your CI pipeline.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 19 Feb 2022, 20:59 UTC
While NuGetAuditMode=direct reduces CI noise, it creates a gap where critical transitive vulnerabilities are ignored. A practical way to bridge this without returning to “all‑inclusive” noise is to use dependency pinning for high‑risk transitive packages.
If a scheduled listing reveals a critical transitive vulnerability that the parent package maintainer hasn't patched, you can explicitly add that transitive package as a direct dependency in your .csproj with the patched version. This effectively “promotes” the package to a direct dependency, allowing NuGetAuditMode=direct to track it and fail the build if it regresses, while keeping the rest of the transitive graph silent.
To verify the current state of your graph before pinning, run:
dotnet list package --vulnerable