---
title: "Fetch private packages only from your own · Agent Wranglers"
url: https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/dependency-confusion
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Fetch private packages only from your own registry

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Supply chain and setup](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: SEC-103
- Level: Recommended
- Chapter: [Supply chain and setup](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup)
- Rule: Install packages with internal names only from your private registry. The public registry must never be able to answer for them.
- How: Skip this rule when you use no private packages. An attacker can publish a public package with your internal name and a higher version. Some package managers then install it, with all the build's secrets in reach. pip searches every index with no priority, so `--extra-index-url` next to a private index is unsafe. Give every internal npm package a scope, such as `@example-shop/`, and map that scope to the private registry. Register the same scope on the public registry too, so nobody else can claim it. For Python, set `--index-url` to one private mirror that proxies the public index and refuses your internal names from upstream. Install from the lock file as [lock and audit dependencies](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/audit-dependencies) says.
- Check: Search the build files, `pip.conf`, `requirements*.txt` and every `.npmrc` for `extra-index-url`. No match is found. Every internal npm package name starts with a scope. For each scope, `npm config get @example-shop:registry` prints the private registry, and the scope is owned by your organisation on the public registry.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### INI example

```ini
# .npmrc: the scope can only come from the private registry
@example-shop:registry=https://npm.internal.example.com/
```

### INI example 2

```ini
# pip.conf: one index, a private mirror of the public one
[global]
index-url = https://pypi.internal.example.com/simple/
```

## Sources

- [pip install documentation on dependency confusion](https://pip.pypa.io/en/stable/cli/pip_install/)
- [npm Docs on scopes and registries](https://docs.npmjs.com/cli/v11/using-npm/scope)

## Related rules

- [Lock and audit dependencies](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/audit-dependencies) in Security testing
- [Use npm with a lock file for JavaScript packages](https://agentwranglers.se/playbook/stack/languages-and-runtimes/npm) in Software choices

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/dependency-confusion">Agent Wranglers security testing playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Treat a machine that installed a bad package as breached](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/compromised-package-response)
- [Supply chain and setup](https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup)
