Repository navigation
fix(runner-policy): auto-approve only ci-workflows release commits - #883
Conversation
GitHub resolves a commit SHA from anywhere in a repository's fork network, so a surface-matching fork-only or unreleased commit was auto-approved. Auto-approval now also requires the candidate to be the commit of an immutable, published, non-prerelease release tag (annotated tags peeled), and declines when the tag or release lookup fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DpzEJAE4EMndcWQXiKSZYn
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Incremental security review of The change is documentation only. It records a new requirement for auto-approving a Dependabot SHA bump of a reusable workflow. The candidate SHA must be the commit of an immutable, published, non-prerelease release tag of the source repository. Annotated tags are peeled. Any failed tag or release lookup declines approval. The same change adds a threat-model row for the fork-network or unreleased-SHA attack and notes that auto-approval now also depends on
critical-findings: 0 |
|
claude-review reviewed Incremental review of 230199b (
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 431ffb973d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…eat model Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DpzEJAE4EMndcWQXiKSZYn
Closes #927 ## Summary A contract-only `ci-status` re-run fails closed when GitHub's jobs API lags on re-run jobs, which left a red `ci-status` on heads whose full run passed. ci-workflows v0.69.0 contains the `aggregate-results` fix (ci-workflows#929); this PR adopts it. ## Fix - Re-pin every `melodic-software/ci-workflows/.github/actions/...` pin in `pr-require-checks.yml` and the two `managed-files-guard` caller components to v0.69.0 (`94f22d06b68fcfc0e293122c1cbbb6e0eba11ef3`), using `components/claude-lanes/repin-callers.sh apply`, the script the repin workflow runs. - Pass `step-name: Aggregate lane results` to `aggregate-results`, matching the step's `name:`. - Raise the `ci-status` job `timeout-minutes` from 3 to 8: the action can wait about 337 s, and a job that times out ends `cancelled`, which counts as red. v0.69.0's `action.yml` recommends a calling-job timeout of 7 for this configuration. ## Verification - `actionlint`, `zizmor --offline` on `pr-require-checks.yml`, `npm run lint:runner-policy`, `lint:concurrency-policy`, `lint:github-actions-conventions` and `harness/shell/run-tests.sh components/claude-lanes/repin-callers.test.sh` all pass. - The acceptance re-run of a failed contract-only `ci-status` can only be observed after merge. ## Related - melodic-software/ci-workflows#929, #842, #883, #914 - [ci-workflows v0.69.0](https://github.com/melodic-software/ci-workflows/releases/tag/v0.69.0) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01VcupojYKhHyDni9LuAXBuX Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
No related issue: owner-authorized hardening of runner-policy auto-approval against imposter commits.
Summary
Auto-approval copies a reviewed contract forward onto any full SHA whose security surface matches a reviewed basis. It never checked that the SHA is a real ci-workflows release. GitHub resolves a SHA from anywhere in a repository's fork network, so a fork-only or unreleased commit with a matching surface and malicious steps would be approved. The hosted-only
pr-review-clicontract forwards theREVIEWS_*OAuth tokens and API keys. Background: Chainguard, imposter commits and StepSecurity, triaging imposter commits.Fix
runner-policy.mjs: after every existing decline rule, a candidate is approved only when a tag of its source repository points at it and that tag's release is immutable, published and not a prerelease. It readsGET /repos/{owner}/{repo}/git/matching-refs/tags/, peels annotated tags throughgit/tags/{sha}, then readsreleases/tags/{tag}, all through the existing fetch seam withGITHUB_TOKENwhen set. A non-release commit declines with a diagnostic; any failed request declines (fail closed). A tag with no release (404) is skipped, not treated as a release.immutable, and every recent ci-workflows release has it set. A future release published without immutability will be declined and needs a reviewed contract.fetchGitHubJsonhelper; its error text is unchanged.README.md: one paragraph on the release-commit requirement.Verification
node --test components/runner-policy/runner-policy.test.mjs: 365 of 365 pass (355 before, plus 10 new cases): a lightweight release-tag commit is approved; an annotated tag is peeled and approved; an annotated tag peeling to another commit, a non-release SHA with an identical surface, a tag without a release, and draft, prerelease and non-immutable releases are declined; a 500 from the tag list or the release lookup is declined.immutablecondition, skipping the peel, and treating a 404 release as approved each fail at least one test.node --test components/claude-lanes/repin-policy-lockstep.test.mjs: 23 of 23 pass.npm run lint:runner-policy: passes. Biome check and markdownlint: clean.releases/tags/v0.65.13returnsdraft: false, prerelease: false, immutable: true, a missing tag returns 404, andmatching-refs/tags/returns all 109 ci-workflows tags in one response.Related
ba7af78), the SHA a local probe showed being auto-approved with no token before it was registered.🤖 Generated with Claude Code
https://claude.ai/code/session_01DpzEJAE4EMndcWQXiKSZYn