Resolve Docker images in a docker-compose file to their exact source code commits on GitHub.
Available as both a Python package and a Node.js package.
Node.js:
npm install -g code-provenancePython:
pip install code-provenanceGiven a docker-compose.yml:
version: "3"
services:
web:
image: traefik:v3.6.0Run:
code-provenance docker-compose.ymlOutput:
web: traefik:v3.6.0
repo: github.com/traefik/traefik
commit: 06db5168c0d9
status: resolved
confidence: exact
url: https://github.com/traefik/traefik/commit/06db5168c0d9...
The tool resolves each Docker image through a chain of strategies, stopping at the first success:
- OCI labels -- reads
org.opencontainers.image.sourceandorg.opencontainers.image.revisionfrom the image manifest - Repo inference -- maps the image registry/namespace to a GitHub repository (GHCR namespaces map directly; Docker Hub images are resolved via the Hub API)
- Tag matching -- matches the Docker tag against git tags in the inferred repository
- Packages API -- for GHCR images, queries the GitHub Packages API to resolve digests or
:latesttags - Latest release / commit -- for
:latesttags, falls back to the most recent GitHub release or the HEAD commit on the default branch
- exact -- the commit is definitively tied to the image (e.g., OCI revision label with a versioned tag, or an exact git tag match)
- approximate -- the commit is a best-effort match (e.g.,
:latesttag, prefix tag match, or latest release fallback)
code-provenance [compose-file] [--image IMAGE] [--json] [--verbose]| Argument | Description |
|---|---|
compose-file |
Path to docker-compose file (default: docker-compose.yml) |
--image IMAGE |
Resolve a single image reference instead of a compose file |
--json |
Output results as JSON |
--verbose, -v |
Show the resolution steps for each image |
# Resolve all images in a compose file
code-provenance docker-compose.yml
# Resolve a single image
code-provenance --image ollama/ollama:0.12.3
# JSON output
code-provenance docker-compose.yml --json
# Show resolution steps
code-provenance docker-compose.yml --verbose
# Combine flags
code-provenance --image traefik:v3.6.0 --json --verboseThe tool works without authentication for basic resolution (OCI labels, tag matching). However, a GITHUB_TOKEN is required for:
- Resolving digest-only images (e.g.,
image@sha256:...) via the GitHub Packages API - Resolving
:latesttags on GHCR images via the Packages API - Higher GitHub API rate limits (5000/hr vs 60/hr unauthenticated)
Option 1 — Use the gh CLI (recommended): If you have the GitHub CLI installed and authenticated, run.sh auto-detects the token. Make sure your token has read:packages scope:
gh auth refresh -h github.com -s read:packagesOption 2 — Set the environment variable directly:
export GITHUB_TOKEN=ghp_your_token_hereCreate a classic token at https://github.com/settings/tokens with read:packages scope.
Both packages export the same API for programmatic use.
Node.js:
import { parseCompose, parseImageRef, resolveImage } from "code-provenance";
import { readFileSync } from "fs";
const yaml = readFileSync("docker-compose.yml", "utf-8");
for (const [service, image] of parseCompose(yaml)) {
const ref = parseImageRef(image);
const result = await resolveImage(service, ref);
console.log(`${result.service}: ${result.commit} (${result.confidence})`);
}Python:
from code_provenance.compose_parser import parse_compose, parse_image_ref
from code_provenance.resolver import resolve_image
yaml_content = open("docker-compose.yml").read()
for service, image in parse_compose(yaml_content):
ref = parse_image_ref(image)
result = resolve_image(service, ref)
print(f"{result.service}: {result.commit} ({result.confidence})")See python/README.md and node/README.md for full API reference.
MIT