container-source-policy-darwin-arm64
v0.5.0
Published
The darwin arm64 binary for container-source-policy
Readme
container-source-policy
Generate BuildKit source policies that make Docker builds reproducible and secure — without modifying your Dockerfiles.
- 📌 Pin images and URLs to immutable checksums
- 🛡️ Harden builds with Docker Hardened Images (fewer CVEs, smaller footprint)
- ✅ Validate existing policies against Dockerfiles (coming soon)
See the BuildKit documentation on build reproducibility for more details on source policies.
Quick start
container-source-policy pin --stdout Dockerfile > source-policy.json
EXPERIMENTAL_BUILDKIT_SOURCE_POLICY=source-policy.json docker buildx build -t my-image:dev .Note:
EXPERIMENTAL_BUILDKIT_SOURCE_POLICYis the environment variable used by Docker Buildx to specify a source policy file.
Install
Run directly without installing (recommended):
# npm/bun
npx container-source-policy --help
bunx container-source-policy --help
# Python
uvx container-source-policy --help
# Ruby (requires RubyGems 3.3+)
gem exec container-source-policy --helpOr install globally:
# Go (build from source)
go install github.com/tinovyatkin/container-source-policy@latest
# npm
npm i -g container-source-policy
# Python
pipx install container-source-policy
# Ruby
gem install container-source-policyUsage
Generate a policy for one or more Dockerfiles:
container-source-policy pin --stdout Dockerfile Dockerfile.ci > source-policy.jsonRead the Dockerfile from stdin:
cat Dockerfile | container-source-policy pin --stdout -Write directly to a file:
container-source-policy pin --output source-policy.json DockerfileDocker Hardened Images (DHI)
Use --prefer-dhi to pin Docker Hub library images to their Docker Hardened Images equivalents when available:
# First, login to dhi.io with your Docker Hub credentials
docker login dhi.io
# Then use --prefer-dhi to prefer hardened images
container-source-policy pin --prefer-dhi --stdout DockerfileThis converts eligible images (e.g., alpine:3.21, node:22, golang:1.23) to their dhi.io equivalents, which are minimal, security-hardened
versions with fewer vulnerabilities.
- Only Docker Hub library images (
alpine,node,golang, etc.) are eligible - Images not available on dhi.io silently fall back to docker.io
- Non-library images (
ghcr.io/*,docker.io/myorg/*) are unchanged - The policy selector still matches the original reference, so your Dockerfile works unchanged
Example output with --prefer-dhi:
{
"selector": { "identifier": "docker-image://golang:1.23" },
"updates": { "identifier": "docker-image://dhi.io/golang:1.23@sha256:..." }
}Then pass the policy to BuildKit / Buildx via the environment variable:
EXPERIMENTAL_BUILDKIT_SOURCE_POLICY=source-policy.json docker buildx build .Or use buildctl directly with the --source-policy-file flag:
buildctl build --frontend dockerfile.v0 --local dockerfile=. --local context=. --source-policy-file source-policy.jsonWhat gets pinned
Container images (FROM, COPY --from, ONBUILD)
- Looks at
FROM …,COPY --from=<image>, and theirONBUILDvariants across all provided Dockerfiles. - Skips:
FROM scratchFROM <stage>/COPY --from=<stage>references to a previous named build stageCOPY --from=0numeric stage indicesFROM ${VAR}/COPY --from=${VAR}(unexpanded ARG/ENV variables)- images already written as
name@sha256:…
- Resolves the image manifest digest from the registry and emits BuildKit
CONVERTrules of the form:docker-image://<as-written-in-Dockerfile>→docker-image://<normalized>@sha256:…
HTTP sources (ADD, ONBUILD ADD)
- Looks at
ADD <url> …andONBUILD ADD <url> …instructions with HTTP/HTTPS URLs. - Skips:
ADD --checksum=… <url>(already pinned)- URLs containing unexpanded variables (
${VAR},$VAR) - Git URLs (handled separately, see below)
- Volatile content (emits warning): URLs returning
Cache-Control: no-store,no-cache,max-age=0, or expiredExpiresheaders
- Fetches the checksum and emits
CONVERTrules withhttp.checksumattribute. - Respects
Varyheader: captures request headers that affect response content (e.g.,User-Agent,Accept-Encoding) and includes them in the policy ashttp.header.*attributes to ensure reproducible builds.
Optimized checksum fetching — avoids downloading large files when possible:
raw.githubusercontent.com: extracts SHA256 from ETag header- GitHub releases: uses the API
digestfield (setGITHUB_TOKENfor higher rate limits) - S3: uses
x-amz-checksum-sha256response header (by sendingx-amz-checksum-mode: ENABLED) - Fallback: downloads and computes SHA256
Git sources (ADD, ONBUILD ADD)
- Looks at
ADD <git-url> …andONBUILD ADD <git-url> …instructions with Git repository URLs. - Supports various Git URL formats:
https://github.com/owner/repo.git#refgit://host/path#ref[email protected]:owner/repo#refssh://git@host/path#ref
- Skips URLs containing unexpanded variables (
${VAR},$VAR) - Uses
git ls-remoteto resolve the ref (branch, tag, or commit) to a commit SHA - Emits
CONVERTrules withgit.checksumattribute (full 40-character commit SHA)
Example: ADD https://github.com/cli/cli.git#v2.40.0 /dest pins to commit 54d56cab...
Development
make build
make test
make lintUpdate integration-test snapshots:
UPDATE_SNAPS=true go test ./internal/integration/...Repository layout
cmd/container-source-policy/cmd/: CLI commands (urfave/cli)internal/dockerfile: Dockerfile parsing (FROMandADDextraction)internal/registry: registry client (image digest resolution)internal/dhi: Docker Hardened Images reference mappinginternal/http: HTTP client (URL checksum fetching with optimizations)internal/git: Git client (commit SHA resolution via git ls-remote)internal/policy: BuildKit source policy types and JSON outputinternal/pin: orchestration logic forpininternal/integration: end-to-end tests with mock registry/HTTP server and snapshotspackaging/: wrappers for publishing prebuilt binaries to npm / PyPI / RubyGems
Packaging
See packaging/README.md for how the npm/PyPI/Ruby packages are assembled from GoReleaser artifacts.
