5.2 Feed Scoping, Upstream Sources & Pipeline Authentication

Key Takeaways

  • Project-scoped feeds are the modern default and inherit project permissions; organisation-scoped feeds are shared across every project and are harder to govern.
  • An upstream source caches every package pulled from a public registry into the feed, so the build keeps working during a public registry outage or package unpublish.
  • Dependency confusion occurs when a public registry serves a higher version of an internal package name; the defence is a single feed with upstreams plus reserved or scoped names.
  • Azure Pipelines authenticates to Azure Artifacts with the built-in NuGetAuthenticate and npmAuthenticate tasks using $(System.AccessToken) - no personal access token is required.
  • An HTTP 401 on npm install from a Microsoft-hosted agent almost always means the .npmrc registry entry is missing or the build service identity lacks the Feed Reader role.
Last updated: September 2026

5.2 Feed Scoping, Upstream Sources & Pipeline Authentication

Choosing the platform is the easy half. The operational half is deciding who can consume a feed, what happens when the public registry is unavailable or hostile, and how a build agent authenticates without a stored credential.

Feed Architecture in Azure Artifacts: Project-Scoped vs. Organization-Scoped

When creating a feed in Azure Artifacts, administrators must choose between two scoping models: Project-scoped feeds and Organization-scoped feeds. This structural decision dictates security boundaries, access inheritance, and URL endpoints.

Azure Artifacts Feed Scoping Hierarchy:

[Azure DevOps Organization: contoso-devops]
 │
 ├── Organization-Scoped Feed: [Enterprise-Common-Libraries]
 │     └── URL: https://pkgs.dev.azure.com/contoso-devops/_packaging/Enterprise-Common-Libraries/...
 │     └── Visibility: All projects and teams across contoso-devops
 │
 ├── Project: [Retail-Banking]
 │     └── Project-Scoped Feed: [Retail-Banking-Components]
 │           └── URL: https://pkgs.dev.azure.com/contoso-devops/Retail-Banking/_packaging/...
 │           └── Visibility: Restricted to members of Retail-Banking
 │
 └── Project: [Commercial-Loans]
       └── Project-Scoped Feed: [Commercial-Loans-Components]
             └── Visibility: Restricted to members of Commercial-Loans

1. Project-Scoped Feeds (Modern Default)

In modern Azure DevOps, newly created feeds default to Project-scoped. The project name is explicitly embedded into the feed's package manager endpoint URL:

https://pkgs.dev.azure.com/{organization}/{project}/_packaging/{feedName}/nuget/v3/index.json
  • Security & Access Boundary: Project-scoped feeds inherit permissions directly from the hosting Azure DevOps project. Users, groups, and build service accounts must have permissions within the project to access the feed.
  • Project Isolation: Feeds are completely isolated from other projects in the same organization. If the project is deleted, the feed and all its packages are deleted.
  • Recommended Use Cases:
    • Microservices or modular applications where package dependencies are strictly internal to that specific product or project team.
    • Regulated systems requiring strict zero-trust segregation between distinct business units or client-specific deliverables.

2. Organization-Scoped Feeds

Organization-scoped feeds are created at the root level of the Azure DevOps organization without being bound to a specific project. The project segment is omitted from the URL:

https://pkgs.dev.azure.com/{organization}/_packaging/{feedName}/nuget/v3/index.json
  • Security & Access Boundary: Permissions are managed at the organization level. Any project within the organization can reference and consume packages from the feed, provided project build service accounts are granted Reader permissions.
  • Recommended Use Cases:
    • Core enterprise shared libraries (e.g., organizational logging frameworks, standardized authentication wrappers, common corporate UI components).
    • Monolithic enterprise architectures where hundreds of repositories across dozens of projects depend on a unified set of internally vetted packages.
CriteriaProject-Scoped FeedOrganization-Scoped Feed
URL StructureContains /{organization}/{project}/_packaging/Contains /{organization}/_packaging/
Default PermissionsInherits from Azure DevOps Project ACLsManaged via Organization Collection ACLs
Cross-Project AccessRequires explicit cross-project build service permissionsReadily accessible to all projects across tenant
Lifecycle DependencyTied to project existenceIndependent of individual projects
AZ-400 Recommended RoleTeam-specific components & microservicesEnterprise-wide shared utility frameworks

Upstream Sources, Outage Resilience & Dependency Confusion Defense

Modern applications rely heavily on external open-source packages from public registries such as nuget.org, npmjs.com, PyPI, and Maven Central. Connecting an Azure Artifacts feed to Upstream Sources provides caching, governance, and supply chain security.

Upstream Caching and Resilience

When an Azure Artifacts feed is configured with an upstream source (such as nuget.org):

  1. A developer or CI build agent requests package Newtonsoft.Json 13.0.3 from the internal Azure Artifacts feed.
  2. Azure Artifacts checks if Newtonsoft.Json 13.0.3 exists in its internal storage:
    • Cache Miss: Azure Artifacts proxies the request to nuget.org, downloads the package, validates its checksum, saves a cached copy into the feed, and returns it to the requester.
    • Cache Hit: If another developer or pipeline requests Newtonsoft.Json 13.0.3 in the future, Azure Artifacts serves the cached copy directly from internal storage.
