Part of #1367 (Phase 3 — Dependency Engine v2).
Problem
Docker support is Docker Hub only: src/utils/dockerfile-parser.ts:189-210 hardcodes registry.hub.docker.com v2 tags API (optional DOCKERHUB_TOKEN). No GHCR/ECR/GCR/Quay/private registries; the registries config (src/types.ts — npm/npmScopes/composer) has no docker entry. Also, OSV lookups skip both Docker and GitHub Actions entirely (toOsvEcosystem returns null for them, src/services/security-advisories.ts).
CodeRabbit ships Hadolint + Trivy for containers; Renovate supports every major registry. We detect "every container build file convention" (96b6fca) but can only resolve tags from one registry.
Spec
1. Generic OCI Distribution API client
src/registry/oci-client.ts implementing the standard flow that covers all compliant registries:
- Parse image ref → registry host, namespace, repo, tag (default host
docker.io→registry-1.docker.io, library/ namespace inference) - Anonymous/token auth:
401→ parseWWW-Authenticate→ fetch bearer token from realm/service/scope → retry (this alone unlocks GHCR, Quay, most registries) GET /v2/{name}/tags/listwith pagination (Linkheaders)- Credentials per host via config + env:
registries.docker?: {
[host: string]: {
username?: string
passwordEnv?: string // env var name, never the secret itself
tokenEnv?: string
}
}Also honor ~/.docker/config.json auth entries when present (base64 user:pass; NOT credential helpers in v1 — document).
2. Registry specifics
- GHCR: bearer flow with
GITHUB_TOKENas password — works out of the box in Actions - ECR: token via
GET /tokenwith basic auth from env (AWS_*viaaws ecr get-login-passwordwhen CLI present; else documented env var) — best-effort tier - GCR/Artifact Registry: bearer flow with
oauth2accesstoken+ token env - Tag semantics: reuse existing version-tag filtering (
fetchLatestDockerImageVersionlogic indockerfile-parser.ts) — semver-ish tag detection, suffix preservation (-alpine,-slim), digest pinning support (updateimage@sha256:...by resolving the new tag's digest viaHEAD /v2/{name}/manifests/{tag})
3. Security coverage extension
- GitHub Actions: OSV supports
GitHub Actionsecosystem — stop returningnull; query advisories for action refs - Docker/base images: OSV has limited container data — instead surface (a) base-image EOL awareness (endoflife.date API for debian/alpine/node/etc. tags) and (b) a gate hook so #1382's dependency gate can block EOL'd base images
Tasks
oci-client.tswith the auth flow + pagination + fixtures (recorded 401/token/tags exchanges for docker.io, ghcr.io, quay.io)- Config
registries.docker+ validation + docs;.docker/config.jsonfallback - Digest-pinning update path (
FROM image@sha256+ comment with tag) - Replace hardcoded Docker Hub path in
dockerfile-parser.tswith the client - OSV:
GitHub Actionsecosystem wiring + tests - EOL detection for common base images + dashboard/gate surfacing
docs/features/docker.mdupdate (per-registry setup table)
Acceptance criteria
- Fixture Dockerfiles referencing
ghcr.io/...andquay.io/...images resolve latest tags and produce update PRs FROM node:20@sha256:...updates both tag and digest- Vulnerable GitHub Action fixture gets an OSV advisory annotation
- Docker Hub behavior unchanged (regression tests)