Check D8 · provenance family · automatic · one of the 11 Docker Desktop checks
The question this check asks: where does this extension say its code comes from — and what do the 22 GitHub checks say about that repository? It is the one check on the Docker Desktop roster that composes with another roster: the declared source is assessed on the same pass, and its verdict rides along.
A Docker Desktop extension is an image, and everything that runs — the dashboard tab, the backend in Docker Desktop's VM, the binaries copied onto the host — is inside layers RepoGates never pulls and Docker never audits. Docker's Marketplace page says extensions "are reviewed by Docker, but are not subject to a full security audit"; its manual validation has been paused since 9 January 2024, and the automated check that replaced it "checks if the extension's Dockerfile specifies all the required labels and if the metadata file is valid against the JSON schema file". The nearest thing to an independent view is the one SensePost named on 30 May 2023: "Unless an extension author makes their extension open source, the only way to see what it is really doing is to manually inspect / reverse engineer the extension itself."
So the declared source is the only place an extension's provenance can be read at all — who made it, when, whether anyone else has, what it carries — and RepoGates already has 22 checks that read exactly that for a GitHub repository, from the owner's account age to the campaign list. D8 exists so an extension is not assessed in ignorance of what those 22 would say about the code it claims to be built from. Where the declaration lives is the image's labels. Docker's labels page requires com.docker.extension.publisher-url and lists com.docker.extension.additional-urls as optional; the OCI org.opencontainers.image.source label is not among Docker's requirements at all, and only 2 of the 12 images sampled from the registry carry it. On this marketplace the repository, when there is one, is usually behind the publisher URL — mochoa's is github.com/marcelo-ochoa/….
The labels come from the image's config blob — a registry pull token, the OCI index, the linux/amd64 manifest, the config; the image is never pulled. D8 reads the declared source in order of authority: org.opencontainers.image.source, then the publisher URL, then each additional URL, and takes the first that is a GitHub repository. A publisher homepage that is not GitHub is not a source. Four rows follow, and three of them are graded on whether the extension is listed and established — in Docker's Marketplace index (D5) with a Hub repository at least 90 days old (dde_established_days).
No source. dde-no-source is INFO, no points, when listed and established ("noted; the extension is listed and established"); MEDIUM, 6 points, on an established image that is not in the index; HIGH, 12 points, on one under 90 days old ("nothing to verify the image against"):
"D8; no source in the labels — only 2 of 12 sampled carry org.opencontainers.image.source, so a note when listed and established; MED established-unlisted; HIGH new"
Owner mismatch. When the source is on GitHub under an owner that is neither the image's Hub namespace nor named in the org.opencontainers.image.vendor label, dde-source-owner-mismatch is a note when listed and established and HIGH, 10 points, otherwise — "the two are not tied":
"D8; source under another GitHub owner — a note on a listed, established extension"
The source's own verdict. The GitHub repository is assessed through the 22 checks on the same pass — under 60 per cent of the time the scan has left, folded with the campaign blocklist — and returned in the response's source object: its verdict, score, up to three driving findings and whether it is campaign-listed. The row dde-source:owner/repo carries that into the extension's report: CRITICAL, 45 points and a BLOCK in every dimension when the source is campaign-listed; HIGH, 15 points, when the source's own verdict is BLOCK; a note otherwise, including when the source is REVIEW. A source the public API cannot see — private, renamed or deleted — is a note that says so:
"D8; the declared source repository's own 22-check verdict rides along: CRIT campaign-listed, HIGH on BLOCK, a note otherwise"
A source outside GitHub. An OCI source label pointing at GitLab or anywhere else is dde-source-external:host, a note:
"D8; a non-GitHub source is not assessed on this tier"
The verdict engine is the one behind all 11 checks: any CRITICAL finding is a BLOCK, any HIGH or MEDIUM finding is a REVIEW, and a report with nothing above INFO is a PASS. The score is 100 minus every fired penalty, floored at zero — green at 80 and above, amber from 50 to 79, red below 50. A campaign-listed source is the single CRITICAL on the whole roster. What the preflight does before docker extension install runs is the profile's decision: personal-default maps HIGH and MEDIUM to warn, an ask, and CRITICAL to block; org-strict maps HIGH to block, so a new image with no source is denied there. When the scan runs out of time before the source can be assessed, the note says "source repository not assessed" and the scan is partial — retried, never cached as a PASS. D8 feeds the Clone the source dimension with D1–D5 and D10; a dimension takes the worst of its checks and reads PASS only when every one of them ran.
Measured 18 September 2026 against all 50 listed extensions: 50 PASS, 0 REVIEW, 0 BLOCK. 27 declare a source — 17 under the same owner as the image, 10 under another: mochoa's images point at marcelo-ochoa, l6khq's at Lacework's repository, and oslabs-beta and prakhar1989 are among the rest — and 23 declare none. Every one of the 50 is listed and at least 853 days old, so all 33 of those rows are notes. Weighted without the grading, D8 alone would have turned two-thirds of the marketplace into REVIEW for a shape Docker's own label requirements do not ask anyone to avoid.
The 27 sources went through the 22 on the same pass: 25 REVIEW, 2 PASS, 0 BLOCK, 0 campaign-listed. A REVIEW source is a note by design — what the 22 find on a repository is reported in the source object for the reader, and escalates only on BLOCK or a campaign listing — so dde-source was a note every time. The cost on the other side is stated: a genuinely new extension with no source reads REVIEW at 88 on this check alone for its first 90 days; an organisation's private, established extension with no source reads REVIEW at 94 on this check alone for as long as it is off the index (D5 takes another 15); and a new image whose vendor label is a company name that does not contain its GitHub owner reads the mismatch at HIGH. On this frozen marketplace D8 is a note-taker; the same shapes are findings on an image that is unlisted or new.
Whether the image was built from the source. Labels are text set at build time; an image can name any repository, and RepoGates never diffs the image's layers against it because the image is never pulled. A declared source proves that a repository exists and what the 22 say about it, not that the layers came from it. A change inside the source. The 22 read a repository's provenance and its file tree, not a diff. A link that is not a label. The extension's detailed description and changelog may contain HTML and any link at all; D8 does not read them. Any host but GitHub. A GitLab source is a note and nothing more. A private source. A repository the public API cannot see is reported as not assessed — not as a pass, and not as a fault.
RepoGates assesses a Docker Desktop extension on request — through the API, the MCP server (platform="dde") and the preflight for docker extension install. It does not see an extension installed from Docker Desktop's own Extensions Marketplace tab, which is the app's own fetch; the board inside Docker Desktop is not built, and cannot be — its marketplace is a native window no browser extension sees. The image is never pulled and its code is not read: a PASS means the provenance and the declared install surface are clean, never that the backend or the host binaries were inspected.
The labels are in the image config, which skopeo reads from the registry without pulling — the same blob RepoGates reads:
skopeo inspect docker://OWNER/NAME | jq '.Labels
| {source: ."org.opencontainers.image.source",
publisher: ."com.docker.extension.publisher-url",
additional: ."com.docker.extension.additional-urls",
vendor: ."org.opencontainers.image.vendor"}'
Read them in D8's order: the source label, then the publisher URL, then the additional URLs, and take the first GitHub repository. Compare its owner with the Hub namespace and the vendor label. Then read that repository the way the 22 do — the three fields worth reading together:
gh api repos/OWNER/REPO --jq '{created_at, pushed_at, stargazers_count}'
Three worked references: docker/disk-usage-extension declares docker/disk-usage-extension as its source — same owner, a note carrying the repository's verdict; mochoa's listings point through their publisher URL at marcelo-ochoa — a mismatch, and a note because the extension is listed and established; library/nginx, which is no extension, declares no source — MEDIUM at 6, because it is established but not in the index, and one of the three rows behind its REVIEW 64. RepoGates itself: GET /v1/dde/score/OWNER/NAME with a personal API token (Authorization: Bearer rgp1.…) returns the source object beside the findings; check_repo("OWNER", "NAME", platform="dde") on the MCP server does the same; and docker extension install OWNER/NAME typed in Claude Code with the plugin installed is answered by the preflight before the line runs.
Why is an extension with no declared source only a note? Because most of the marketplace declares none. In the 18 September 2026 measurement of all 50 listed extensions, 23 carry no source in their labels — org.opencontainers.image.source is not among the labels Docker requires, and only 2 of the 12 images sampled from the registry carry it. So no source is a note on a listed extension with a Hub repository 90 days or older, MEDIUM at 6 points on an established image that is not in the index, and HIGH at 12 only on a new one, where nothing at all ties the image to anyone. The control library/nginx is the middle case: established, unlisted, sourceless, and 6 of its 36 lost points are this row.
What happens to the source's own verdict? It rides along. The declared GitHub repository is put through the 22 checks on the same pass, under 60 per cent of the remaining time budget, folded with the campaign blocklist, and returned in the response's source object with its verdict, score and the findings that drove it. The row dde-source:owner/repo carries that into the extension's report: CRITICAL at 45 points and a BLOCK everywhere when the source is campaign-listed, HIGH at 15 when the source's own verdict is BLOCK, a note otherwise — including REVIEW. In the measurement 25 of the 27 declared sources were REVIEW on the 22 and 2 were PASS, none BLOCK, none campaign-listed, so every one rode along as a note.
Does a declared source prove the image was built from it? No. Labels are text set at build time, and an image can name any repository it likes; RepoGates never diffs the image's layers against the repository, because the image is never pulled. What D8 establishes is that the repository the extension names exists, who owns it, and what the 22 checks say about it. It does not see a change inside that repository — the 22 read provenance and a file tree, not a diff — and it does not read a link buried in the extension's HTML description, which is not a label this check reads.
D1 Publisher — the other thing a sourceless image usually lacks: a Hub badge, and an account with any history · D5 Marketplace listing — the switch that decides a note against MEDIUM against HIGH here · V5 Source repository — the same composition on the VS Code Marketplace roster · C1 Owner account age — the first of the 22 the declared source is put through, and the one that turns a source into a BLOCK.
Add RepoGates to Chrome Pricing
Numbers on this page: the 18 September 2026 measurement of all 50 extensions in Docker's Marketplace index, the twelve-image registry sample read the same day, and library/nginx as a control; Docker's own Extensions documentation (labels, validation and Marketplace pages; manual validation paused 9 January 2024); SensePost, 30 May 2023; weights from the product's scoring table.