Back to blog
|Rorix Team

A Trusted NuGet Registry Is a Policy Decision, Not a Cache

analysisregistrynuget
Package artifacts moving through evidence checks before entering a trusted registry

A conventional NuGet proxy answers an operational question: “Do I already have these package bytes nearby?” A trusted registry must answer a harder one: “Should this exact package version be available to our builds at all?”

Those are different jobs. Caching improves availability and restore speed. Trust requires evidence, a decision, and an enforcement point.

If a registry downloads everything upstream offers and only scans it after publication, the organization still restores packages before its policy has made a decision. The feed may be private, but the trust model is unchanged.

The Package and Its Source Are Separate Claims

A .nupkg can contain a repository URL, a commit identifier, Source Link data, and assembly version metadata. Each item is evidence about where the artifact came from. None should be treated as proof merely because it appears inside the package being evaluated.

A provenance workflow needs to resolve that evidence to an immutable source revision, build it in a controlled environment, and compare the result with the upstream artifact. The comparison may establish a strong connection between source and package—or reveal that important parts differ.

The important thing is to keep the claims separate:

  • Source identity: which repository and commit are associated with the version?
  • Build evidence: was that commit built under controlled conditions?
  • Artifact comparison: how closely does the output match what upstream distributed?
  • Package policy: do security, license, and provenance rules allow publication?

Collapsing all four into a green “trusted” badge hides the information reviewers need.

Trust Is a Ladder, Not a Boolean

Real NuGet ecosystems contain excellent provenance, incomplete metadata, difficult build systems, signed upstream packages, and unsigned legacy artifacts. A useful registry represents those differences rather than pretending every package can take the same path.

Rorix uses explicit provenance levels:

  1. Reproduced source — an exact commit was rebuilt and its normalized package contents and assemblies matched upstream.
  2. Pinned source — an exact commit was rebuilt, but the output differs.
  3. Inferred source — an immutable commit identified through an exact version-tag heuristic was rebuilt.
  4. Upstream signed — the exact upstream bytes were preserved after signature verification.
  5. Digest only — unsigned upstream bytes were preserved with a pinned digest and require a version-specific override.

An organization can select the weakest level it is willing to restore. That turns provenance from descriptive metadata into enforceable policy.

Fallback Must Stay Visible

Source builds will fail. A package may omit its commit, use a build system the isolated environment cannot reproduce, or depend on unavailable tooling. Blocking every such package may be impractical; silently mirroring it and labeling it “verified” is worse.

An honest fallback preserves the exact upstream bytes and labels how they were authenticated. A signed upstream artifact is meaningfully different from an unsigned file known only by digest. Both are meaningfully different from a source rebuild.

Fallback is not a failure of the model. Undisclosed fallback is.

Publication Is the Enforcement Boundary

Scanning a package does not protect a restore unless the result controls whether the package becomes visible. A fail-closed registry publishes only versions that have completed the required checks.

That decision can combine:

  • minimum provenance;
  • vulnerability severity;
  • license policy;
  • suspected typosquatting;
  • recursive dependency eligibility;
  • narrow, reviewed exceptions.

Queued, failed, dependency-blocked, and quarantined versions should not appear to clients as ordinary restore candidates. Otherwise the build can consume an artifact while its decision is still pending.

Exceptions Should Change the Decision, Not the Evidence

There are legitimate reasons to accept a package version that falls below a default threshold. The exception should record the reviewer, rationale, scope, and affected version. It should not delete the original vulnerability, license result, or provenance level.

This distinction preserves auditability. A future reviewer can see both what the system observed and why the organization chose to proceed.

Restore-Time Policy Has Operational Consequences

Moving from upstream packages to source-built artifacts may change NuGet content hashes even when normalized package contents reproduce. Existing packages.lock.json files can therefore require a reviewed migration.

That is a feature of making artifact identity explicit, not a reason to disable locked restores. Regenerate the lock file deliberately, review the changed hashes, commit it, and keep locked mode in CI.

The Rorix Registry documentation describes the provenance ladder, publication gates, and lock-file migration in detail. The product overview shows how those controls fit into the restore path.

A trusted registry is not defined by where package bytes are stored. It is defined by the evidence required before those bytes are allowed to become part of a build.