One command.
Every NuGet supply chain risk.

The Authors field in every NuGet package is free text. Anyone can claim Authors = "Microsoft" — and neither Visual Studio nor the .NET CLI will warn you. nuget-audit uses nuget.org's cryptographically backed publisher verification, not self-reported metadata. It is also the enforcement layer for the full zero-trust NuGet workflow — from project setup through CI gate — and verifies that every control is in place.

dotnet tool install -g nuget-audit — requires .NET 8 SDK or later
Windows · macOS · Linux .NET global tool CI/CD ready VS pre-build integration

Why not just use what you already have?

Package Source Mapping, lock files, Dependabot, and vulnerability scanning are all valuable — but each covers a different slice. None of them surfaces the one signal that matters most: whether the publisher is actually who they claim to be.

What you might already have Publisher identity Detection window Enforcement gate Setup advisory
dotnet list package --vulnerable No — CVEs only No No No
Package Source Mapping No — feed isolation only No No No
NuGet lock files + RestoreLockedMode No — graph pinning only No Partial No
Dependabot No Can auto-merge within window No No
nuget-audit audit --check Yes Yes — flags recent versions Yes — exit code 1 Yes — warns on missing setup

nuget-audit audit --check in CI is a single pass/fail gate that covers all of the above — and warns you when any complementary control is not configured.

What it looks like

By default, only packages that need action are shown. A clean project produces no output and exits with code 0.

Flagged audit
Found 2 package(s) needing review.

Type    PackageId       Version  Owners         Verified  Trust
------  --------------  -------  -------------  --------  -------
Direct  Contoso.Http    3.1.0    contoso-oss    No        Untrusted
Direct  SomeLib         2.0.0    known-owner    Yes       VersionChanged

Recently published (within 14 days):
  Contoso.Http 3.1.0  published 3 days ago  [Untrusted]
Clean audit
Found 0 package(s) needing review.

No packages match the current filter.

Recently published:
  No packages published within
  the last 14 days.

Exit code: 0

Run nuget-audit audit --all to see every package with its trust status, or nuget-audit audit --check for a counts-only CI gate.

The detection window

Most NuGet supply chain attacks are detected within days of a compromised version being published — by the community, security researchers, or automated scanning. This creates a defensible window: a version in the ecosystem for weeks without incident is meaningfully safer than one published yesterday.

nuget-audit flags any package version published within recentDaysThreshold days (default: 14) regardless of trust status. A verified Microsoft.* package published two days ago carries more risk than one published six months ago — account compromise, insider threat, and build pipeline compromise do not respect the verified flag.

The recency check also provides substantial coverage for ownership transfer attacks — where a package is sold or transferred to a malicious actor who then publishes a compromised version. That version will be flagged as recently published. The unmitigated residual is a version that ages past the threshold before the community detects it — an attacker must simultaneously achieve both conditions. Pair with NuGet package signing (<trustedSigners> in NuGet.Config) for ownership-transfer detection independent of the recency window.

Dependabot and the detection window

Dependabot can auto-merge a dependency PR within hours of a compromised version being published — well inside the detection window. See the Dependabot integration guide for the mitigation pattern.

Trust model

Each package is evaluated against a layered model. The primary signal is nuget.org prefix reservation (verified=true) — a cryptographically backed flag that cannot be self-reported by an attacker, unlike the free-text Authors field. You configure which verified owners you trust and which specific package versions you have manually reviewed.

ConditionTrust StatusAction needed?
404 on nuget.org — private or local feed PrivateFeed No
verified=true + owner in trusted owners Verified No
Exact ID+version in trusted packages list TrustedPackage No
verified=true + owner not in trusted owners VerifiedUnknownOwner Yes — add owner to trustedOwners if you trust them broadly, or pin the version in trustedPackages for per-version review
ID in trusted packages, but version changed VersionChanged Yes — urgent, re-review
Not verified, not in trusted packages Untrusted Yes — review required

trustedOwners vs trustedPackages

When you see VerifiedUnknownOwner, you have two options:

Add the owner to trustedOwners for publishers you trust across their entire catalog — well-known organizations like Microsoft, AWS, Google, whose packages you use broadly and will track as they update. Future packages from this owner are trusted automatically.

Add the specific version to trustedPackages for everything else. Even for verified publishers, pinning a version means you explicitly review each update before it enters your project. This is the more conservative, zero-trust default — and the version-pinning cost is highest exactly where the scrutiny should be highest: publishers you haven't fully evaluated.

Everything in one pass

🔍

Publisher verification

Uses nuget.org prefix reservation — the only signal an attacker cannot self-report. Not the free-text Authors field.

🕐

Detection window

Flags recently published versions regardless of trust status. Configurable threshold, default 14 days.

⚠️

CVEs & deprecation

Surfaces known vulnerabilities and deprecated packages from nuget.org metadata in the same pass.

🔎

Exec content detection

Flags packages containing MSBuild targets, Roslyn analyzers, or tool executables — the content that runs at build time.

👁️

Pre-restore preview

Resolve the full transitive graph before anything downloads. Review what will land on disk before it does.

🔒

Setup enforcement

Warns when lock files, RestoreLockedMode, the VS pre-build sentinel, or Package Source Mapping are not configured — and --check exits 1 on any of these conditions.

🚦

CI/CD gate

--check returns exit code 1 on any package issue or setup advisory. Clean pass/fail signal for any pipeline or VS pre-build target.

🖥️

VS pre-build enforcement

MSBuild target runs --check automatically before each build when the lock file changes.

Quick start

Install

dotnet tool install -g nuget-audit

Audit your solution

# Create TrustConfig.json and Directory.Build.targets with defaults
nuget-audit init --path .

# Run the audit
nuget-audit audit --path MySolution.slnx

# See the full workflow walkthrough
nuget-audit guide

Add to CI/CD

# Gate 1: restore fails if lock file is out of date
dotnet restore

# Gate 2: audit fails if any packages need review
nuget-audit audit --check --path .
New to the zero-trust approach?

The full team workflow — new projects, package updates, cloning, CI/CD, Dependabot, VS pre-build enforcement, and where the policy can break down — is documented in the zero-trust workflow guide. For individual developers on teams that haven't adopted the policy, see the solo dev workflow.

Ready to audit?

Requires .NET 8 SDK or later. Runs on Windows, macOS, and Linux.

Install from NuGet.org Read the user guide