From 00c5dc142081a399acb2eaed1d29c264d5855755 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:10:02 +0000 Subject: [PATCH 1/2] Initial plan From f8dabac85a369c134413dc6fe058b0d58acae207 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:35:54 +0000 Subject: [PATCH 2/2] Pin AWF 0.27.0 firewall images Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/actions-lock.json | 20 +++++ pkg/actionpins/data/action_pins.json | 20 +++++ pkg/workflow/data/action_pins.json | 20 +++++ .../docker_firewall_pin_compile_test.go | 82 +++++++++++++++++++ pkg/workflow/docker_pin_test.go | 7 ++ 5 files changed, 149 insertions(+) create mode 100644 pkg/workflow/docker_firewall_pin_compile_test.go diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index d4dfd1be3fe..00c0e66ea18 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -247,6 +247,11 @@ "digest": "sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715", "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.25.67@sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715" }, + "ghcr.io/github/gh-aw-firewall/agent:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0", + "digest": "sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248", + "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0@sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248" + }, "ghcr.io/github/gh-aw-firewall/agent:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.1", "digest": "sha256:55149fa2daf8fa8afa2803f2ac1a3534591a7c96f173ee2aec9545fbe67305df", @@ -292,6 +297,11 @@ "digest": "sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5", "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.67@sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5" }, + "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0", + "digest": "sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb", + "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0@sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb" + }, "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1", "digest": "sha256:2802437f05830336ea3ae8639f628776608d14d95b5b3cf30f161eb505e29752", @@ -327,6 +337,11 @@ "digest": "sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a", "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.67@sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a" }, + "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0", + "digest": "sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d", + "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0@sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d" + }, "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1", "digest": "sha256:2e6dc98321dbf82840f83ec0ef8b198506149255a15d3a7854d59c0d34063e27", @@ -372,6 +387,11 @@ "digest": "sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f", "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.25.67@sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f" }, + "ghcr.io/github/gh-aw-firewall/squid:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0", + "digest": "sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6", + "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0@sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6" + }, "ghcr.io/github/gh-aw-firewall/squid:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.1", "digest": "sha256:1f3df3207dc9faa9080088115ca50a5ab0d7a692c61dffa8c8898d0b7b750413", diff --git a/pkg/actionpins/data/action_pins.json b/pkg/actionpins/data/action_pins.json index d4dfd1be3fe..00c0e66ea18 100644 --- a/pkg/actionpins/data/action_pins.json +++ b/pkg/actionpins/data/action_pins.json @@ -247,6 +247,11 @@ "digest": "sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715", "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.25.67@sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715" }, + "ghcr.io/github/gh-aw-firewall/agent:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0", + "digest": "sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248", + "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0@sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248" + }, "ghcr.io/github/gh-aw-firewall/agent:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.1", "digest": "sha256:55149fa2daf8fa8afa2803f2ac1a3534591a7c96f173ee2aec9545fbe67305df", @@ -292,6 +297,11 @@ "digest": "sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5", "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.67@sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5" }, + "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0", + "digest": "sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb", + "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0@sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb" + }, "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1", "digest": "sha256:2802437f05830336ea3ae8639f628776608d14d95b5b3cf30f161eb505e29752", @@ -327,6 +337,11 @@ "digest": "sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a", "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.67@sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a" }, + "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0", + "digest": "sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d", + "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0@sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d" + }, "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1", "digest": "sha256:2e6dc98321dbf82840f83ec0ef8b198506149255a15d3a7854d59c0d34063e27", @@ -372,6 +387,11 @@ "digest": "sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f", "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.25.67@sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f" }, + "ghcr.io/github/gh-aw-firewall/squid:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0", + "digest": "sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6", + "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0@sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6" + }, "ghcr.io/github/gh-aw-firewall/squid:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.1", "digest": "sha256:1f3df3207dc9faa9080088115ca50a5ab0d7a692c61dffa8c8898d0b7b750413", diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index d4dfd1be3fe..00c0e66ea18 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -247,6 +247,11 @@ "digest": "sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715", "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.25.67@sha256:0f54fa48dd1a03ef6d171574eecf9a9edbf0406cea011a534cd12ed1fcb46715" }, + "ghcr.io/github/gh-aw-firewall/agent:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0", + "digest": "sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248", + "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.27.0@sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248" + }, "ghcr.io/github/gh-aw-firewall/agent:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.1", "digest": "sha256:55149fa2daf8fa8afa2803f2ac1a3534591a7c96f173ee2aec9545fbe67305df", @@ -292,6 +297,11 @@ "digest": "sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5", "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.67@sha256:d3f51df1869bda0e1f71ae31a81450641c6ae67404e0769469aae34c2738aeb5" }, + "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0", + "digest": "sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb", + "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0@sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb" + }, "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.1", "digest": "sha256:2802437f05830336ea3ae8639f628776608d14d95b5b3cf30f161eb505e29752", @@ -327,6 +337,11 @@ "digest": "sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a", "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.67@sha256:97387002ec54c8ab9f255d5aaf3d435071642e058f528c8268ca0e80b201609a" }, + "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0", + "digest": "sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d", + "pinned_image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.0@sha256:42529ecb9f90da5adb00593d268dfdbd35d14bb1dc92dd897286b27ce1e3d58d" + }, "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.1", "digest": "sha256:2e6dc98321dbf82840f83ec0ef8b198506149255a15d3a7854d59c0d34063e27", @@ -372,6 +387,11 @@ "digest": "sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f", "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.25.67@sha256:9a05085db054f41bd67c772bcfc25cabc15bc33ee993b051a31e30669dd2031f" }, + "ghcr.io/github/gh-aw-firewall/squid:0.27.0": { + "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0", + "digest": "sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6", + "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.27.0@sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6" + }, "ghcr.io/github/gh-aw-firewall/squid:0.27.1": { "image": "ghcr.io/github/gh-aw-firewall/squid:0.27.1", "digest": "sha256:1f3df3207dc9faa9080088115ca50a5ab0d7a692c61dffa8c8898d0b7b750413", diff --git a/pkg/workflow/docker_firewall_pin_compile_test.go b/pkg/workflow/docker_firewall_pin_compile_test.go new file mode 100644 index 00000000000..9fe014a6332 --- /dev/null +++ b/pkg/workflow/docker_firewall_pin_compile_test.go @@ -0,0 +1,82 @@ +//go:build !integration + +package workflow + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/github/gh-aw/pkg/stringutil" + "github.com/github/gh-aw/pkg/testutil" +) + +func TestCompileWorkflow_FirewallImagesPinnedForAWF0270(t *testing.T) { + frontmatter := `--- +on: workflow_dispatch +engine: claude +sandbox: + agent: + id: awf + version: v0.27.0 +network: + allowed: + - defaults +tools: + web-fetch: +--- + +# Test +Test workflow.` + + tmpDir := testutil.TempDir(t, "docker-firewall-pins-test") + testFile := filepath.Join(tmpDir, "test-workflow.md") + if err := os.WriteFile(testFile, []byte(frontmatter), 0644); err != nil { + t.Fatal(err) + } + + compiler := NewCompiler() + if err := compiler.CompileWorkflow(testFile); err != nil { + t.Fatalf("Failed to compile workflow: %v", err) + } + + lockFile := stringutil.MarkdownToLockFile(testFile) + yaml, err := os.ReadFile(lockFile) + if err != nil { + t.Fatalf("Failed to read lock file: %v", err) + } + + yamlStr := string(yaml) + + expectedPins := map[string]string{ + "ghcr.io/github/gh-aw-firewall/agent:0.27.0": "sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248", + "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0": "sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb", + "ghcr.io/github/gh-aw-firewall/squid:0.27.0": "sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6", + } + + for image, digest := range expectedPins { + pinnedImage := image + "@" + digest + if !strings.Contains(yamlStr, `"image":"`+image+`","digest":"`+digest+`","pinned_image":"`+pinnedImage+`"`) { + t.Errorf("Expected manifest header to include pinned metadata for %s", image) + } + if !strings.Contains(yamlStr, "# - "+pinnedImage) { + t.Errorf("Expected pinned container comment for %s", image) + } + if !strings.Contains(yamlStr, pinnedImage) { + t.Errorf("Expected pinned download reference for %s", image) + } + } + + for _, imageTagPart := range []string{ + `imageTag`, + `0.27.0,`, + `agent=sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248`, + `api-proxy=sha256:f28d2bd3197fb6ef9ec40ef345bbf2bb33e50151a8e72e89abb618fc3d0066eb`, + `squid=sha256:d6a01d4cf3d928e6a7fc42e34afef228e753dce87646edc91d8a5cd0b612d9a6`, + } { + if !strings.Contains(yamlStr, imageTagPart) { + t.Errorf("Expected AWF config JSON to include %s", imageTagPart) + } + } +} diff --git a/pkg/workflow/docker_pin_test.go b/pkg/workflow/docker_pin_test.go index 47a048fb9a3..88f4b77c890 100644 --- a/pkg/workflow/docker_pin_test.go +++ b/pkg/workflow/docker_pin_test.go @@ -34,6 +34,13 @@ func TestApplyContainerPins(t *testing.T) { expectedRefs: []string{"node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}, expectedDigests: []string{"sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}, }, + { + name: "embedded firewall pin used when cache is absent", + images: []string{"ghcr.io/github/gh-aw-firewall/agent:0.27.0"}, + pins: nil, + expectedRefs: []string{"ghcr.io/github/gh-aw-firewall/agent:0.27.0@sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248"}, + expectedDigests: []string{"sha256:3816d1692e6d96887b27f1e4f1d64b8d7edb43ed9d7506b8f203913cbb81c248"}, + }, { name: "pinned image replaced with digest reference", images: []string{"node:lts-alpine"},