feat: fips-strict-debug variant for GODEBUG=fips140=only builds

Summary

Adds a seventh image variant, kaniko:vX.Y.Z-fips-strict-debug, built from the same Renovate-tracked upstream tag as every other variant but with a local patch applied that constrains the TLS client's ECDH curve preferences to the FIPS 140-3 approved P-curves (P-256, P-384, P-521).

Why: the standard -fips-debug image panics on the first TLS handshake when run with GODEBUG=fips140=only because Go's default tls.Config.CurvePreferences includes X25519, which is outside the FIPS boundary. Server-side curve restriction is necessary but not sufficient; the client must also be constrained. The fix is one application-side override that the adjacent Go ecosystem has already converged on (aws/aws-sdk-go-v2#3345, cockroachdb/cockroach#166494).

Patch was first opened as a draft PR at andrewdunndev/kaniko@feat/fips140-strict-curve-preferences targeting chainguard-forks/kaniko. The upstream repository restricts PR creation to named collaborators, so the patch lands downstream here as a tracked artifact under patches/fips-strict/, applied on top of the upstream tag at build time. Upstream version tracking continues through Renovate against chainguard-forks/kaniko.

End-to-end lab evidence (panic transcript + side-by-side baseline / relaxed / patched-strict bench cells) at public-sector-tools/lab/airgap-fips.

What changes

  • patches/none/.gitkeep -- empty marker for vanilla builds.
  • patches/fips-strict/0001-fips-strict-curve-preferences.patch -- the diff as a single auditable artifact (218 lines, includes full commit message with precedent links).
  • Dockerfile.{standard,debug,warmer} -- one new ARG KANIKO_PATCHES_SET (default none), one COPY patches/${KANIKO_PATCHES_SET}/ + apply loop, one new OCI label io.gitlab.public-sector-tools.kaniko.patches-set for provenance. Default behavior unchanged for callers who don't pass the build-arg.
  • .gitlab-ci.yml -- one new build job, one new SBOM job, one new SLSA attest job, one new cosign verify job, one new needs: override to serialize sbom -> slsa attest. Matches the supply-chain coverage of every other variant.
  • README.md -- variant table gains a row, new section explains when to use -fips-strict-debug and points at the patch file + the upstream PR attempt for pedigree.
  • CHANGELOG.md -- Unreleased entry.

Test plan

  • CI pipeline green on this branch (all seven build jobs, including the new container-build-debug-fips-strict)
  • container-sbom-debug-fips-strict produces a CycloneDX SBOM attestation against the image digest
  • container-attest-debug-fips-strict produces a SLSA v1.0 provenance attestation
  • container-verify-debug-fips-strict cosign-verifies the chain
  • Pull the resulting image, inspect labels: confirm io.gitlab.public-sector-tools.kaniko.patches-set="fips-strict" is set and io.gitlab.public-sector-tools.gofips140="v1.0.0" is set
  • Run the lab harness against the new image with GODEBUG=fips140=only and --fips-strict: expect bench passes (lab already validated against a locally-built version of this binary; this re-test confirms the CI-produced artifact behaves the same)
  • No regression in the existing six variants: confirm their builds produce identical labels and binaries to today (the KANIKO_PATCHES_SET=none default means the patch-apply step is a no-op)

Risks

  • Patch rot. If a future chainguard-forks/kaniko release modifies pkg/util/transport_util.go::MakeTransport in a way that conflicts with the patch, git apply will fail and the CI build for the strict variant will fail loudly. Other six variants continue to build normally. Recovery: refresh the patch against the new upstream and re-test. Same maintenance shape any downstream distro-style patch series carries.
  • Renovate doesn't know about the patch. Renovate bumps the upstream tag in .gitlab-ci.yml's KANIKO_VERSION variable. The patch is decoupled -- it just needs to keep applying. If it stops applying, CI fails the strict variant only, surfacing the conflict.
  • Provenance label is informational only. The io.gitlab.public-sector-tools.kaniko.patches-set OCI label declares the patch series applied; auditors verify the actual diff by reading patches/fips-strict/0001-*.patch in this repository. Cross-reference, not enforcement.

Followups (not blocking)

  • Add -fips-strict-standard and -fips-strict-warmer variants if customers ask. The Dockerfile + CI scaffolding already supports it; each is one additional CI block to enable.
  • The andrewdunndev/kaniko branch remains live as the artifact of the upstream PR attempt. Re-target if Chainguard responds and offers a contribution path.

Merge request reports

Loading