Configure upstream behavior

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019 | TFS 2018

With upstream sources, developers can use a single feed to publish and consume packages from Artifact feeds and public registries such as NuGet.org or npmjs.com. To set up upstream sources for your feed, check the box to include packages from common public sources. This will allow your feed to use packages from the common public registries.

Include packages from common public sources checkbox

Previously, Artifact feeds combined a list of available package versions from the feed and all the upstream sources.

Previous upstream sources behavior

Upstream behavior is a feature that enables developers to choose if they want to consume externally sourced package versions. Upstream behavior dictates which packages will be made available from the public registries for individual packages.

When the upstream behavior is enabled, when a package is published to your Azure Artifacts feed, any version from the public registry will be blocked and not made available for download.

This approach provides another layer of security by blocking the exposure to malicious packages that may infiltrate the public registries.

Users will still be able to toggle off the upstream behavior setting and consume packages from the public registries if they choose to do so.

Note

The new behavior won't affect any package versions that are already in use. Those are stored in the feed's @local view.

Applicable scenarios

The next section shows a few common scenarios where the upstream behavior is triggered to block externally sourced package versions along with few other cases where no blockage to the public packages is needed.

Public versions will be blocked

  • Private package version made public: in this scenario, a team has a private package that was made public. The upstream behavior in this case will be triggered to block any new public versions (untrusted packages).

    Internal package version made public

  • Having both private and public packages: in this scenario, if a team already has both private and public packages, enabling the upstream behavior will result in blocking any new package versions from the public registry.

    both private and public packages

Public versions will not be blocked

  • All packages are private: if all existing packages are private and the team won't be consuming any public packages, the new upstream behavior will have no effect on the team's workflow in this scenario.

    private packages only

  • All packages are public: if all the packages consumed are public, whether it's from the public registry or any other open-source repositories, the new upstream behavior will have no effect on the team's workflow in this scenario.

    public packages only

  • Public package made private: if a public package is switched to a private package, the new upstream behavior will have no effect on the team's workflow in this scenario.

    switched from public to private

Allow external versions

Note

You must be a feed Owner or a feed Administrator to allow externally sourced versions. See Feed permissions for more details.

  1. Select Artifacts, and then select your feed.

  2. Select your package, and then select the ellipsis button for more options. Select Allow externally-sourced versions.

    A screenshot showing how to set up external versions.

  3. Select the toggle button to allow external versions. Select Close when you're done.

    A screenshot showing how to allow external versions.

Allow external versions using the REST API

Aside from using the feed's user interface, you can also configure the upstream behavior using the Azure DevOps Services REST API. Select the appropriate tab and find the links to the REST API docs.

Allow external versions using PowerShell

  1. Create a personal access token with Packaging > Read, write, & manage permissions.

    Screenshot showing how to select packaging permissions.

  2. Create an environment variable for your personal access token.

    $env:PATVAR = "YOUR_PERSONAL_ACCESS_TOKEN"
    
  3. Convert your personal access token to baser64 encoded string and construct the HTTP request header.

    $token = [Convert]::ToBase64String(([Text.Encoding]::ASCII.GetBytes("username:$env:PatVar")))
    $headers = @{
        Authorization = "Basic $token"
    }
    
  4. Construct your endpoint url. Example: //pkgs.dev.azure.com/MyOrg/MyProject/_apis/packaging/feeds/MyFeed/nuget/packages/pkg1.0.0.nupkg/upstreaming?api-version=6.1-preview.1

    • Project-scoped feed:

      $url = "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_apis/packaging/feeds/<FEED_NAME>/<PROTOCOL>/packages/<PACKAGE_NAME>/upstreaming?api-version=6.1-preview.1"
      
    • Organization-scoped feed:

      $url = "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_apis/packaging/feeds/<FEED_NAME>/<PROTOCOL>/packages/<PACKAGE_NAME>/upstreaming?api-version=6.1-preview.1"
      

Run the following command to retrieve the upstream behavior state of your package. $url and $headers are the same variables we used in the previous section.

Invoke-RestMethod -Uri $url -Headers $headers