Summary
Compiling with gh aw v0.79.4 produces .lock.yml files where the three
firewall sidecar images are referenced by mutable tag only, while every other
container is digest-pinned:
ghcr.io/github/gh-aw-firewall/agent:0.27.0 ← tag only
ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0 ← tag only
ghcr.io/github/gh-aw-firewall/squid:0.27.0 ← tag only
ghcr.io/github/gh-aw-mcpg:... ← @sha256: pinned
ghcr.io/github/github-mcp-server:... ← @sha256: pinned
node:lts-alpine ← @sha256: pinned
This was previously addressed for all six images by #25071 / #27715, and the
v0.77.5 regression in #36579 restored pinning for gh-aw-mcpg and
github-mcp-server — but not for the three gh-aw-firewall/* images. They
remain tag-only on v0.79.4.
Environment
- gh aw v0.79.4 (via SHA-pinned
github/gh-aw-actions/setup@v0.79.4)
- AWF v0.27.0, engine info 1.0.60
- Strict mode (default), action SHA pinning intact
Expected
The three gh-aw-firewall/* images are emitted as image:tag@sha256:<digest>
everywhere they appear (download step, docker run, manifest comment), matching
the treatment of gh-aw-mcpg, github-mcp-server, and node:lts-alpine.
Actual
The firewall images are emitted as bare image:tag. Recompiling on a
Docker-capable host with gh aw compile --validate-images produces
byte-identical, tag-only firewall references; --validate-images only confirms
pullability and does not embed digests. No compile flag restores firewall
digest pinning.
Likely cause
In pkg/workflow/docker.go, collectDockerImages adds the firewall images by
bare tag, and applyContainerPins only substitutes @sha256: for images that
have an entry in the action cache (actions-lock.json containers) or embedded
pins. v0.79.4 ships pins for gh-aw-mcpg, github-mcp-server, and node but
not for the gh-aw-firewall/* images, so they pass through unpinned. The
firewall pinning helpers already exist
(buildAWFImageTagWithDigests / lookupContainerDigest cover
squid/agent/api-proxy/cli-proxy) — they are simply unpopulated for these images.
Impact
Supply-chain / reproducibility: a re-push to a mutable 0.27.0 tag would
silently propagate to consumers on the next run. The firewall containers sit on
the network-enforcement boundary, so this is the same defense-in-depth concern
raised in #25071.
References
Summary
Compiling with gh aw v0.79.4 produces
.lock.ymlfiles where the threefirewall sidecar images are referenced by mutable tag only, while every other
container is digest-pinned:
ghcr.io/github/gh-aw-firewall/agent:0.27.0← tag onlyghcr.io/github/gh-aw-firewall/api-proxy:0.27.0← tag onlyghcr.io/github/gh-aw-firewall/squid:0.27.0← tag onlyghcr.io/github/gh-aw-mcpg:...← @sha256: pinnedghcr.io/github/github-mcp-server:...← @sha256: pinnednode:lts-alpine← @sha256: pinnedThis was previously addressed for all six images by #25071 / #27715, and the
v0.77.5 regression in #36579 restored pinning for
gh-aw-mcpgandgithub-mcp-server— but not for the threegh-aw-firewall/*images. Theyremain tag-only on v0.79.4.
Environment
github/gh-aw-actions/setup@v0.79.4)Expected
The three
gh-aw-firewall/*images are emitted asimage:tag@sha256:<digest>everywhere they appear (download step, docker run, manifest comment), matching
the treatment of
gh-aw-mcpg,github-mcp-server, andnode:lts-alpine.Actual
The firewall images are emitted as bare
image:tag. Recompiling on aDocker-capable host with
gh aw compile --validate-imagesproducesbyte-identical, tag-only firewall references;
--validate-imagesonly confirmspullability and does not embed digests. No compile flag restores firewall
digest pinning.
Likely cause
In
pkg/workflow/docker.go,collectDockerImagesadds the firewall images bybare tag, and
applyContainerPinsonly substitutes@sha256:for images thathave an entry in the action cache (
actions-lock.jsoncontainers) or embeddedpins. v0.79.4 ships pins for
gh-aw-mcpg,github-mcp-server, andnodebutnot for the
gh-aw-firewall/*images, so they pass through unpinned. Thefirewall pinning helpers already exist
(
buildAWFImageTagWithDigests/lookupContainerDigestcoversquid/agent/api-proxy/cli-proxy) — they are simply unpopulated for these images.
Impact
Supply-chain / reproducibility: a re-push to a mutable
0.27.0tag wouldsilently propagate to consumers on the next run. The firewall containers sit on
the network-enforcement boundary, so this is the same defense-in-depth concern
raised in #25071.
References
node:lts-alpineuses floating LTS tag #25071, Feature request: pin container images by digest in compiled lock files #27715 — original digest-pinning feature (covered firewall images)