# Security runtime: the published control image plus a Gitleaks 8.21.2 built from verified upstream source with a patched # Go toolchain and golang.org/x/text, for the history secret scan. # Why a rebuild: the upstream prebuilt 8.21.2 binary was scanned at 28 HIGH/CRITICAL findings (26 in the Go standard # library, 2 in golang.org/x/text). Gitleaks' own source, rules and fingerprints are exactly the 8.21.2 commit below; # only the compiler (official Go image) and the golang.org/x/text version change. No scanner source or rule is edited. # Stages: gitleaks-source downloads and verifies the source archive (control image Python: urllib, hashlib, tarfile); # gitleaks-build compiles it in the pinned Go image; the final stage is the control image plus that one binary. # Only the final stage ships. Nothing is installed or downloaded when a pipeline runs, and no platform or application # source is copied into the image. The downloads and `go get` happen at image build time only. Build context is not used. # UNQUALIFIED: this recipe has not been built, scanned, smoke-tested or published; see SECURITY-RUNTIME.md. # The pins mirror runtime-qualification/security/rebuild-pins.json. # # CONTROL_IMAGE the published control image, pinned by digest # GO_IMAGE the official Go 1.27.3 image, pinned by digest (compiler and standard library) # GITLEAKS_VERSION the Gitleaks release, embedded in the binary as its version; must equal secret_scan.py # GITLEAKS_SOURCE_COMMIT the upstream commit of that release; GITLEAKS_SOURCE_SHA256 is the SHA-256 of its codeload archive # TEXT_VERSION the golang.org/x/text version that fixes the two library findings ARG CONTROL_IMAGE=git.kof22.com/koftwentytwo/platform-ci-control@sha256:11f8cb328e7fc7aca8e0c39ed979b33cb1db411a59460baae3e0d48281a15e3c ARG GO_IMAGE=golang:1.27.3-bookworm@sha256:e482b31b5d30c31f9e495f4b8cbdf41429b2d74955dfbcd9c0a904483d738390 ARG GITLEAKS_VERSION=8.21.2 ARG GITLEAKS_SOURCE_COMMIT=43fae355e6fe4d99d2a7b240a224b85e2903aeb4 ARG GITLEAKS_SOURCE_SHA256=9035d05f3aa6c28dbc06c9785b019b2c2331efdb91c626abe39381417d08ab41 ARG TEXT_VERSION=v0.41.0 # Source stage: only builds /src, the verified upstream source tree. FROM ${CONTROL_IMAGE} AS gitleaks-source ARG CONTROL_IMAGE ARG GITLEAKS_SOURCE_COMMIT ARG GITLEAKS_SOURCE_SHA256 RUN <<'FETCH' set -eu printf '%s' "${CONTROL_IMAGE}" | grep -Eq '@sha256:[0-9a-f]{64}$' || { echo 'CONTROL_IMAGE must be pinned by @sha256 digest' >&2; exit 1; } printf '%s' "${GITLEAKS_SOURCE_COMMIT}" | grep -Eq '^[0-9a-f]{40}$' || { echo 'GITLEAKS_SOURCE_COMMIT must be a full commit hash' >&2; exit 1; } printf '%s' "${GITLEAKS_SOURCE_SHA256}" | grep -Eq '^[0-9a-f]{64}$' || { echo 'GITLEAKS_SOURCE_SHA256 must be a SHA-256 hex digest' >&2; exit 1; } mkdir /extract python3 -I - <<'PYTHON' import hashlib import io import os import sys import tarfile import urllib.request commit = os.environ["GITLEAKS_SOURCE_COMMIT"] want = os.environ["GITLEAKS_SOURCE_SHA256"] url = f"https://codeload.github.com/gitleaks/gitleaks/tar.gz/{commit}" data = urllib.request.urlopen(url, timeout=120).read() got = hashlib.sha256(data).hexdigest() if got != want: sys.exit(f"{url}: checksum mismatch, got {got}") with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as archive: archive.extractall("/extract", filter="data") PYTHON set -- /extract/* test "$#" = 1 test -d "$1" mv "$1" /src test -f /src/go.mod test -f /src/main.go FETCH # Build stage: compiles with the official Go image only, never with a toolchain downloaded by Go itself. FROM ${GO_IMAGE} AS gitleaks-build ARG GO_IMAGE ARG GITLEAKS_VERSION ARG TEXT_VERSION ENV GOTOOLCHAIN=local ENV CGO_ENABLED=0 COPY --from=gitleaks-source /src /src WORKDIR /src RUN <<'BUILD' set -eu printf '%s' "${GO_IMAGE}" | grep -Eq '@sha256:[0-9a-f]{64}$' || { echo 'GO_IMAGE must be pinned by @sha256 digest' >&2; exit 1; } go version | grep -q ' go1\.27\.3 ' go get "golang.org/x/text@${TEXT_VERSION}" test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "${TEXT_VERSION}" module="$(go list -m)" go build -trimpath -buildvcs=false -ldflags "-s -w -X ${module}/cmd.Version=${GITLEAKS_VERSION}" -o /out/gitleaks . go version -m /out/gitleaks | grep -q ': go1\.27\.3$' go version -m /out/gitleaks | grep -Eq "dep[[:space:]]+golang\.org/x/text[[:space:]]+${TEXT_VERSION}([[:space:]]|\$)" test "$(/out/gitleaks version)" = "${GITLEAKS_VERSION}" BUILD # Runtime stage: the control image and the one rebuilt binary, nothing else. FROM node:22.20.0-bookworm@sha256:915acd9e9b885ead0c620e27e37c81b74c226e0e1c8177f37a60217b6eabb0d7 AS actions-node FROM ${CONTROL_IMAGE} ARG CONTROL_IMAGE ARG GITLEAKS_VERSION ARG GITLEAKS_SOURCE_COMMIT ARG TEXT_VERSION COPY --from=actions-node /usr/local/bin/node /usr/local/bin/node RUN test "$(node --version)" = "v22.20.0" COPY --from=gitleaks-build /out/gitleaks /usr/local/bin/gitleaks RUN test "$(/usr/local/bin/gitleaks version)" = "${GITLEAKS_VERSION}" && git --version LABEL io.platform-ci.control-image="${CONTROL_IMAGE}" LABEL io.platform-ci.gitleaks-version="${GITLEAKS_VERSION}" LABEL io.platform-ci.gitleaks-source-commit="${GITLEAKS_SOURCE_COMMIT}" LABEL io.platform-ci.gitleaks-text-version="${TEXT_VERSION}"