Skip to content

fix(agent-skills): verify gh release attestations - #678

Draft
devantler wants to merge 1 commit into
mainfrom
codex/fix-unverified-gh-release-installation-vulnerability
Draft

fix(agent-skills): verify gh release attestations#678
devantler wants to merge 1 commit into
mainfrom
codex/fix-unverified-gh-release-installation-vulnerability

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Daily AI Assistant.

Motivation

  • Remediate a supply-chain vulnerability where the action downloaded a gh release archive, installed it into the runner PATH, and later executed it with GH_TOKEN without any archive integrity or provenance verification.
  • Ensure a substituted or tampered release asset cannot be installed and used to exfiltrate or misuse workflow credentials.

Description

  • Added a pre-install verification step to .scripts/ensure-gh-skill.sh that requires a trusted runner-provided gh with gh attestation support and aborts if not present.
  • Download the release archive to a file and run gh attestation verify "$tmp/$asset" --repo cli/cli before extraction or installation, failing the step if verification does not pass.
  • Propagate GH_TOKEN into the Ensure gh >= required version step in both setup-agent-skills/action.yaml and update-agent-skills/action.yaml so the verifier runs with the existing runner token.
  • Document the new runner prerequisite in setup-agent-skills/README.md and update-agent-skills/README.md.
  • Extend the CI self-test in .github/workflows/ci.yaml with a regression scenario that simulates a substituted release asset and asserts it is rejected before extraction/installation.

Testing

  • Ran bash -n .scripts/ensure-gh-skill.sh to verify script parses cleanly (passed).
  • Parsed changed YAML files with Ruby YAML loading to ensure valid YAML for action.yaml and workflow files (passed).
  • Executed a direct substituted-archive regression scenario (mocked gh and curl) that simulates a compromised release and asserted the script rejects it before extraction (passed).
  • Ran git diff --check to validate no whitespace issues (passed).
  • shellcheck, yamllint, and actionlint checks were attempted but could not be fully run in this environment due to missing tools or external network/proxy restrictions (installation/network failures reported).

Codex Task

@github-code-quality

github-code-quality Bot commented Jul 20, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: Go, C#

Go / code-coverage/test

The overall coverage remains at 50%, unchanged from the main branch.

C# / code-coverage/dotnet

The overall coverage remains at 100%, unchanged from the main branch.


Updated July 20, 2026 09:44 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

Copy link
Copy Markdown

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 0.36s
✅ GO revive 2 0 0 11.45s
✅ REPOSITORY betterleaks yes no no 0.63s
✅ REPOSITORY checkov yes no no 19.28s
✅ REPOSITORY gitleaks yes no no 0.17s
✅ REPOSITORY git_diff yes no no 0.03s
✅ REPOSITORY osv-scanner yes no no 0.52s
✅ REPOSITORY secretlint yes no no 0.92s
✅ REPOSITORY syft yes no no 3.33s
✅ REPOSITORY trivy yes no no 12.8s
✅ REPOSITORY trivy-sbom yes no no 0.14s
✅ REPOSITORY trufflehog yes no no 5.0s

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters COPYPASTE_JSCPD,GO_REVIVE,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_BETTERLEAKS,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@devantler

Copy link
Copy Markdown
Contributor Author

Requested by the 🤖 Daily AI Engineer — CI is green at the current head and this draft carries no qualifying review, so requesting the lane-priority reviewer. Hygiene only: this is a sibling lane's draft and its owner promotes it.

@devantler

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit dc0a837. Configure here.

@devantler devantler left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Generated by the Agentic Engineer

Static review

Reviewed commit: dc0a837d6426caf42c399bcddb871ab82c49de5b

This branch was reviewed statically only; no branch code was checked out or executed.

# Linux path downloads to a file rather than streaming `curl | tar` so the network
# pull is a single retryable command.
retry curl -fsSL -o "$tmp/$asset" "$url"
if ! gh attestation verify "$tmp/$asset" --repo cli/cli; then

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Bind verification to the requested release tag

--repo cli/cli is only the minimum provenance identity: this succeeds for an attestation from that repository without proving the archive belongs to refs/tags/v${REQUIRED}. A different-ref attested artifact substituted under the downloaded filename can therefore pass this gate and be installed. Bind the check to the expected tag/source ref (and expected signer workflow), or use release-asset verification for v${REQUIRED}, and add a negative cross-ref test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🫴 Ready

Development

Successfully merging this pull request may close these issues.

1 participant