Skip to content

fix(arborist): recognize registry-mediated tarballs - #9921

Open
martinrrm wants to merge 4 commits into
latestfrom
martinrrm/bug-npm-install-fails-with-eallowremote-on-certa
Open

fix(arborist): recognize registry-mediated tarballs#9921
martinrrm wants to merge 4 commits into
latestfrom
martinrrm/bug-npm-install-fails-with-eallowremote-on-certa

Conversation

@martinrrm

Copy link
Copy Markdown
Contributor

Summary

  • recognize registry-resolved tarballs served from same-origin sibling paths when the exact URL is advertised by registry metadata
  • derive registry identity from valid dependency edges so npm: aliases use the target package's scope, registry, and credentials
  • preserve existing allow-remote policy behavior and carry trusted identity through the linked install strategy
  • document the registry-path and metadata-verification behavior

Problem

During reification, Arborist passes registry tarballs to pacote as name@URL. npm-package-arg parses that temporary spec as a remote dependency, so Arborist grants a narrow allowRemote: 'all' exemption after confirming the URL came from a configured registry.

The existing confirmation had two blind spots:

  1. It accepted only tarball paths beneath the configured registry path. Private registries such as Artifactory and GitHub Packages may advertise tarballs from a sibling path on the same origin.
  2. It selected the registry using the installed dependency slot. For an unscoped alias such as hoek: npm:@npm/hoek@6.1.4, that loses the target scope and selects the default registry instead of the registry configured for @npm.

Both cases incorrectly reached pacote's remote-fetch policy and failed with EALLOWREMOTE under npm 12's default allow-remote=none.

Implementation

Registry tarballs under the configured registry path retain the existing fast-path exemption. For a same-origin URL outside that path, Arborist now fetches the exact package-version manifest and grants the exemption only when its advertised tarball URL matches the effective lockfile URL. Registry-host replacement is applied consistently, URL fragments are ignored because they are not sent over HTTP, and path and query components must still match exactly.

The package identity used for this verification is derived from valid inbound dependency specs rather than package or lockfile metadata. npm: aliases are unwrapped to their target package names, and all valid inbound registry edges must agree. This identity is also used for the temporary pacote extraction spec so scoped registry authentication follows the alias target while the package remains installed in its alias location. Linked installations explicitly carry the trusted identity to their synthetic store nodes.

Verification fails closed: metadata errors, mismatches, conflicting dependency identities, cross-origin URLs, and non-registry dependencies continue through the configured allow-remote policy and remain blocked when that policy is none. Arborist also skips metadata verification when remote fetching is already permitted by implicit or explicit all, or for a root dependency under root.

Tests

  • unit coverage for ordinary registry dependencies, aliases, invalid and conflicting edges, non-registry specs, and linked-node identity transfer
  • reify regressions for verified sibling-path tarballs, metadata mismatches and failures, lockfile-controlled package names, target-scoped credentials, locked transitive aliases, URL fragments, policy modes, and the linked strategy
  • CLI npm ci regression proving an unadvertised same-origin sibling-path tarball remains blocked
  • configuration definition coverage and linting for all changed files

Fixes #9796

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@martinrrm
martinrrm requested review from a team as code owners August 27, 2026 17:44
martinrrm and others added 3 commits August 27, 2026 18:01
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
})

t.test('allowRemote=none blocks same-origin tarball outside registry path', async t => {
t.test('allowRemote=none allows registry-advertised tarball outside registry path', async t => {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test for the main change to fix #9796.

If a registry is serving tarballs from a different path than the actual registry metadata (such as https://registry.example.com/blob/package.tgz, while the registry is https://registry.example.com/npm) this results in EALLOWREMOTE attempting to install anything from it.

await t.resolves(arb.reify(), 'registry-advertised sibling-path tarball is allowed')
})

t.test('allowRemote=none verifies against dependency identity, not lockfile name', async t => {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is also important; we are now getting the packument of the package (so a new metadata request if the tarball URL is different from the registry) and validating that the advertised URL are the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] npm install fails with EALLOWREMOTE on certain private registry configurations

1 participant