How to Create a Package Approval Workflow for NuGet
by Eric Seng, on Oct 19, 2021 3:01:00 AM
Getting a NuGet reviewed and approved is frustrating and restricting even when the process goes smoothly. Consuming third-party packages straight from NuGet.org is bad.
But how should someone request a package review? Email? Ticket system? And after it's reviewed and approved, where should the package be sent?
In this article, I’ll outline why you need a NuGet package approval workflow and show you how to do it in ProGet.
Package Approval Workflow
A package approval process is just like a code review but for packages, your team would like to use. It can be as casual as sending an email to an approver OR it could have a formal gated process where multiple people sit in a room and discuss it.
Creating a standard package approval workflow simplifies the approval process for developers & approvers, ensures all the packages your team is using pass a quality check, and makes it extremely easy for developers to access all the packages they need.
Since both developers and build servers access ProGet, it's important to create a standard process for both.
Package approval workflows are restrictive and often frustrating for Developers to stick to. If the package workflow is too difficult to follow, Developers will often find a way around the workflow. However, if a package approval workflow is isn't restricting enough, you risk packages with dependency, vulnerability, or quality issues making it to production.
The following guidelines create a process that balances both convenience and quality.
There are 3 main features that are important for you to pay attention to when setting up your NuGet Package Approval workflow are: Feeds, Package Promotion, and Connectors.
A feed in ProGet are used to store NuGet packages, and developers can connect to different feeds to see what's packages are available to use. They can also "proxy" packages from another feed using connectors.
The necessary number of feeds varies by organization. If you have multiple teams/groups that require separate feeds with separate permissions, you may want to do one feed per team/group (e.g. team-b-nuget, team-a-nuget.) While this lets you restrict teams and manage packages better, this makes the approval workflow much more complex.
Setting up a NuGet feed in ProGet is simple. Navigate to "Feeds" in the ribbon and select "Create New Feed." After creating a new feed, click on NuGet and fill in the feed details including name, description, and feed usage.
As I said, larger more complex team structures will require many different feeds. However, most teams need these three feeds:
|Unapproved packages from nuget.org||Read-Only For Devs||Raw packages from Nuget.org|
|Approved packages that have been reviewed||Read-Only For Devs
Approvers can Promote here
|Only approved NuGet.org packages|
|Internal + Approved Packages||Read-Only For Devs
Read-write for Build Servers
|All available packages|
Unapproved Third-Party NuGet Packages
This feed is where a requested package is reviewed. Only approvers should have access to edit/promote packages from this feed to the “Approved” feed.
This feed should have a connector to nuget.org so packages can be easily accessed for review.
Approved Third-Party NuGet Packages
The package has now been approved and promoted to this feed. Therefore, there should be no connectors to nuget.org.
This feed should still be read-only for most devs since approved packages are connected to the Internal + Approved Package feed.
Internal + Approved Third-Party Packages
This feed should contain both pre-release and stable internal packages.
In this example, we’ve created a feed clearly labeled MyCompany-Nuget that all devs should have access to. Having only 1 feed makes it convenient and easy for devs and your build servers to access all the packages they need/are permitted to use.
There’s no need to separate pre-release packages into their own feed since Visual Studio already filters them out by default. However, it is best practice to make a process rule on your team that pre-release packages can’t be deployed into production. ProGet will automatically clean up unused prerelease packages, deleting pre-release versions that are unused.
Package Promotion & Permissions
Package promotion is the process of promoting packages between feeds to ensure that only approved and verified packages are used in the right environments. Senior developers that have been trained to approve packages should be the only ones with access to promote packages from "Unapproved" to "Approved."
ProGet allows for teams to easily give/restrict permissions based on users and user groups.
Working with a package approval workflow is restrictive and frustrating. Requiring your team to configure or work between multiple feeds makes it a complex burden. People often look for the path of least resistance and in retaliation, many are most likely to get frustrated and become unproductive or completely bypass internal feeds and go to nuget.org for packages.
Developers should be generally just use a single feed that has internal and approved third-party packages. Supplying developers with a single feed with all packages they need (e.g. mycompany-nuget) lets them to work without the worrying about whether a package is approved or not.
Approvers (Promote to Approved)
Approvers (i.e. senior developers with training on how to approve packages) should be the only ones on your team that have promote-access in ProGet. Approvers are responsible for reviewing packages and promoting them from “unapproved” to “approved.”
There are three things that an approver should be trained to review on NuGet packages:
- Licensing; does this package have an appropriate license
- Vulnerabilities; is this package generally safe to use
- Quality; is this a high-quality, Enterprise-ready library
Developers also need to receive proper training on how to ask for permission; this can be as simple as sending an email.
And of course, approvers need to learn how to follow this process effectively and quickly – same-day if possible. Keep in mind, developers will always take the path of least resistance. If they know that approval takes more than 1 day, they’re most likely going to simply access NuGet.org themselves.
Build Servers (Publish to Internal)
Build Servers access your feeds, same as your developers. So, it makes sense to create rules and standards that your build servers should follow as well.
Build Servers should use an API Key that has permission to consume from and publish to the Internal + Approved Third-Party Packages feed (mycompany-nuget) and should only be able to access that feed. In order to publish, the build server will have to receive special access to that feed.
This way, builds will fail if unapproved third-party packages are used and give developers immediate feedback. When that happens, a developer can recognize package is not approved, and submit approval. Following CI/CD best practices, only the machine can continue to create builds, not developers.
Connectors allow ProGet feeds to include packages from an external source, whether it is another ProGet feed, a public gallery like NuGet.org, or another third-party package source like Azure DevOps Packages or Artifactory.
Your "Unapproved" feed should be the only feed with an external connector.
Approvers should be responsible for reviewing packages in your "Unapproved" feed and promoting them to "Approved" which is then connected to "First Party + Approved Third-Party Packages."
Setting up connectors in ProGet is straightforward after setting up a feed. Navigate to the feed and click on add connector. Here you can set the connector URL, name, username, and password.
Tool + Training
A package approval can be as casual as sending an email to an approver OR it could have a formal gated process where multiple people sit in a room and discuss it.
Feel free to use our basic package approval policy as a starting point. Inedo Developers follow 3 simple rules:
- Developers don’t decide on which packages to use nor when to upgrade packages in use.
- If developers need to use a new package or upgrade an existing package, they need to ask a senior developer for a package review.
- Developer’s workstations (Visual Studio, etc.) are connected to ProGet and only ProGet.
You don’t NEED a formal policy, but you need a standard to ensure package quality.
ProGet can create feeds and restrictions, but an internal standard and training is necessary for a package approval workflow to be successful. Developers should be trained on how to use appropriate feeds and ask for approval while approvers should be trained on how to recognize inappropriate packages due to licenses, vulnerabilities, or quality and make judgments on them.
I can’t stress enough how important human review is in your package approval workflow. Automated blanket approvals don’t make sense. For example, a rule like "all packages by Microsoft" are approved might reduce package approval work in the beginning but it might also allow technology preview or beta packages that may is buggy and not suitable. It could also mean that a new version of a framework that no one has training on like Microsoft.EntityFrameworkCore is used. Approvers will also help prevent dependency confusion attacks. A machine might believe that MyCompany.Lib 9.9.9 is a legitimate package, while a human would catch it immediately.
Package approval workflows can be as simple or formal as your company needs/is comfortable with. What's important is that your company has an approval workflow.
Requiring a trained approver to review packages before they have the chance to make it to the developers will increase security, quality, and reduce the risk of an inappropriately licensed package ever sneaking its way into production, essentially applying CICD best practices to your third-party NuGet packages.
But this is just the tip of the iceberg when using NuGet in an Enterprise, and we’re working on a free guide that covers this topic and much more!