Enforce a Safe Composer Version Across Your Organization

Enforce a Safe Composer Version Across Your Organization

This is the next post in our supply chain security series, following the supply chain security update, the Composer 2.10 release, closing Composer's download fallback paths, and blocking malware downloads for every Composer version.

While the protections we have shipped try their best to cover older Composer versions too, a current Composer fixes the same problems more cleanly: Dependency policies reject flagged versions during resolution with an actionable error without a network trip, rather than failing with a HTTP 410 on download, and source code download fallback is off by default. Known Composer CVEs are only fixed in current releases.

In a large organization with hundreds of developers, dozens of CI images of varying ages, and an increasing number of AI coding agents managing dependencies, "tell everyone to upgrade and hope they follow through" does not scale. Private Packagist customers can now enforce which Composer client versions are allowed to talk to their Composer repository.

The Composer CLI is part of the supply chain

The packages a developer installs are not the only thing that can go wrong. The Composer client itself sits in a privileged position: It parses metadata from third-party repositories, downloads archives, and runs plugin code during install. Composer has shipped fixes for several vulnerabilities over the years that let a malicious or compromised repository attack the client itself, most recently a pair of command injection issues involving Perforce VCS handling.

Beyond known CVEs, older Composer versions predate the protections shipped in this series:

  • The unified dependency policy framework (malware, advisories, abandoned packages) only exists from Composer 2.10 onwards.
  • The source fallback that lets Composer silently clone from a third-party repository when a dist download fails was only deprecated and disabled by default in 2.10.
  • The Aikido-powered malware feed Packagist.org consumes only takes effect at install time on 2.10 clients.

Repository-side protections like the ones we have shipped in Private Packagist work across every Composer version, but the strongest combination is repository-side protections together with a current client. Keeping every developer, every CI runner, and every AI coding agent on a recent Composer is still the best defense.

How it works

A new Composer client version restriction section in your organization's Settings > Security page offers three options:

  • All Composer versions allowed: The old behavior and default for existing organizations.
  • Composer 2.2.* (LTS) and 2.10.* (latest): The recommended setting for most teams. Keeps the LTS line available for environments that have not yet migrated to a more recent PHP version.
  • Composer 2.10.* (latest only): For teams committed to staying on the current release line and using modern PHP.

When a restriction is active, Private Packagist refuses every request from an outdated Composer client, whether it is fetching metadata or downloading an archive. The client receives a clear message back through Composer's normal error path:

$ composer update
Warning from repo.packagist.com:
======================

COMPOSER VERSION NOT ALLOWED
Your organization restricts the allowed Composer client versions. Please
upgrade to one of: 2.2.*, 2.10.*. See https://getcomposer.org/download/ for
installation instructions.

======================

The instruction shows up in the developer's terminal at the moment they hit the problem, rather than in internal documentation they would have to find first. The same message appears for human developers, AI agents and in CI logs.

Before you enable it

The Composer 2.10 release includes a small number of intentional backward-incompatible changes, most notably the removal of automatic source fallback on dist download failure. Workflows that quietly relied on the old behavior will need to be updated to Composer 2.10 before you break them with this new setting. An example are projects that habitually install from source in CI because they do not set credentials for Private Packagist there, a very inefficient and dangerous practice. Reviewing the Composer 2.10 release post before turning the restriction on is worth the few minutes.

It’s also worth checking on AI agents in your environment. Many use whatever Composer version was current when their container or template was built, and they often have no path to upgrade themselves. Enforcing a current version forces this conversation to come up explicitly, rather than letting an agent silently install malware because it was using a Composer version that predates these protections..

Defaults and scope

Existing organizations keep allowing all Composer versions by default. Nothing changes until you turn the restriction on. New organizations start on the recommended setting: Composer 2.2.* (LTS) and 2.10.* (latest), so they are protected by default.

The setting lives on the organization and is automatically applied to every suborganization. Per-suborganization overrides are on the roadmap; get in touch if that scenario applies to you.

What's next

This is the first iteration, and the current options are deliberately coarse. A future update will make these version sets dynamic, automatically tracking the current latest LTS and latest Composer release lines and excluding any specific bugfix releases with known security vulnerabilities. Finer-grained version selection, specific version ranges, exact bugfix releases, and per-suborganization overrides are on the same roadmap.

The feature is available on Private Packagist Cloud today. Self-Hosted support will follow.