At Microsoft, we use many private NuGet repositories. High-security environments often require developers to consume packages from internally managed and curated repositories, whether working with C# and NuGet, Java and Maven, or any other programming language with a package manager. Before joining Microsoft, I hadn’t often worked in environments that required managing private NuGet repositories, so this was a new challenge for me.

The first time I encountered this requirement, it was a bit flabbergasting because I couldn’t even build my code due to a failed .NET restore. On my Windows PC, the NuGet packaging worked seamlessly, but on my primary machine—a MacBook Pro 16”—I was unable to restore packages from internal repositories. It turns out that I needed to run the restore process interactively.

Initial Error Encountered

When attempting to restore a private .NET NuGet feed, I ran into the following error:

: error NU1301: Unable to load the service index for source https://pkgs.dev.azure.com/foo/bar/_packaging/bar_PublicPackages/nuget/v3/index.json. Response status code does not indicate success: 401 (Unauthorized). Restore failed with 1 error(s) and 4 warning(s) in 20.1s

This error indicates that authentication is required but has not been successfully provided. While Microsoft documentation offers multiple solutions, many involve embedding credentials within your local system, such as in environment variables or a NuGet configuration file — options that are not ideal for security reasons.

The documentation gives quite a few not so good answers.

The first couple options covered all include embedding credentials somewhere in your local system. Either in an environment variable or within a nuget file. This is a non-starter.

Using a NuGet Credential Provider

The best approach for securely authenticating a private NuGet feed is to use a NuGet credential provider. Running the following command enables interactive authentication:

dotnet restore --interactive

Executing this command may result in the following output:

[CredentialProvider]DeviceFlow: https://pkgs.dev.azure.com/foo/bar/_packaging/foobar_PublicPackages/nuget/v3/index.json
[CredentialProvider]ATTENTION: User interaction required.

**********************************************************************

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code FOOBAR to authenticate.

**********************************************************************

Follow these steps to complete authentication:

  1. Open a web browser and navigate to https://microsoft.com/devicelogin.
  2. Enter the provided code (e.g., FOOBAR) to authenticate.
  3. Sign in with your corporate credentials.
  4. Wait for the authentication process to complete.

Once authentication is successful, your package restore should proceed without issues.

Touching Secrets: Just Say No!

Of course, there are options where you can use secrets, but one of the major initiatives we’re following at Microsoft is to avoid storing secrets and instead use implicit authentication based on identity. This could be user identity for interactive authentication or managed identity for machine-to-machine authentication. This approach enhances security and reduces the risks associated with credential leakage.

Conclusion

By using the dotnet restore –interactive command and following the authentication process, you can securely restore a private NuGet feed without embedding credentials in your local system. Adopting implicit authentication based on identity, rather than secrets, aligns with best security practices ensuring a safer and more manageable authentication process.