From ffbaa4be2a718907fd1282f0efc2bf2c74e0c0b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:31:01 +0000 Subject: [PATCH 1/2] Initial plan From 719f41863dabe26de30c102c710c8de455e8d6cc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:42:14 +0000 Subject: [PATCH 2/2] Pin poutine docker image to digest-pinned constant Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/poutine.go | 12 ++++++------ pkg/cli/poutine_test.go | 9 +++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/cli/poutine.go b/pkg/cli/poutine.go index 21beb2d1842..ae9ec977d3f 100644 --- a/pkg/cli/poutine.go +++ b/pkg/cli/poutine.go @@ -95,7 +95,7 @@ func runPoutineOnDirectory(workflowDir string, verbose bool, strict bool) error } // Build the Docker command with JSON output for easier parsing - // docker run --rm -v "$(pwd)":/workdir -w /workdir ghcr.io/boostsecurityio/poutine:latest analyze_local . --format json + // docker run --rm -v "$(pwd)":/workdir -w /workdir analyze_local . --format json // #nosec G204 -- gitRoot comes from git rev-parse (trusted source) and is validated as absolute path // exec.Command with separate args (not shell execution) prevents command injection volumeMount, err := buildDockerVolumeMount(gitRoot, "/workdir") @@ -112,7 +112,7 @@ func runPoutineOnDirectory(workflowDir string, verbose bool, strict bool) error "--rm", "-v", volumeMount, "-w", "/workdir", - "ghcr.io/boostsecurityio/poutine:latest", + PoutineImage, "analyze_local", ".", "--format", "json", @@ -130,7 +130,7 @@ func runPoutineOnDirectory(workflowDir string, verbose bool, strict bool) error "--rm", "-v", volumeMount, "-w", "/workdir", - "ghcr.io/boostsecurityio/poutine:latest", + PoutineImage, "analyze_local", ".", "--format", "json", @@ -215,7 +215,7 @@ func runPoutineOnFile(lockFile string, verbose bool, strict bool) error { } // Build the Docker command with JSON output for easier parsing - // docker run --rm -v "$(pwd)":/workdir -w /workdir ghcr.io/boostsecurityio/poutine:latest analyze_local . --format json + // docker run --rm -v "$(pwd)":/workdir -w /workdir analyze_local . --format json // #nosec G204 -- gitRoot comes from git rev-parse (trusted source) and is validated as absolute path // exec.Command with separate args (not shell execution) prevents command injection volumeMount, err := buildDockerVolumeMount(gitRoot, "/workdir") @@ -232,7 +232,7 @@ func runPoutineOnFile(lockFile string, verbose bool, strict bool) error { "--rm", "-v", volumeMount, "-w", "/workdir", - "ghcr.io/boostsecurityio/poutine:latest", + PoutineImage, "analyze_local", ".", "--format", "json", @@ -250,7 +250,7 @@ func runPoutineOnFile(lockFile string, verbose bool, strict bool) error { "--rm", "-v", volumeMount, "-w", "/workdir", - "ghcr.io/boostsecurityio/poutine:latest", + PoutineImage, "analyze_local", ".", "--format", "json", diff --git a/pkg/cli/poutine_test.go b/pkg/cli/poutine_test.go index fbcb7ea11d7..c567dc0d236 100644 --- a/pkg/cli/poutine_test.go +++ b/pkg/cli/poutine_test.go @@ -360,3 +360,12 @@ func TestEnsurePoutineConfig(t *testing.T) { } }) } + +func TestPoutineImageIsPinnedByDigest(t *testing.T) { + if _, err := validateDockerImageRef(PoutineImage); err != nil { + t.Fatalf("PoutineImage %q failed docker image reference validation: %v", PoutineImage, err) + } + if !strings.Contains(PoutineImage, "@sha256:") { + t.Errorf("PoutineImage must be pinned by digest, got %q", PoutineImage) + } +}