Upstream Ingestion and Caching Flow:

[Developer / CI Agent]
       │
       ▼ (1. Request: Newtonsoft.Json 13.0.3)
[Azure Artifacts Feed]
       │
       ├── (2. Check Local Cache: MISS)
       │
       ▼ (3. Fetch from Upstream)
[Upstream Source: nuget.org]
       │
       ▼ (4. Stream Package Binary)
[Azure Artifacts Feed] ──► [Saves Immutable Cached Copy to @local]
       │
       ▼ (5. Return Package Binary to Client)
[Developer / CI Agent]

Why Upstream Caching is Critical for CI/CD

  • Resilience Against Public Registry Outages: If npmjs.com or nuget.org suffers an outage, builds do not fail because all previously restored dependencies are served directly from the Azure Artifacts internal cache.
  • Protection Against Upstream Deletions: If an author unpublishes or deletes an open-source library from a public registry, the cached copy remains permanently in the internal Azure Artifacts feed, ensuring future builds succeed.
  • Bandwidth & Latency Optimization: Builds running on Azure Pipelines agents in the same Azure region retrieve cached dependencies over internal Azure datacenter backbones rather than transiting the public internet.

Dependency Confusion (Namespace Collision) Attacks

A Dependency Confusion attack (discovered by security researcher Alex Birsan) targets software delivery pipelines that combine private internal packages with public open-source packages.

Dependency Confusion Vulnerability Mechanism:

1. Enterprise develops internal proprietary package: 'contoso-telemetry-auth' (v1.2.0)
2. Attacker discovers internal package name from leaked configs or build logs
3. Attacker publishes malicious package named 'contoso-telemetry-auth' to public npmjs.org (v99.0.0)
4. Package manager (npm/yarn/pip) queries feed with upstreams enabled:
     Internal Feed offers:  contoso-telemetry-auth v1.2.0
     Public Upstream offers: contoso-telemetry-auth v99.0.0 (HIGHER VERSION)
5. Default package manager logic resolves v99.0.0 from public registry!
6. Malicious code executes inside enterprise CI/CD pipeline or developer machine!

Defenses in Azure Artifacts & Package Managers

To prevent dependency confusion in Azure Artifacts and client package managers, implement three complementary controls:

  1. Package Source Mapping (NuGet): In nuget.config, declare explicit packageSourceMapping patterns. This forces the package manager to query only the internal feed for internal namespaces and only public upstreams for open-source namespaces:
<!-- nuget.config with Package Source Mapping -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="ContosoInternalFeed" value="https://pkgs.dev.azure.com/contoso/Finance/_packaging/CoreFeed/nuget/v3/index.json" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <!-- Internal proprietary libraries are strictly routed to the internal feed -->
    <packageSource key="ContosoInternalFeed">
      <package pattern="Contoso.*" />
      <package pattern="CompanyCore.*" />
    </packageSource>
    <!-- All third-party open-source libraries are routed to nuget.org -->
    <packageSource key="nuget.org">
      <package pattern="*" />
    </packageSource>
  </packageSourceMapping>
</configuration>
  1. Scoped Namespaces (npm): For JavaScript/TypeScript, always prefix proprietary packages with an organizational scope (e.g., @contoso/telemetry-auth). In .npmrc, route that scope exclusively to the private Azure Artifacts feed while leaving default packages routed to public npmjs:
# .npmrc configuration enforcing scoped routing
@contoso:registry=https://pkgs.dev.azure.com/contoso/Finance/_packaging/CoreFeed/npm/registry/
always-auth=true
  1. Upstream Source Internal Package Priority: In Azure Artifacts feed settings, administrators can explicitly configure package source behavior to block external resolution for specific package identifiers once an internal package is published.

Authentication & Credential Provisioning

Private package feeds require secure, authenticated access. In Exam AZ-400, understanding how to configure authentication for both developer workstations and automated CI/CD pipelines is heavily tested.

Feed Authentication Matrix:

[Developer Workstation] ──► Azure Artifacts Credential Provider ──► Entra ID Device Flow / PAT
[CI/CD Build Pipeline]  ──► Packaging Authenticate Tasks ───────► $(System.AccessToken)
[External System / CLI] ──► az artifacts login / Scoped PAT ────► Basic Auth / Bearer Token

1. Developer Workstation Authentication

  • Personal Access Tokens (PATs): Developers can generate a PAT in Azure DevOps user settings. For packaging operations, the PAT must be assigned the Packaging scope:
    • Packaging (Read): Allows querying and downloading packages.
    • Packaging (Read & write): Allows publishing new packages and unlisting.
    • Packaging (Read, write, & manage): Full permissions including feed settings and view management.
  • Azure Artifacts Credential Provider: The recommended modern approach for .NET developers. The credential provider automatically detects when dotnet restore or nuget.exe encounters an authenticated Azure Artifacts feed and launches an interactive Microsoft Entra ID browser prompt or device code login, acquiring short-lived bearer tokens without requiring manual PAT generation in configuration files.
  • Azure CLI az artifacts login: Automatically injects authentication tokens into client configuration files for npm, pip, and twine:
