Add artifact attestations for GHCR CI images
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Summary
GStack publishes/reuses GitHub Container Registry CI images, but the image-producing workflows do not generate GitHub artifact attestations. That leaves maintainers without a first-party provenance record tying `ghcr.io/garrytan/gstack/ci:*` images back to the workflow run, commit, and build inputs that produced them.
GitHub's artifact attestation flow is designed for this exact build-provenance gap: GitHub Actions can generate attestations for binaries and container images, and the action requires explicit OIDC/attestation permissions (`id-token: write`, `attestations: write`).
## Repo-local evidence
- `origin/main:.github/workflows/ci-image.yml` builds and pushes the reusable CI image:
- `packages: write` at line 21
- `docker/build-push-action@v6` at line 34
- `push: true` at line 38
- tags `ghcr.io/${{ github.repository }}/ci:latest` and `ghcr.io/${{ github.repository }}/ci:${{ github.sha }}` at lines 40-41
- `origin/main:.github/workflows/evals.yml` and `origin/main:.github/workflows/evals-periodic.yml` can also build/push the cached eval image when it is missing:
- `packages: write` at line 21 in both workflows
- `docker/build-push-action@v6` at line 49 in both workflows
- `push: true` at line 53 in both workflows
- Repo grep found no artifact-attestation wiring in the current default branch:
- `git grep -n -E 'attest-build-provenance|artifact attestation|attestation|provenance|id-token: write|attestations: write' origin/main -- .github package.json bun.lock README.md CONTRIBUTING.md docs`
- Only unrelated design-doc uses of the word `provenance` were returned.
- The existing security backlog already covers adjacent checks, not this one:
- #1948 covers mutable third-party action tags and secret-bearing PR evals.
- #1987 covers dependency-review gating.
- #1997 covers OpenSSF Scorecard visibility.
None of those asks for GHCR image artifact attestations.
## Expected impact
- Maintainers can verify that CI images consumed by eval jobs were built by this repo's GitHub Actions workflow from the expected commit.
- Raises the bar against CI-image substitution/poisoning, especially because the eval workflows run tests inside `ghcr.io/${{ github.repository }}/ci:*` containers.
- Complements #1948's action-pinning work: pinning reduces supply-chain drift; attestations give consumers provenance for what was actually built.
## Suggested fix
Add artifact attestation to image-producing workflows, starting with `.github/workflows/ci-image.yml` and then mirroring into the on-demand image build path in `evals.yml` / `evals-periodic.yml` if maintainers want those images attested too.
Concrete shape:
1. Add least-privilege attestation permissions to the image build job:
```yaml
permissions:
contents: read
packages: write
id-token: write
attestations: write
```
2. Give `docker/build-push-action` an `id` so the pushed digest can be referenced.
3. Add `actions/attest-build-provenance` after the push, pinned to a full commit SHA in the same style requested by #1948, with `subject-name: ghcr.io/${{ github.repository }}/ci` and `subject-digest` from the build step.
4. Keep it non-blocking only if the repository plan/permissions do not support attestations yet; otherwise fail the image build if provenance generation fails.
## Duplicate check performed
- Inspected 200 open issues with:
- `gh issue list -R garrytan/gstack --state open --limit 200 --json number,title,body,url,labels,createdAt,updatedAt`
- Inspected 200 open PRs with:
- `gh pr list -R garrytan/gstack --state open --limit 200 --json number,title,body,url,labels,createdAt,updatedAt,isDraft,headRefName,baseRefName`
- Searched the inspected open issue/PR title+body set for:
- `attestation`, `provenance`, `SLSA`, `artifact integrity`, `attest-build-provenance`, `build provenance`
- `ghcr`, `ci image`, `container image`, `docker/build`, `packages: write`
- `id-token`, `OIDC`, `OpenID Connect`
- Ran targeted GitHub issue/PR searches with `gh search issues --repo garrytan/gstack` for:
- `artifact attestation`
- `attest-build-provenance`
- `build provenance`
- `ghcr provenance`
- `container image attestation`
- `id-token attestations`
- `artifact integrity`
- Adjacent hits found: #1948, #1987, #1997. No open issue or PR specifically requests artifact attestations for the GHCR CI image.
## Commands/files inspected
- `README.md`
- `CONTRIBUTING.md`
- `docs/ADDING_A_HOST.md`
- `docs/OPENCLAW.md`
- `.github/workflows/skill-docs.yml`
- `.github/workflows/evals.yml`
- `.github/workflows/evals-periodic.yml`
- `.github/workflows/ci-image.yml`
- `.github/workflows/actionlint.yml`
- `package.json`
- Recent merged PRs by title/body/files: #1990, #1966, #1951, #1929, #1916, #1912, #1911, #1910, #1909, #1908
- `git fetch origin main --prune`
- `git ls-tree -r --name-only origin/main .github/workflows`
- `git grep -n -E 'attest-build-provenance|artifact attestation|attestation|provenance|id-token: write|attestations: write|dependency-review|osv-scanner|semgrep|ossf/scorecard|scorecard-action|codeql-action' origin/main -- .github package.json bun.lock README.md CONTRIBUTING.md docs`
- `git grep -n -E 'packages: write|docker/build-push-action|push: true|ghcr.io|IMAGE:' origin/main -- .github/workflows`
- GitHub docs checked: `Using artifact attestations to establish provenance for builds`, `actions/attest-build-provenance`
Contributor guide
Assessment
This issue has not been assessed yet.