Safeguard
Supply Chain•

Did Python fix dependency confusion? What happened to PEP 708

PEP 708 aimed to stop dependency confusion across Python package indexes, but it was rejected. Here is what that means and what to configure instead.

Safeguard Security Team
4 min read

Not at the protocol level. PEP 708 proposed a way for Python package indexes to say which projects they track, so installers could refuse a lookalike from another index. After three years as provisionally accepted, it was rejected because its conditions were never met. Protection still depends on how you configure installs.

What dependency confusion means in Python

The PEP defines it plainly: a user expects package A and gets package B. In Python this almost always comes from using more than one repository, for example a private index plus PyPI. The user expects a name to come from one place, and someone publishes the same name in the other.

The root cause, in the PEP's words, is that there is no globally unique namespace. Each repository is its own namespace. When you ask for a name, the installer has to guess which repository it belongs to.

The PEP cites a real case. A project had an internal package that was meant to come only from its own download site, but that site was designed to be used alongside PyPI, and the name was not claimed on PyPI. An attacker registered it there.

What PEP 708 proposed

It would have extended the Simple Repository API with two ideas:

  • A "tracks" field, so a repository can say a project on it mirrors a project on another repository.
  • "Alternate locations", so a project could declare that its namespace spans several repositories on purpose.

With that metadata an installer could tell a legitimate merge from a surprise. The PEP was provisionally accepted with three conditions: an implementation in PyPI, an implementation in at least one other repository, and an opt-in implementation in pip. Its current status page says it was rejected because those conditions were never met.

What this means for your builds

Nothing changed in how pip merges indexes. If you configure more than one index, pip considers all of them. So the controls are yours:

ControlWhat it doesCost
One index only, with a proxy that holds internal namesRemoves the second namespaceNeeds a proxy you run
Claim your internal names on the public indexStops a third party taking themPublic placeholder projects
Hash-checking modeRefuses any file whose hash you did not recordHash upkeep
Explicit per-package sourceTells the installer where a name must come fromDepends on your tool

The PEP itself lists "rely only on hash checking" as an idea it did not choose as the default fix, because users must opt in and manage hashes, and build-time dependencies are harder to cover. That is a fair description of the trade-off, and it is also why hashes work well as a final gate in a pipeline you control. See pip require-hashes as the final gate and why extra-index-url is unsafe for private packages.

A short action list

  1. Run pip config list and read every index setting in effect, including environment variables.
  2. Remove any second index that exists only for convenience.
  3. For private package names, register the name publicly or serve them through a single proxy.
  4. Add hashes for the production install path.
  5. Alert when a name you consider internal appears in a public index.

Safeguard's dependency scanning and SBOM generation give you an inventory of the Python packages in a project, which makes step 5 easier to check against. You can try a free scan at gold.safeguard.sh/scan.

Try it yourself

Click through it at your own pace, or open it full screen. Look for package names you do not recognise as internal or public.

Quick check

Is PEP 708 in pip today?

No. The PEP was rejected, so there is no standard "tracks" metadata for pip to enforce.

Does a private index alone prevent dependency confusion?

Only if it is the sole index. If PyPI is also configured, the installer can still pick up a public package with the same name.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.