# Authenticate Azure CLI with packaging credentials for npm
az artifacts login --organization https://dev.azure.com/contoso --name CoreFeed --tool npm

2. Azure Pipelines CI/CD Authentication

In automated pipelines, developers must never hardcode personal access tokens or credentials into nuget.config or .npmrc files stored in source repositories. Instead, Azure Pipelines provides dedicated authentication tasks that dynamically inject the pipeline's runtime identity token ($(System.AccessToken)):

  • NuGetAuthenticate@1: Configures authentication for NuGet package restore and push commands.
  • npmAuthenticate@0: Injects credentials into .npmrc files located in the pipeline workspace.
  • TwineAuthenticate@1: Injects authentication variables for Python twine uploads to PyPI feeds.
  • MavenAuthenticate@0: Updates Maven settings.xml with repository credentials.

YAML Pipeline Example: Authenticating and Publishing NuGet and npm Packages

# azure-pipelines.yml: Authenticating feeds and publishing packages
trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  feedName: 'Retail-Banking/CoreComponentsFeed'

steps:
# 1. Checkout source code
- checkout: self

# 2. Authenticate NuGet feed using runtime pipeline token
- task: NuGetAuthenticate@1
  displayName: 'Authenticate with Azure Artifacts NuGet Feed'
  inputs:
    forceReinstallCredentialProvider: false

# 3. Restore and build .NET library
- task: DotNetCoreCLI@2
  displayName: 'Restore NuGet Packages'
  inputs:
    command: 'restore'
    projects: '**/*.csproj'
    feedsToUse: 'select'
    feedRestore: '$(feedName)'

- task: DotNetCoreCLI@2
  displayName: 'Pack NuGet Package'
  inputs:
    command: 'pack'
    packagesToPack: '**/*.csproj'
    versioningScheme: 'off'
    outputDir: '$(Build.ArtifactStagingDirectory)/nuget'

# 4. Push NuGet package to Azure Artifacts
- task: DotNetCoreCLI@2
  displayName: 'Push NuGet Package to Feed'
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/nuget/*.nupkg'
    publishVstsFeed: '$(feedName)'

# 5. Authenticate npm session using .npmrc
- task: npmAuthenticate@0
  displayName: 'Authenticate npm using .npmrc'
  inputs:
    workingFile: '$(System.DefaultWorkingDirectory)/client-app/.npmrc'

# 6. Install and publish npm package
- script: |
    cd client-app
    npm install
    npm publish
  displayName: 'Publish npm Package to Azure Artifacts'
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)

Practical AZ-400 Exam Scenarios & Anti-Patterns

Scenario 1: Preventing Dependency Confusion in Multi-Source Environments

  • Scenario: A corporate security audit reveals that developer machines and CI build agents frequently download packages from public npmjs.org rather than the company's internal private Azure Artifacts feed whenever identical package names exist.
  • AZ-400 Solution: Enforce organizational scoping (@contoso/packagename) for all internal npm packages. In the workspace .npmrc, bind @contoso:registry exclusively to the private feed URL. For .NET projects, commit a repository-level nuget.config with packageSourceMapping explicitly routing Contoso.* patterns to the internal feed and * patterns to nuget.org.

Scenario 2: Storing Multi-Gigabyte Deployment Payloads

  • Scenario: An engineering team deploying automated test rigs requires downloading a 35 GB pre-compiled simulation engine and operating system image during pipeline runs. They attempt to publish it as a NuGet package to Azure Artifacts, but the upload is rejected.
  • AZ-400 Solution: NuGet packages in Azure Artifacts are capped at 500 MiB. The team must publish the 35 GB binary payload as a Universal Package using the Azure CLI (az artifacts universal publish). Universal Packages support arbitrary file collections up to 4 TiB in size.
Loading diagram...
Azure Artifacts Feed Architecture, Upstream Caching, and Ingestion Flow
Test Your Knowledge

An enterprise develops an internal proprietary library named 'contoso-financial-core'. During an automated CI build, the build agent pulls an unexpected version 99.1.0 published on public npmjs.org containing malicious code, rather than the expected internal version 1.4.0 from their Azure Artifacts feed. What security vulnerability occurred, and what is the primary recommended defense to prevent this in Azure Artifacts?

A
B
C
D
Test Your Knowledge

A developer configures an Azure Pipelines YAML build to restore private npm packages from a project-scoped Azure Artifacts feed. The build fails on a Microsoft-hosted agent with an HTTP 401 Unauthorized error during the 'npm install' step. The repository includes a valid .npmrc file referencing the feed registry URL. What step must be added to the pipeline immediately prior to 'npm install' to resolve the authentication failure without exposing secrets?

A
B
C
D