Skip to content

Add refreshed nuget staging proposal#14978

Open
japarson wants to merge 3 commits into
devfrom
japarson/staging
Open

Add refreshed nuget staging proposal#14978
japarson wants to merge 3 commits into
devfrom
japarson/staging

Conversation

@japarson

@japarson japarson commented Jul 7, 2026

Copy link
Copy Markdown

Design spec for package staging on nuget.org. Builds on the 2024 Release Staging and Deprecation proposal with a narrower scope and a security-first approach.

Related: NuGet/NuGetGallery#3931
Rendered document: https://github.com/NuGet/Home/blob/japarson/staging/accepted/2026/package-staging.md

@japarson japarson marked this pull request as ready for review July 7, 2026 08:12
@japarson japarson requested a review from a team as a code owner July 7, 2026 08:12
@Nigusu-Allehu Nigusu-Allehu self-requested a review July 7, 2026 14:41

All commands support `--format json` for machine-readable output.

**`dotnet nuget stage push`**

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I see we are adding a new command. What happens to the exisitng dotnet nuget push command?

I would assume we won't be deprecating it as it would still be used by other package sources.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not change the behavior for 'dotnet nuget push'


### Supply chain protection

If a CI/CD pipeline is compromised or credentials leak, an attacker can push malicious packages to nuget.org today. Staging introduces a separation between pushing and publishing. CI/CD can only stage packages. A human must log into nuget.org (which requires two-factor authentication) to publish them. Even if an attacker compromises a build pipeline, they can only stage invisible packages that never reach consumers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if a customer runs dotnet nuget push(How does the server react to these requess)? They could be on an old dotnet sdk.


## Summary

Package staging lets authors push packages to nuget.org ahead of time, run them through full validation (malware scanning, signing), and publish them later with a single action through the Gallery UI. Staged packages are invisible to consumers until published. Publishing requires logging into nuget.org, which enforces two-factor authentication as a proof of presence check.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it would be nice if we could have a sentence per line. Makes commenting during reviews much easier.


### Publish latency

Today, the time from push to all packages being restorable includes validation plus the V3 pipeline (catalog, flat container, registration, search). For 2000 packages, total time was about 2 hours during the March 2026 Patch Tuesday. By removing validation from the critical path, the only remaining cost is the V3 pipeline, which should bring the total time from publish to restorable down significantly.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should call out that we made work to bring the V3 ingestion down from 1 hour to around 5 minutes. So I overall, we will be able to manage to bring down the published time from 2 hours to only 5 min, assuming package are properly staged and validated prior to release

dotnet nuget stage push MyPackage.1.0.0.nupkg
```

The package goes through the same validation pipeline as a normal push: malware scanning, author signature checks, certificate revocation checks, and repository co-signing. The difference is what happens after validation succeeds. Instead of becoming publicly available, the package enters a "staged" state. It is not restorable, not searchable, and not visible on nuget.org to anyone except the package owner.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the package are visible at all even for the package owners. Package Owner would only be able to see the staged package from the UI, not through search. Let's clarify that.

Packages can optionally be organized into staging groups. A group is a named collection of staged packages owned by a user or organization.

```
dotnet nuget stage group create my-release --name "My Release"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to have a create command. Let's simplify this!

If you do 'dotnet nuget stage --group "BCL Release 11.0" , the push will automatically stage the package under that group. If you do not supply the --group, the package will be stage under no group


The nuget.org Manage Packages page adds two new sections:

![Manage Packages - Staged Packages and Staging Groups](images/staging-manage-packages.png)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only have one category: "Staged Packages" When expanding Stage Packages, staged packages would be grouped by "Groups", one of the group being "none". It's important for the groups to be expanded in order to see the packages visible under that group. For instance, if a package fails to validate, the ability to re-kick a validation needs to be available, even for packages under a group


All commands support `--format json` for machine-readable output.

**`dotnet nuget stage push`**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not change the behavior for 'dotnet nuget push'


**`dotnet nuget stage group create`**

Create a new staging group.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need that command.

Delete a staged package. Fails if the package is currently validating.

```
dotnet nuget stage delete <PACKAGE_ID> <VERSION> [options]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I which context this command would be needed?

```
Staging Groups (2 groups)

Group ID Name Packages Status Expires

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Ungroup) should an implied group for ungrouped packages


**`dotnet nuget stage group delete`**

Delete a staging group and all its staged packages. Fails if any package in the group is currently validating.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a --force command to force deletion of a group no matter what?


- **Publish is not automatable.** Requiring Gallery UI login means publishing cannot be scripted or run from CI/CD. This is intentional for security but adds a manual step to release workflows. Someone has to log in and click "Publish" on release day.

- **No atomic publish.** We are not guaranteeing that all packages in a group become restorable at the exact same instant. The V3 pipeline processes packages in batches and there will be a small window (minutes) where some packages are available and others are not. Package authors who need strict ordering should manage dependency sequencing on their side.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By dependencies sequencing, this means proper grouping. For instance, BCLs groups should be release first, then SDK Libraries and then Tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants