Skip to content

Version-list filtering for all remaining ecosystems #132

Open

Description

@andrew

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:

  • Go (Apply cooldown to Go modules #564)
  • 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.

Activity

  1. Markeli commented on Oct 1, 2026

    @Markeli

    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?

  2. andrew commented on Oct 8, 2026

    @andrew
    ContributorAuthor

    Thanks for the nudge.

    #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.

    README Helm row: yes, out of date, I'll fix it.

  3. simonchrz commented on Oct 23, 2026

    @simonchrz
    Contributor

    Go is in #564.

    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.

    Would you take a PR along these lines?

  4. added a commit that references this issue on Oct 23, 2026
  5. andrew commented on Oct 23, 2026

    @andrew
    ContributorAuthor

    Thanks for Go. Yes to Maven along those lines. packages.ecosyste.ms uses the .pom Last-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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions