The last months, and even more so the last weeks, saw an increasing amount of software supply chain attacks targeting open-source ecosystems. A handful of these have hit the PHP ecosystem too, via taken-over GitHub accounts and stolen access tokens that let attackers publish new tags on packages they had no legitimate access to. Most notably laravel-lang on May 22 and intercom/intercom-php on April 30th.
This post is an update on where Composer and Packagist.org's supply chain security work stands right now: what's already in place, what ships in the next few weeks, and the longer-running projects we're working through. We've been focused on this area for close to a year, and there's enough to cover that it's worth pulling it together in one place.
If you maintain any package on Packagist.org and don't have MFA enabled, please enable it now. We will begin to publish package maintainer MFA status to package transparency logs and it will be visible on profiles. See the MFA section below for details.
In place today:
Shipping this week:
Coming in the next weeks and months:
Longer-term direction:
The rest of the post goes through each of these in detail.
In March 2026, Packagist.org started importing malware detection results from Aikido (see composer/packagist#1681). When a version is flagged, the warning shows up prominently in the Packagist.org UI and is included in package metadata served to Composer. Aikido flagged the malicious versions in each of the recent incidents.
The team operating Packagist.org has been responding to each incident within minutes of detection, pulling affected packages or versions before they can be installed at scale. Manual intervention is not the type of rapid response we want this process to depend on long-term, though, and most of what follows is about replacing reaction with prevention.
Packagist.org has a public transparency log (login required) that records security-relevant events across the repository. It covers things like package ownership changes, maintainer additions and removals, user changes, and changes to version references.
The log is a tool for investigative use cases and continuous monitoring for risks. If you're interested in building tools or integrations on top of it, get in touch at contact@packagist.org or GitHub issues and help shape the API for this log.
Work on the transparency log was funded by the German Sovereign Tech Agency and it has been directly useful in handling the recent attacks. One of the key elements of nearly every recent supply chain attack on Packagist involved attackers modifying existing git tags after the fact. The transparency log accurately recorded each of these modifications, which let us identify exactly what had been manipulated and reconstruct precise timelines of each attack.
Why does this kind of record matter in general?
We plan to keep expanding what the log captures. The next additions are on the account security side.
We already collect MFA-related events internally (enabling, disabling, recovery code usage, and similar). In about six months, these events will start appearing publicly in the transparency log alongside the existing entries. This ties directly into the "account security review" point above: it lets anyone see whether the maintainers of a package are actively keeping their accounts secure.
Once that is in place, we will go a step further and surface MFA status on maintainer profiles, so it is visible whether the people behind a package have MFA enabled. We expect this to nudge the ecosystem toward stronger account security, and it is one more reason to enable MFA on your account now if you haven't already.
Attackers already prioritize targets by download counts and dependency graphs, both of which are public information, MFA status doesn't change which packages are worth attacking, only how feasible an attack is once a target is chosen. Meanwhile the consumers of those packages have a legitimate interest in knowing the security posture of what they depend on, and today they have no way to see it. Making MFA status visible turns it from a private hygiene question into a property of the package that downstream users can see, ask about, and factor into their decisions. We expect this shift will get MFA adopted across the ecosystem faster than any amount of individual nudging.
Beyond that, we intend to implement FIDO2 support and eventually require MFA for all Packagist.org accounts. There is no fixed date yet, but the direction is set, and we want to give maintainers enough lead time to enable it without disruption.
A practical note for organizations using shared company user accounts and struggling with MFA: Please move to individual accounts per maintainer ahead of these changes. Organizational Package Ownership, which we are actively building, is designed to make that transition straightforward. You will be able to have an organization own packages and vendor prefixes, while individual users act on behalf of the organization, without the security and accountability problems of a shared login.
Composer 2.10 is shipping later this week, with a dedicated release announcement to follow on this blog. This section is a short summary of the parts most relevant to supply chain security.
The headline change is the introduction of dependency policies, a single framework for configuring how Composer treats vulnerability advisories, abandoned packages, and now packages flagged as malware. The framework matters because it gives us a clean place to add more policies later, rather than bolting each new check on as a one-off feature.
The first follow-up that we have already designed is a minimum release age policy (also known as cooldown period): refuse to install a version that was published less than N hours or days ago. This is one of the more effective defenses against the recent class of attacks, because malicious versions are typically pulled or detected within hours of publication. The policy is currently blocked by prerequisite work on the Packagist.org side. We need release metadata to be reliably immutable before we can safely treat "publication time" as a security input. More on that below.
Composer 2.10 will disable and deprecate source fallbacks for package downloads, to be removed entirely in 2.11. Previously, failing stable dist artifact downloads would automatically fall back to the underlying source repository. This behavior could lead to unexpected behaviors when the repository intentionally removes or blocks specific versions available on the underlying source repository.
Operating Packagist.org under active attack has surfaced some sharp edges in our internal tools. The work currently in progress includes:
None of this is glamorous, but a lot of incident response time today is spent working around tooling gaps.
This is the larger change, and the one we have been working through the details on for a while. The first piece is imminent: stable versions on Packagist.org will become immutable as part of a deploy scheduled for this week, see https://github.com/composer/packagist/pull/1742.
Today, the transparency log already records when a version's source reference changes (you can filter the log by version_reference_changed to see this). That's useful for detection. But detection after the fact is a weak help compared to not allowing the change in the first place.
Once the deploy goes out, and a package publishes a non-dev version, Packagist.org will no longer silently rewrite it in response to upstream re-tagging or force-pushed annotated tags in Git/VCS repositories. Tag changes upstream are detected and rejected, and the maintainers of the affected package get an email notification. Branch-based dev versions continue to behave as they do today, since their whole purpose is to track a moving reference.
As a side note, we have been recommending to never retag a version for years. Even when an existing version turns out to have a problem, the right fix is to release a new version, not to overwrite an existing one. Immutability on our side enforces that recommendation.
It is worth spelling out why this matters, because the consequences of re-tagging are easy to underestimate:
composer update, composer require, or composer update foo -W, Composer refreshes registry metadata and rewrites the affected lock entries, even if a version is not updated, but was re-tagged in the meantime.Alongside the server-side change, we are also auditing Composer's behavior in installation scenarios where an attacker has modified git tags before repository-side immutability is in place. The goal is to make Composer's behavior in those edge cases more predictable. You’ll either get the originally published version, or a clear error, but never a silently-different version.
A lot of recent attacks come down to a single maintainer's account being compromised. Separately from repository-wide MFA enforcement, we want to give organizations and the maintainers of widely-used packages tools to harden that boundary:
These controls won't help every package, but they meaningfully raise the cost of compromising the ones that matter most to the ecosystem.
Further out, we want Packagist.org to begin hosting immutable build artifacts directly, alongside SLSA build provenance and Sigstore attestations, published through Trusted Publishing / OIDC, with verification on the Composer client side. The dependency policy framework we are shipping in Composer 2.10 is already set up to eventually let organizations configure, at fine granularity, which kinds of artifacts they trust based on their build provenance.
There are two pieces of external work we are aiming this at:
This project is a long-term direction and a significant amount of engineering on both the repository and the client side. We want to get the ergonomics right before pushing it on the ecosystem. But we’re convinced, it is where things need to end up.
This post is the opening of a short series. Over the next days we will follow up with:
The Composer 2.10 release announcement, with a detailed walkthrough of how malware handling, the dependency policy framework, and the dist/source fallback changes actually behave in practice.
A set of posts detailing Composer behaviors in the context of supply chain security and presenting new supply chain security features in Private Packagist. These features are aimed at organizations that want to enforce supply chain decisions consistently across all their projects and developers, rather than leaving each project to set its own policy. Some of what we are rolling out:
These only really make sense in a private repository where one organization controls the policy, which is why they are landing in Private Packagist rather than on Packagist.org.
This extensive amount of work requires financing. In addition to Private Packagist which funds the majority of our work, we would like to thank the Sovereign Tech Agency and Aikido for financing many work hours that went into these projects so far.
Financial contributions help us pay our staff for operating Packagist.org and supporting its users, e.g. reacting to supply chain attacks in the middle of the night, and maintaining and building these new supply chain security features for Composer. If your business is interested in joining this new sponsorship program (3 tiers from €2,500/month), please reach out to sponsoring@packagist.org for details and to be included in our launch announcement and new sponsorship website in June!
The underlying ideas in this post: public audit logs, mandatory MFA, immutable releases, build provenance, attestations aren't new, and we are not the first ecosystem to work through them. PyPI made 2FA mandatory for all publishers in January 2024 and now supports Sigstore-signed attestations via PEP 740. npm shipped SLSA-compliant Sigstore-signed provenance in 2023 and added staged publishing in May 2026. Composer and Packagist have caught up at different speeds in different places: Ahead on some, e.g. the Packagist.org transparency log already captured the kinds of attacks the rest of this post is about, and Composer's model of distributing packages straight from git tags keeps the artifact directly tied to its source rather than to a separately-uploaded build. But behind on others, mandatory MFA most visibly. The work highlighted in this post closes the remaining gaps in a foundation that ties what you install directly to the source it came from, unlike most package registries.