Skip to content
andrew.dunn.dev

kaniko

Source Site Releases

kaniko is a pipeline-driven build of chainguard-forks/kaniko, the fork of the daemonless kaniko image builder, packaged for GitLab Runner. I build it at GitLab Public Sector, the group behind egress, manifold and bulkhead, on the pattern of GitLab’s own CNG images: an upstream tag compiled in a UBI9 builder, shipped from scratch. Six images a release: standard, debug and warmer, in standard-library and FIPS 140-3 crypto, each cosign-signed through the job’s GitLab OIDC identity with a CycloneDX SBOM, SLSA v1.0 provenance and OpenVEX attached.

INPUTSupstream tagchainguard-forks/kanikogo-overrides.txtGo tarball + digestBUILDERUBI9check Go digestgo get overridesgo build, GOFIPS140 on or offRUNTIMEFROM scratchexecutor, CA bundlestandard, debug, warmer× stdlib, FIPS 140-3REGISTRYsix digestscosign signatureSBOM · SLSA · OpenVEXtag pipeline onlyRULEno upstream source file is edited • an override is a build input, like the Go and base-image pins
Build path from upstream tag to six images
  • The builder clones the fork at a tag Renovate tracks and checks the Go tarball against the digest go.dev publishes.
  • go-overrides.txt raises a module above the version the tag declares, for an advisory’s fix; scripts/check-versions.sh fails the pipeline once upstream carries it.
  • CGO off; GOFIPS140 empty or the pinned module version picks the crypto.
  • FROM scratch: the binary, the CA bundle from UBI, an empty Docker configuration directory. Debug variants add a busybox built from source at /busybox, with /bin/sh linked to it, since a CI job image needs a shell.
  • Scratch because kaniko unpacks a build’s base over its own root without clearing it: any file the base does not shadow is visible to that build’s RUN steps.

Build, sign, SBOM, provenance and release are public-sector/pipeline catalog components; OpenVEX is this project’s own job, rendered per variant from security/vex/statements.json and bound to that digest. A verify stage then runs the pushed bytes.

PUSHEDsix imagesrun, not rebuiltreal Dockerfilereal registryVERIFYsmoke buildsfips140=on, fips140=onlynon-UBI base leaks nothingwarmer round-tripREPRODUCEsame bytestwo more builds, —no-cache+ pushed /kaniko/executorthree hashes, one valueCONSUMERcosign verifytag-ref identitygrype or trivy, —vexofflineCONTRACTlinux/amd64 • unprivileged container, CAP_CHOWN only • no telemetry • release jobs run on a tag only
Verify the pushed images, then consume them
  • Smoke builds of a real Dockerfile against a real registry under GODEBUG=fips140=on and fips140=only.
  • A build over a non-UBI base fails if any path of ours beyond /kaniko, /workspace, /busybox and /bin/sh reaches the result.
  • verify-reproducibility compiles the builder twice more with --no-cache; both binaries and the published /kaniko/executor must hash identically.
  • A consumer checks offline: cosign verify against the tag-ref identity, the OpenVEX predicate handed to grype or trivy.

The executor runs as user 0 in an unprivileged container with one capability, CAP_CHOWN, for the chown(2) its extraction makes; the images call nothing home. Vulnerabilities in the kaniko binary go to the fork’s own security policy; this project answers for the wrapper, the images and their attestations, on linux/amd64, with no support entitlement.