{"slug": "php-composer-2-11-ships-dependency-cooldowns", "title": "PHP Composer 2.11 ships dependency cooldowns", "summary": "Composer 2.11.0 ships a new cooldown dependency policy that withholds newly published package versions for a configurable period before Composer will install them, addressing the window between a malicious release and its flagging on Packagist.org. The policy is configured under config.policy, is not enabled by default, and accepts a period string such as \"1 day\" or \"6 hours\" (units second, minute, hour, day or week) or an integer number of seconds, also settable via the COMPOSER_POLICY_COOLDOWN_PERIOD environment variable. The release also includes several security fixes, removes the source fallback behavior deprecated in 2.10, lets custom policies block during composer install, and brings dependency resolution performance improvements; Private Packagist already supports cooldown periods across all projects.", "body_md": "[composer](https://blog.packagist.com/tag/composer/)\n\n# Composer 2.11\n\nWe are pleased to announce the release of [Composer 2.11.0](https://github.com/composer/composer/releases/tag/2.11.0). The highlight of this release is the new cooldown dependency policy, which withholds newly published package versions for a configurable period of time before Composer will install them. Composer 2.11 also ships several security fixes, removes the source fallback behavior deprecated in 2.10, lets custom policies block during `composer install`, and brings noticeable dependency resolution performance improvements.\n\n[Private Packagist](https://packagist.com) already supports cooldown periods today. Private Packagist organizations can enforce a cooldown period across all their projects, independently of the Composer version their developers, AI agents, and CI systems use.\n\n## **Cooldown periods: withholding new releases**\n\nMost malicious releases we have seen on [Packagist.org](https://packagist.org) in the past months were published by attackers who briefly gained control of a legitimate package, for example through a compromised GitHub account. The malware policy introduced in Composer 2.10 blocks such versions once they have been flagged, but there is always a window between publication and flagging.\n\nA cooldown period narrows or closes that window, it's sometimes also called a minimum release age. Automated malware scanners can flag the first problems within minutes of a release, so even a cooldown period of a single hour gives automatic detection a chance to act before a new version becomes a candidate for your `composer update`. Reports that need manual review take longer, and a cooldown period of a few hours up to a day makes it more likely that these are caught as well. A cooldown period cannot guarantee that a malicious release is flagged in time, but every hour of delay increases the chance.\n\nThe cooldown policy is configured like the other dependency policies under `config.policy` and is not enabled by default. To withhold all versions published within the last day:\n\n```\n{\n    \"config\": {\n        \"policy\": {\n            \"cooldown\": {\n                \"period\": \"1 day\"\n            }\n        }\n    }\n}\n```\n\nThe `period` takes a string like `\"6 hours\"` with the units `second`, `minute`, `hour`, `day` or `week`, or an integer number of seconds. You can also set it in your global Composer configuration, or through the `COMPOSER_POLICY_COOLDOWN_PERIOD` environment variable, for example in CI.\n\nThe cooldown policy applies whenever Composer resolves dependencies, so during `update` and `require`. `composer install` continues to install exactly what is in your `composer.lock`. `require`, `init` and `create-project` skip withheld versions when choosing a version, and `outdated` and `show --latest` report the newest version the policy allows while pointing out releases still in their cooldown period. Dev versions like `dev-main` representing moving targets and platform packages are never withheld.\n\nIn a partial update like `composer update vendor/package`, locked packages which are not being updated are left alone. A full `composer update` re-evaluates every package, so if your lock file already contains a version still in its cooldown period, Composer may replace it with an older version.\n\n## **Security fixes and choosing a cooldown period**\n\nA cooldown period applies to every new version, including releases that fix security vulnerabilities. With a cooldown period of one day, Composer will not install a security fix during the first day after its release unless you tell it to.\n\nComposer cannot safely let security fixes skip the cooldown policy automatically. An attacker who gains access to a package's repository has the same permissions as the maintainer. They can publish a security advisory for the package themselves, or release a malicious version after a legitimate advisory was published. Any rule that exempts releases based on advisory data would give attackers a way around the cooldown period.\n\nInstead, you decide when a release should skip the cooldown policy. To install a fix right away, use the new `--no-cooldown` option on `update`, `require`, `remove` or `create-project`. It only skips the cooldown policy. Blocking of versions with security advisories, malware and your other policies stays active:\n\n```\ncomposer update --no-cooldown vendor/package\n```\n\nPackages you always want to receive immediately, such as your own, can be exempted permanently with the ignore option, which supports reasons, version constraints and wildcards like the other dependency policies:\n\n```\n\"cooldown\": {\n    \"period\": \"1 day\",\n    \"ignore\": {\n        \"mycompany/*\": \"We trust the code in our own packages\"\n    }\n}\n```\n\nManually updating and bypassing the cooldown period for security fixes only works if you notice the vulnerability. The longer your cooldown period, the longer every fix for a vulnerability you are not actively tracking is delayed. A period of a few hours to a day covers most of the time automatic and manual detection need, while keeping the delay for security fixes short. Tools like [Private Packagist Security Monitoring](https://blog.packagist.com/security-monitoring/) can notify you by email, Slack, Microsoft Teams or webhook when a security advisory affects a dependency in one of your projects, so you can apply the fix right away.\n\n## **Why weren't cooldown dependency policies shipped in Composer 2.10 already?**\n\nComposer 2.10 introduced dependency policies, but Composer metadata did not yet contain a timestamp a cooldown policy could rely on. The only date was the `time` field, which Packagist.org derives from the commit date of the tag or takes directly from the package's `composer.json`. Both are controlled by whoever publishes the release. An attacker can backdate a malicious release by a few weeks, and a cooldown period based on `time` would let it through immediately. Tools built on the `time` field to delay updates could not protect against a compromised release, because the attacker controls the date these tools check.\n\nPackagist.org now includes a `published-time` for every version, based on when Packagist.org itself first made the version available ([composer/packagist#1765](https://github.com/composer/packagist/pull/1765)).\n\nIf another Composer repository does not report a `published-time` for a version, that Composer needs to consider, the command fails and names the affected package, so a missing timestamp never silently disables the cooldown. For repositories you trust, you can set `require-published-time` to `false` to fall back to the `time` field. VCS, path and artifact repositories only have the `time` field.\n\nThe cooldown policy was implemented in [#12692](https://github.com/composer/composer/pull/12692), [#13098](https://github.com/composer/composer/pull/13098), [#13099](https://github.com/composer/composer/pull/13099), [#13100](https://github.com/composer/composer/pull/13100), [#13102](https://github.com/composer/composer/pull/13102) and [#13153](https://github.com/composer/composer/pull/13153). See the [cooldown configuration documentation](https://getcomposer.org/doc/06-config.md#cooldown) for all details.\n\n## **Cooldown periods in Private Packagist**\n\nPrivate Packagist already supports the cooldown policy and provides a publication time for every version it serves, including mirrored open-source packages and your private packages. Like Packagist.org, it sets the publication time itself when it first imports a version, and if the code of a version changes, for example through a force-pushed tag, the cooldown starts again.\n\nOrganization admins can also set a cooldown dependency policy for the entire organization under Settings > Security. Private Packagist then holds back recently published versions for every project using the organization's Composer repository, regardless of the project's `composer.json` and of the Composer version in use, so projects that have not updated to Composer 2.11 yet are protected as well. Packages that should be available immediately can be added to the *Packages without cooldown* list. Read the [cooldown dependency policy documentation](https://packagist.com/docs/cooldown-dependency-policy) for details.\n\n## **Security fixes**\n\nComposer 2.11 includes the following security fixes:\n\n- Package names in `vendor/composer/installed.json` can not escape the vendor directory during install and reinstall anymore.[GHSA-c968-33g3-wh7p](https://github.com/composer/composer/security/advisories/GHSA-c968-33g3-wh7p)\n- HTTP headers configured inline in a repository config, such as API tokens, are no longer being written into `composer.lock` /`installed.json` .[GHSA-fm2w-xgf2-f9fh](https://github.com/composer/composer/security/advisories/GHSA-fm2w-xgf2-f9fh)\n- TLS connections presenting the distrusted, compromised eMudhra intermediate certificates are now rejected, even if the system CA store trusts their roots. [#13146](https://github.com/composer/composer/pull/13146)\n- Bin proxies no longer embed package-controlled bin paths and shebangs unescaped, and bin paths containing shell metacharacters are rejected. [#13056](https://github.com/composer/composer/pull/13056)\n- `secure-http` now also catches insecure URLs which are not strictly valid or use git's`<transport>::<address>` syntax.[#13144](https://github.com/composer/composer/pull/13144)\n- Repository options like custom HTTP headers are no longer sent to dist URLs on other hosts whose name merely starts with the same string as the repository host. [#13142](https://github.com/composer/composer/pull/13142)\n\n## **Source fallback removed**\n\nComposer 2.10 deprecated the fallback to a source checkout when a dist download fails, and added a temporary `source-fallback` config option to re-enable the old behavior. As announced, Composer 2.11 removes this option, and dist installs no longer fall back to source. [#13050](https://github.com/composer/composer/pull/13050)\n\nYou can still install packages from source explicitly (including per-vendor) using the [`preferred-install`](https://getcomposer.org/doc/06-config.md#preferred-install) config option or the `--prefer-source` command line option.\n\n## **Custom policies can block during install**\n\nCustom dependency policies, such as an internally maintained list of disallowed package versions, can now use the `block-scope` option already known from the malware policy. Setting it to all blocks matching versions during `composer install` as well, so a version added to your list after a lock file was created will fail the next install. [#12990](https://github.com/composer/composer/pull/12990)\n\n## **Lock file warning with policy config**\n\nComposer now marks the lock file as outdated when the `policy` config changes, fixing an oversight in Composer 2.10 that ignored it. If your project defines a `policy` config, you will see a lock file warning after upgrading to 2.11 until you update the lock file. [#13149](https://github.com/composer/composer/pull/13149)\n\n## **Other notable improvements**\n\n- **Faster dependency resolution** : Dependency resolution is faster and uses less memory.[#13071](https://github.com/composer/composer/pull/13071) ,[#13072](https://github.com/composer/composer/pull/13072) ,[#13103](https://github.com/composer/composer/pull/13103) ,[#13123](https://github.com/composer/composer/pull/13123) ,[#13124](https://github.com/composer/composer/pull/13124) ,[#13132](https://github.com/composer/composer/pull/13132) ,[#13174](https://github.com/composer/composer/pull/13174)\n- **No more HTTP/3 delay** : Composer no longer requests HTTP/3, which added a delay to every new connection with recent curl versions.[#13096](https://github.com/composer/composer/pull/13096)\n- **Parallel outdated** :`composer outdated` and`composer show --latest` load package metadata in parallel.[#13113](https://github.com/composer/composer/pull/13113)\n- **Audit direct dependencies only** : The new`--direct (-D)` option on`composer audit` only audits direct dependencies.[#13121](https://github.com/composer/composer/pull/13121)\n- **Terminal progress reporting** : Composer reports progress and status to supporting terminals via[OSC 7501](https://www.superlogical.com/rex/docs/build/program-status) and[OSC 9](https://vtdn.dev/docs/osc/osc9/) escape sequences, configurable with`COMPOSER_TERMINAL_STATUS` .[#13117](https://github.com/composer/composer/pull/13117)\n- **Rate limit handling** : Composer waits and retries when a repository responds with a 429 status and a`Retry-After` header.[#13082](https://github.com/composer/composer/pull/13082)\n- **Bitbucket SSH hostname** : Support for Bitbucket Cloud's new`ssh.bitbucket.org` SSH hostname, which is now also used for the SSH fallback.[#13152](https://github.com/composer/composer/pull/13152)\n- **Restricting VCS branches** : The new`only-branches` option on VCS repositories restricts which branches are loaded.[#13086](https://github.com/composer/composer/pull/13086)\n- **strict-psr-autoloader config** : The`--strict-psr-autoloader` flag is now also available as a config option.[#12893](https://github.com/composer/composer/pull/12893)\n- **Clearer conflict errors** : Dependency conflict errors explain versions blocked by security advisories more clearly.[#13108](https://github.com/composer/composer/pull/13108) ,[#13075](https://github.com/composer/composer/pull/13075)\n- **Lock file merge conflicts** :`composer install` now fails when composer.lock has a content-hash merge conflict.[#13105](https://github.com/composer/composer/pull/13105)\n\nFind out about other features and bugfixes in the [complete changelog](https://github.com/composer/composer/releases/tag/2.11.0).\n\n## **Upgrading**\n\nRun `composer self-update` to upgrade to Composer 2.11. If you run into any problems, please report them on the [Composer issue tracker](https://github.com/composer/composer/issues).", "url": "https://wpnews.pro/news/php-composer-2-11-ships-dependency-cooldowns", "canonical_source": "https://blog.packagist.com/composer-2-11-release/", "published_at": "2026-10-30 09:54:36+00:00", "updated_at": "2026-10-30 10:16:54.312307+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Composer", "Composer 2.11.0", "Packagist.org", "Private Packagist"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/php-composer-2-11-ships-dependency-cooldowns", "markdown": "https://wpnews.pro/news/php-composer-2-11-ships-dependency-cooldowns.md", "text": "https://wpnews.pro/news/php-composer-2-11-ships-dependency-cooldowns.txt", "jsonld": "https://wpnews.pro/news/php-composer-2-11-ships-dependency-cooldowns.jsonld"}}