You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Version-list filtering for all remaining ecosystems #132
Ten handlers (npm, Composer, PyPI, Cargo, pub, NuGet, Hex, RubyGems, Conda, Helm) can filter versions out of a package's metadata today because they already parse it for cooldown. The other twelve can't:
Maven (no per-version publish time; denylist/advisory filtering only)
OCI containers (no tag push time; denylist/advisory filtering only)
CRAN
Debian
RPM
Conan
Julia
APK
Gradle (build cache has no versions; Gradle dependency resolution goes through Maven)
Homebrew
Swift
For cooldown and advisory blocking (#130) to apply everywhere, each of these needs its version-list response parsed enough to drop entries before serving. Some are a few lines (Go's /@v/list, OCI /tags/list), some need index-file parsing (CRAN, Debian, RPM), and a couple are structurally awkward (Julia is content-addressed, Conan keys on user/channel).
This issue tracks bringing all of them up to parity. The per-ecosystem approach can be worked out as each one is picked up.
Related: #127. Per-handler PRs on the current proxy.Cooldown.IsAllowed hook are welcome without waiting for it.
Hi! Thanks for tracking this. Is there a rough plan or priority order for these ecosystems, and is #127 still a blocker, or can individual handlers be picked up before it lands?
For us, cooldown on Go, Maven/Gradle and OCI containers matters most (supply-chain protection for CI). Since Go /@v/list and OCI /tags/list are noted as a few lines, would you accept a PR for them on top of the current cooldown hook, or would you rather wait for the Filter interface from #127?
Also, the README table doesn't show cooldown for Helm, but this issue lists Helm among the handlers that already filter versions. Is the README out of date?
#127 isn't a hard blocker. The ten handlers that filter today all call proxy.Cooldown.IsAllowed directly, so adding more on the same hook is fine and they'll move to the Filter interface together whenever #127 lands.
Go /@v/list: a PR would be welcome. The list itself is bare version strings, so the handler will need to fetch (and cache) each version's .info for the Time field before deciding whether to drop it. That's more than a few lines but still contained.
OCI /tags/list: happy to take a PR, but the distribution API doesn't expose a publish time for a tag, and the config history timestamps are build time, not registry push time. Without a timestamp cooldown has nothing to measure against. If you have a workable source for tag push time I'm interested, otherwise OCI probably stays on the "no cooldown" list and the per-version denylist (#360) is the tool for blocking a specific image.
Maven/Gradle: maven-metadata.xml only has a single <lastUpdated> for the whole artifact, not per-version timestamps, so same problem as OCI. Gradle build cache has no versions.
For Maven, there's a per-version time the proxy could use: the Last-Modified header of each version's .pom. On Central it matches the deploy time, e.g. guava-33.0.0-jre.pom returns Mon, 18 Dec 2023 20:49:31 GMT, the same time search.maven.org reports. Renovate's minimumReleaseAge uses this header for Maven, Dependabot falls back to it, and Cloudsmith's cooldown stores it as the publish time.
Roughly:
Read the POM's Last-Modified once per version and store it in versions.published_at, as npm does now. Release files don't change.
Use only the header of a 2xx response.
Remove versions in cooldown from maven-metadata.xml, recompute <latest>/<release> and its checksum files, and refuse the version's files.
To keep requests down, only check versions that could still be in cooldown. If <lastUpdated> is older than the window, no version can be new, so nothing needs checking. Otherwise, walk the list from the newest end and stop at the first version that is old enough. That matters because Central now answers bursts with long 429 blocks.
Caveats: a Nexus or Artifactory upstream may report when it cached the file rather than when it was published, and SNAPSHOTs are left out.
Thanks for Go. Yes to Maven along those lines. packages.ecosyste.ms uses the .pomLast-Modified for Maven publish times too (maven.rb). One more case for the caveat besides Nexus/Artifactory: on Google's Central mirror Last-Modified is when the file reached the bucket, and the upload time is in x-goog-meta-last-modified instead, missing for files from its 2019 bulk import. Please put that in the docs next to the Go caveat.
Activity
Markeli commentedon Oct 1, 2026
Hi! Thanks for tracking this. Is there a rough plan or priority order for these ecosystems, and is #127 still a blocker, or can individual handlers be picked up before it lands?
For us, cooldown on Go, Maven/Gradle and OCI containers matters most (supply-chain protection for CI). Since Go /@v/list and OCI /tags/list are noted as a few lines, would you accept a PR for them on top of the current cooldown hook, or would you rather wait for the Filter interface from #127?
Also, the README table doesn't show cooldown for Helm, but this issue lists Helm among the handlers that already filter versions. Is the README out of date?
andrew commentedon Oct 8, 2026
Thanks for the nudge.
#127 isn't a hard blocker. The ten handlers that filter today all call
proxy.Cooldown.IsAlloweddirectly, so adding more on the same hook is fine and they'll move to the Filter interface together whenever #127 lands.Go
/@v/list: a PR would be welcome. The list itself is bare version strings, so the handler will need to fetch (and cache) each version's.infofor theTimefield before deciding whether to drop it. That's more than a few lines but still contained.OCI
/tags/list: happy to take a PR, but the distribution API doesn't expose a publish time for a tag, and the confighistorytimestamps are build time, not registry push time. Without a timestamp cooldown has nothing to measure against. If you have a workable source for tag push time I'm interested, otherwise OCI probably stays on the "no cooldown" list and the per-version denylist (#360) is the tool for blocking a specific image.Maven/Gradle:
maven-metadata.xmlonly has a single<lastUpdated>for the whole artifact, not per-version timestamps, so same problem as OCI. Gradle build cache has no versions.README Helm row: yes, out of date, I'll fix it.
simonchrz commentedon Oct 23, 2026
Go is in #564.
For Maven, there's a per-version time the proxy could use: the
Last-Modifiedheader of each version's.pom. On Central it matches the deploy time, e.g.guava-33.0.0-jre.pomreturnsMon, 18 Dec 2023 20:49:31 GMT, the same time search.maven.org reports. Renovate'sminimumReleaseAgeuses this header for Maven, Dependabot falls back to it, and Cloudsmith's cooldown stores it as the publish time.Roughly:
Last-Modifiedonce per version and store it inversions.published_at, as npm does now. Release files don't change.maven-metadata.xml, recompute<latest>/<release>and its checksum files, and refuse the version's files.<lastUpdated>is older than the window, no version can be new, so nothing needs checking. Otherwise, walk the list from the newest end and stop at the first version that is old enough. That matters because Central now answers bursts with long 429 blocks.Caveats: a Nexus or Artifactory upstream may report when it cached the file rather than when it was published, and SNAPSHOTs are left out.
Would you take a PR along these lines?
Apply cooldown to Go modules
andrew commentedon Oct 23, 2026
Thanks for Go. Yes to Maven along those lines. packages.ecosyste.ms uses the
.pomLast-Modifiedfor Maven publish times too (maven.rb). One more case for the caveat besides Nexus/Artifactory: on Google's Central mirrorLast-Modifiedis when the file reached the bucket, and the upload time is inx-goog-meta-last-modifiedinstead, missing for files from its 2019 bulk import. Please put that in the docs next to the Go caveat.Apply cooldown to Maven
Document Maven cooldown