Skip to content

AWF runtime container images use mutable version tags without SHA digest pinning — supply chain integrity gap relative to SHA-pi [Content truncated due to length] #2026

@szabta89

Description

@szabta89

Summary

The github/gh-aw-actions/setup action is SHA-pinned (@2fe53acc...) to provide code integrity guarantees, but the four AWF runtime containers it pulls — squid, agent, iptables-init, and api-proxy — are referenced only by semver tag (ghcr.io/github/gh-aw-firewall/*:0.25.18), with no @sha256: digest appended. This creates an integrity asymmetry: the orchestrating code is verified, but the images it pulls are not. If any tag is moved — via registry compromise, insider action, or a publishing error — subsequent workflow runs would execute unverified container content while the pinned setup action continues to pass its integrity check.

The infrastructure for digest pinning already exists: download_docker_images.sh handles image:tag@sha256:... references correctly, and action_pins.json already pins third-party Docker MCP images by digest. The gap is that AWF's own containers are not included in this pattern.

Affected Area

AWF container supply-chain boundary — trust between the ghcr.io/github/gh-aw-firewall registry and the AWF runtime execution environment (firewall containers managed by docker-compose).

Reproduction Outline

  1. Run any gh-aw workflow using the Claude engine (version v0.68.1 / AWF v0.25.18).
  2. Inspect the generated docker-compose.redacted.yml in /tmp/gh-aw/sandbox/firewall/audit/.
  3. Observe all four service image references use mutable tags: ghcr.io/github/gh-aw-firewall/<service>:0.25.18 — no @sha256: digest.
  4. Contrast with the lock file, which shows github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc (SHA-pinned).
  5. (Theoretical exploit) Push a replacement image to any of those tags in the registry; the next workflow run pulls the replaced image without detection.

Observed Behavior

All four AWF containers (squid, agent, iptables-init, api-proxy) are pulled by mutable version tag. No digest is verified at pull time. A tag overwrite in the registry would silently replace the container content executed on subsequent runs.

Expected Behavior

Each container image reference in the generated docker-compose should include an @sha256:<digest> suffix. The setup action (or the --image-tag value passed to the awf binary in firewall.go:getAWFImageTag) should embed or verify expected digests, consistent with the existing pattern in action_pins.json for third-party MCP images.

Security Relevance

If the awf-agent container image were replaced, the MCP gateway process running inside it (reachable at host.docker.internal:80) would be attacker-controlled. Exploitation requires write access to ghcr.io/github/gh-aw-firewall (registry compromise, insider threat, or a compromised AWF image build pipeline), but digest pinning is a low-cost, standard mitigation that eliminates this entire class of risk and is consistent with existing infrastructure in the repository.

Additional Context

If mutable tags are an intentional design choice (e.g., to simplify rollout), that assumption should be explicitly documented — either in the release process or the setup action README — so that the integrity asymmetry with the SHA-pinned setup action is understood to be deliberate rather than an oversight.

gh-aw Version

v0.68.1 (AWF v0.25.18)

Original finding: https://github.com/githubnext/gh-aw-security/issues/1848

Generated by File Issue · ● 242.9K ·

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions