fix: stop reporting unrelated repos as Docker image provenance - #2
Open
azaidelson wants to merge 3 commits into
Open
fix: stop reporting unrelated repos as Docker image provenance#2azaidelson wants to merge 3 commits into
azaidelson wants to merge 3 commits into
Conversation
Filtering Docker's meta repos out of official-image descriptions promoted whatever GitHub link happened to come next, including links that appear in prose. library/ubuntu resolved to docker-library/postgres, linked inside a locale example in its README: [2/5] Repo inferred: docker-library/postgres repo: github.com/docker-library/postgres Require the fallback candidate's owner or repo to contain the image name, and return nothing when none does. Exact name matches are unaffected, and the common wrapper naming still resolves (alpinelinux/docker-alpine, MariaDB/mariadb-docker, CentOS/sig-cloud-instance-images). Also treat docker-library/faq, docker/hub-feedback and docker/roadmap as meta repos - they appear in the same descriptions and could win the fallback. Adds node/src/github.test.ts, which had no coverage; the two implementations were kept in sync by eye.
Reviewers found the name-substring gate rejected correct answers for a whole class of images: the source repo often shares no substring with the image name. Measured against live Docker Hub, it fixed ubuntu but destroyed six: oraclelinux oracle/container-images -> none rockylinux rocky-linux/sig-cloud-instance-images -> none eclipse-temurin adoptium/containers -> none amazoncorretto corretto/corretto-docker -> none r-base rocker-org/rocker -> none prom/node-exporter prometheus/node_exporter -> none It also promoted worse repos, since it scans for the first *related* link: library/ros went from osrf/docker_images to ros2/demos, matched only because "ros" is a substring of "ros2". Accept a link as a source claim on any of three signals instead: the repo is named after the image, it belongs to the image's own Docker Hub namespace, or it is linked more than once. Descriptions link the source once per supported tag (oracle/container-images, 18 times) while a prose aside appears once. Over 80 images this now matches the previous behaviour everywhere except three, all improvements: ubuntu docker-library/postgres -> none registry opencontainers/distribution-spec -> distribution/distribution clickhouse/clickhouse-server moby/moby -> ClickHouse/ClickHouse This also makes the meta-repo deny list load-bearing rather than cosmetic: docker-library/docs and friends are linked 2-6 times in nearly every official description, so a count-based rule would otherwise select them constantly. Tests now cover the namespaced path, which the previous round never exercised, and 'npm test' builds first so src/ tests cannot silently go unrun.
infer_repo_from_dockerhub guesses name/name (or namespace/name) when the description yields nothing, and check_github_repo_exists followed redirects, so GitHub's rename redirects turned wrong guesses into confident answers: ubuntu/ubuntu -> ubuntu-xx/ubuntu (personal repo) debian/debian -> Debian/.github (meta repo) consul/consul -> consuldemocracy/consuldemocracy (unrelated project) This is why ubuntu:24.04 still reported a source repo after the previous commit: the description path correctly gave up, then the guess "succeeded" via a redirect. It now reports repo_not_found. Require the API to answer at exactly the requested path, ignoring case. The cost, measured over 40 guesses: 5 resolve only via a redirect, and of those only nginxinc/nginx-prometheus-exporter (a genuine org rename) is one we lose - it now returns nothing instead of nginx/nginx-prometheus-exporter. A rename and a squatted name are structurally identical over the API, so no rule separates them; for a provenance tool, no answer beats a wrong one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to aae52c1 (resolve official Docker Hub images to source repo, not build wrapper).
Two independent ways a wrong GitHub repo gets reported as an image's source. Three reviewers shaped this; the first pushed version of this PR was itself wrong and was replaced (history kept for the record).
1. Links cited in passing
Filtering Docker's meta repos out of official-image descriptions promoted whatever link came next — including prose asides.
library/ubuntuhas no source link, onlyofficial-images,repo-info,docs, and this, in a locale example:So on
maintoday,ubuntu:24.04reportsgithub.com/docker-library/postgres. The failure that bites is a wrong-but-plausible repo whose tags coincidentally match the image tag, which yields a fabricated commit with a confidence score.Rejected approach (first push): require the image name to appear in the owner or repo. Measured against live Docker Hub, this fixed
ubuntuand destroyed six correct answers — the source repo frequently shares no substring with the image (eclipse-temurin→adoptium/containers,r-base→rocker-org/rocker,oraclelinux→oracle/container-images,rockylinux,amazoncorretto,prom/node-exporter). It also promoted worse repos, since it scans for the first related link:library/roswent fromosrf/docker_imagestoros2/demos, matched only becauserosis a substring ofros2.Shipped approach: accept a link as a source claim on any of three signals — the repo is named after the image, it belongs to the image's own Docker Hub namespace, or it is linked more than once. Descriptions link the source once per supported tag (
oracle/container-imagesappears 18 times); a prose aside appears once.Over 80 library and namespaced images this matches previous behaviour everywhere except three, all improvements:
ubuntudocker-library/postgresregistryopencontainers/distribution-specdistribution/distributionclickhouse/clickhouse-servermoby/mobyClickHouse/ClickHouseThis also makes the meta-repo deny list load-bearing rather than cosmetic:
docker-library/docsand friends are linked 2-6 times in nearly every official description, so a count-based rule would otherwise select them constantly.2. Redirects turning guesses into answers
When the description yields nothing, resolution guesses
name/name.check_github_repo_existsfollowed redirects, so GitHub's rename redirects turned wrong guesses into confident answers:This is why
ubuntustill reported a repo after fix 1 — the description path correctly gave up, then the guess "succeeded" via a redirect. It now requires the API to answer at exactly the requested path, ignoring case.Measured cost: of 40 guesses, 5 resolve only via redirect; only
nginxinc/nginx-prometheus-exporter(a genuine org rename) is one we lose — it returns nothing instead ofnginx/nginx-prometheus-exporter. A rename and a squatted name are structurally identical over the API, so no rule separates them. For a provenance tool, no answer beats a wrong one. This is a separate commit (e40ef06) and can be dropped independently if you disagree with that trade.Result
Tests
Python 71 pass, Node 37 pass. New coverage for the namespaced path (never exercised before), repeatedly-linked sources, meta repos linked repeatedly, and redirect rejection.
node/src/github.tshad no test file at all —node/src/github.test.tsis new.npm testnow builds first, sosrc/tests cannot silently go unrun.Known remaining gaps (unchanged by this PR)
-library-imagewrapper filter is narrower than wrapper naming in the wild:redis→redis/docker-library-redis,nginx→nginxinc/docker-nginx,mariadb→MariaDB/mariadb-dockerstill resolve to build wrappers rather than source.., so repos with a dot in the name can never resolve (WASdev/ci.dockercaptures asWASdev/ci).