Skip to main content

Overview

NuGet.VerifyMicrosoftPackage is a developer-facing command-line tool that Microsoft teams use to catch NuGet package metadata compliance problems before pushing to nuget.org. Rather than discovering violations at upload time through server-side security policies, this tool runs the same rule-set locally so teams can fix packaging issues earlier in the release pipeline. The tool validates .nupkg files against a configurable JSON rule set. The built-in default rule set encodes the MicrosoftTeamSubscription policy from NuGetGallery.Services: required co-owner username "Microsoft", allowed copyright notices in 18 locales, required authors field containing only "Microsoft", and mandatory licenseUrl/projectUrl fields.
The tool only validates .nuspec metadata. It does not verify author signatures, package size limits, Authenticode on DLLs, or nuget.org-specific pre-release label rules. Those gaps are documented in the README as future work.

Role in the NuGetGallery Ecosystem

Server-side mirror

The same compliance logic enforced by MicrosoftTeamSubscription on the gallery server is exposed here for local use, keeping client and server behaviour in sync.

Developer shift-left

Allows Microsoft package authors to run verify.ps1 *.nupkg in CI before pushing, surfacing the exact error messages they would see on nuget.org.

Distributed as a NuGet tool package

Packaged as NuGet.VerifyMicrosoftPackage (tools layout) and published to nuget.org. verify.ps1 downloads it on demand via nuget.exe install.

Configurable rule sets

Teams can export the default JSON rule set, customise it, and pass it back via --rule-set, enabling policy variations without recompiling.

Key Files and Classes

File path (relative to src/VerifyMicrosoftPackage/)Class / SymbolPurpose
Program.csProgramEntry point; delegates to Application.Execute() and maps exit codes to error states
Application.csApplicationExtends CommandLineApplication; owns all CLI option parsing, wildcard file expansion, package loading, and compliance reporting
VerifyMicrosoftPackage.csprojnet472 exe; references NuGetGallery.Services and Microsoft.Extensions.CommandLineUtils
VerifyMicrosoftPackage.nuspecPacks the net472 build output into tools/ for consumption as a NuGet tool package
verify.ps1PowerShell bootstrap script; downloads nuget.exe and the tool package, then invokes the exe
Fakes/FakeEntityRepository.csFakeEntityRepository<T>In-memory IEntityRepository<T> with no-op mutations; satisfies PackageService constructor without a database
Fakes/FakeEntitiesContext.csFakeEntitiesContextStub IEntitiesContext — all members throw NotImplementedException; only the constructor path through PackageService is exercised
Fakes/FakeSecurityPolicyService.csFakeSecurityPolicyServiceStub ISecurityPolicyService; policy evaluation is not needed at validation time
Fakes/FakeTelemetryService.csFakeTelemetryServiceStub ITelemetryService; most methods throw, but ArePatternSetTfmHeuristicsEnabled returns true to allow TFM parsing
Fakes/FakeAuditingService.csFakeAuditingServiceStub IAuditingService
Fakes/FakeContentObjectService.csFakeContentObjectServiceStub IContentObjectService
Fakes/FakeFeatureFlagService.csFakeFeatureFlagServiceStub IFeatureFlagService; ArePatternSetTfmHeuristicsEnabled() returns true
Key types from NuGetGallery.Services used at runtime:
File (in NuGetGallery.Services/Security/)ClassPurpose
MicrosoftTeamSubscription.csMicrosoftTeamSubscriptionDefines the canonical Microsoft package policy and the 18-locale copyright allowlist
RequirePackageMetadataState.csRequirePackageMetadataStateJSON-serialisable DTO representing one rule set (authors, copyright, URL requirements, error format)
RequirePackageMetadataComplianceUtility.csRequirePackageMetadataComplianceUtilityStatic utility; deserialises a RequirePackageMetadataState from UserSecurityPolicy values and runs the four compliance checks

Dependencies

NuGet Package References

PackagePurpose
Microsoft.Extensions.CommandLineUtilsCLI argument / option parsing (CommandLineApplication base class)
Newtonsoft.Json(transitive via NuGetGallery.Services) JSON serialisation of rule sets
NuGet.PackagingPackageArchiveReader — reads .nupkg zip entries and nuspec

Internal Project References

ProjectHow it is used
NuGetGallery.ServicesProvides PackageService, MicrosoftTeamSubscription, RequirePackageMetadataComplianceUtility, RequirePackageMetadataState, CryptographyService, and all gallery entity types

Framework / BCL

AssemblyReason
System.WebRequired by ISecurityPolicyService signatures (HttpContextBase) even though policy evaluation is never called

Notable Patterns and Implementation Details

Fake service wiring pattern. Application.GetPackageService() constructs a real PackageService instance by injecting eight fake collaborators. None of the fakes implement actual behaviour — they exist solely to satisfy the constructor. Only the CreatePackageAsync code path is exercised, and it only reads from the PackageArchiveReader; no database, audit, or telemetry calls are made.
Rule set derivation. The default rule set is not hard-coded in this project. Application.GetDefaultRuleSet() instantiates MicrosoftTeamSubscription and deserialises its Policies collection through RequirePackageMetadataComplianceUtility.DeserializeState. This means the tool and the gallery server share exactly the same policy definition — a change to MicrosoftTeamSubscription automatically flows into the tool on next build.
FakeFeatureFlagService.ArePatternSetTfmHeuristicsEnabled() returns true (not throw). This is the only non-throwing stub method in the feature flag fake and is required for PackageService.CreatePackageAsync to correctly parse target framework monikers from the .nuspec. If this is accidentally changed to throw, package creation will fail at runtime.
Exit code conventions. The exe returns 0 on full success, -1 for help/version/bad arguments, -2 for unexpected exceptions, and the count of invalid packages (a positive integer) when validation completes with failures. verify.ps1 treats any non-zero exit as an error via Write-Error.
Custom rule sets. Run NuGet.VerifyMicrosoftPackage.exe --rule-set custom.json --write-default-rule-set to export the default JSON rule set, then edit and pass it back with --rule-set custom.json for team-specific overrides without touching gallery code.
Wildcard support is directory-scoped. Wildcards in the filename portion of a path (e.g., *.nupkg) are supported and can be made recursive with --recursive. Wildcards or globs in the directory segment are not supported — the directory must be a literal path.

CLI Reference

Usage: NuGet.VerifyMicrosoftPackage [arguments] [options]

Arguments:
  PATHS  One or more file paths to a package (.nupkg).

Options:
  -v | --version            Show version information.
  -? | -h | --help          Show help information.
  --recursive               Evaluate wildcards recursively into child directories.
  --rule-set                A path to a JSON rule set file.
  --write-default-rule-set  Write the default rule set to the --rule-set file path.

Quick Start

# Download and run against all .nupkg files in the current directory
$url = "https://raw.githubusercontent.com/NuGet/NuGetGallery/master/src/VerifyMicrosoftPackage/verify.ps1"
Invoke-WebRequest $url -OutFile verify.ps1
.\verify.ps1 *.nupkg

# Export the default rule set for inspection or customisation
.\NuGet.VerifyMicrosoftPackage.exe --rule-set default.json --write-default-rule-set

# Validate with a custom rule set
.\NuGet.VerifyMicrosoftPackage.exe --rule-set custom.json path\to\MyPackage.1.0.0.nupkg