Package Source Mapping
Describes package source mapping functionality and how to onboard
Package Source Mapping is a tool that can be used to improve your supply chain security, especially if you use a mix of public and private package sources.

By default, NuGet will search all configured package sources when it needs to download a package. When a package exists on multiple sources, it may not be deterministic which source the package will be downloaded from. With Package Source Mapping, you can filter, per package, which source(s) NuGet will search.

We also have suggestions for other best practices to help you fortify your supply chain against attacks.

Package Source Mapping was added in NuGet 6.0. Starting with Visual Studio 17.5, you can add and remove Package Source Mappings with the Visual Studio Options Dialog.

Visual Studio support

Visual Studio Package Source Mapping Support in Tools -> Options Support in Package Manager UI 17.0 - 17.4 â Available â Not available â Not available 17.5 â Available â Available â Not available 17.7 Preview 3 â Available â Available â Status displayed

The feature is available across all NuGet integrated tooling.

Visual Studio 2022 and later

.NET SDK 6.0.100 and later

nuget.exe 6.0.0 and later

Older tooling will ignore the Package Source Mapping configuration. To use this feature, ensure all your build environments use compatible tooling versions.

Package Source Mappings will apply to all project types â including .NET Framework â as long as compatible tooling is used.

Video walkthrough

For a video-based overview of the Package Source Mapping feature, consider watching the Secure your NuGet packages with Package Source Mapping video on YouTube.

Enabling Package Source Mapping

To opt into this feature, you must have a nuget.config file. Having a single nuget.config at the root of your repository is considered a best practice. See nuget.config documentation to learn more.

Enable by using Visual Studio Options Dialog

Open your solution in Visual Studio.

Navigate to the Package Source Mappings Options Dialog.

From the Package Manager UI

Select a package from the list to show it in the Details Pane.

Press the Configure button to open the Package Source Mappings options page.

From the Visual Studio Options Dialog

Go to the Tools menu in the main Visual Studio toolbar, and choose NuGet Package Manager -> Package Manager Settings.

Navigate to the Package Source Mappings page.

Press the Add button in the Package Source Mappings page to open the Add Package Source Mappings dialog.

4. Enter a Package ID or Package Pattern, and select one or more package source(s) by toggling the checkbox for your desired source(s).

The Package Source Mapping options page will show the newly created source mapping.

Press OK on the Options Dialog to save changes to the applicable nuget.config.

The NuGet Package Manager window will refresh and reflect the new status of the selected package's source mappings.

Enable by manually editing nuget.config

Declare your desired package sources in your nuget.config file.

Following your source declarations, add a <packageSourceMapping> element that specifies the desired mappings for each source.

Declare exactly one packageSource element for each source in use.

Add as many patterns as you find necessary.

<?xml version="1.0" encoding="utf-8"?> <configuration> <!-- Define the package sources, nuget.org and contoso.com. --> <!-- `clear` ensures no additional sources are inherited from another config file. --> <packageSources> <clear /> <!-- `key` can be any identifier for your source. --> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="contoso.com" value="https://contoso.com/packages/" /> </packageSources> <!-- Define mappings by adding package patterns beneath the target source. --> <!-- Contoso.* packages and NuGet.Common will be restored from contoso.com, everything else from nuget.org. --> <packageSourceMapping> <!-- key value for <packageSource> should match key values from <packageSources> element --> <packageSource key="nuget.org"> <package pattern="*" /> </packageSource> <packageSource key="contoso.com"> <package pattern="Contoso.*" /> <package pattern="NuGet.Common" /> </packageSource> </packageSourceMapping> </configuration>

Package Source Mapping settings are applied following nuget.config precedence rules when multiple nuget.config files at various levels (machine-level, user-level, repo-level) are present.

Package Source Mapping rules

For maximum flexibility and control, NuGet requires that all packages match a package pattern through a well defined precedence.

Package Pattern requirements

All requested packages must map to one or more sources by matching a defined package pattern. In other words, once you have defined a packageSourceMapping element you must explicitly define which sources every package - including transitive packages - will be restored from.

Both top-level and transitive packages must match defined patterns. There is no requirement that a top level package and its dependencies come from the same source.

The same ID pattern can be defined on multiple sources, allowing matching package IDs to be restored from any of the feeds that define the pattern. However, this isn't recommended due to the impact on restore predictability (a given package could come from multiple sources). This may be a valid configuration if you trust all respective sources.

Package Pattern Syntax

Pattern Example syntax Description Package prefix pattern *, NuGet.* Must end with a *, where * matches 0 or more characters. * is the shortest allowed prefix pattern and matches all packages ids. Package ID pattern NuGet.Common, Contoso.Contracts Exact package ID.

Package Pattern precedence

When multiple unique patterns match a package ID, the most specific one will be preferred. Package ID patterns always have the highest precedence while the generic * always has the lowest precedence. For package prefix patterns, the longest has precedence.

Setting default sources

The * pattern can be used to make a declare a de-facto default source - meaning any package that doesn't match other specified patterns will be restored from that source without throwing an error. This configuration is advantageous if you primarily use packages from say, nuget.org, and only have a few internal packages, or use standard prefixes for all internal packages like Contoso.*.

If your team doesn't use standard prefixes for internal package IDs or vets nuget.org packages prior to installation, then making a private source the default will suit your needs better.

Get started

There are 2 ways you can fully onboard your repository, manually or using the NuGet.PackageSourceMapper tool.

Manual onboarding

For manual onboarding you may take the following steps:

Declare a new global packages folder for your repo.

Run dotnet restore to restore dependencies.

Run dotnet list package --include-transitive to view all top-level and transitive packages in your solution.

For .NET framework projects using packages.config, the packages.config file will have a flat list of all direct and transitive packages.

Define mappings such that every package ID in your solution - including transitive packages - matches a pattern for the target source.

Run dotnet nuget locals global-packages -c to clear global-packages directory.

Run restore to validate that you have configured your mappings correctly. If your mappings don't fully cover every package ID in your solution, the error messages will help you identify the issue.

When restore succeeds, you are done! Optionally consider:

Simplifying the configuration to fewer declarations by using broader package ID prefixes or setting a default source where possible.

Verifying the source each package was restored from by checking the metadata files in the global packages folder or reviewing the restore logs.

Automated onboarding using tool

Many repositories have a large number of packages and doing the work manually can be time consuming. The NuGet.PackageSourceMapper tool can automatically generate a NuGet.config for you, based on your project's known packages and sources.

The package source mapper tool requires you to have completed a successful package restore in which it will read each respective .nupkg.metadata file generated as part of your build to best understand how you map your respective packages and sources. Tool not only covers top dependencies it also considers all the transitive dependencies when generating mapping.

Tool has several option how to generate mapping pattern depending on your need, please check blog post and tool's readme instruction for more details.