Skip to content

verify-action-build: reject actions that ship pre-compiled binaries#819

Open
potiuk wants to merge 4 commits intoapache:mainfrom
potiuk:reject-in-tree-binaries
Open

verify-action-build: reject actions that ship pre-compiled binaries#819
potiuk wants to merge 4 commits intoapache:mainfrom
potiuk:reject-in-tree-binaries

Conversation

@potiuk
Copy link
Copy Markdown
Member

@potiuk potiuk commented May 7, 2026

Summary

Test plan

  • uv run pytest utils/tests/ — 224/224 (15 new).
  • prek run --all-files clean.
  • Smoke: verify-action-build runs-on/action@e46a3c6d… flags 3 binaries and fails.
  • Smoke: verify-action-build docker/bake-action@a66e1c87… (clean bundled JS action) passes.

Stacked on #807 — this PR edits .claude/skills/analyze-action-pr/SKILL.md which is introduced by #807. Until #807 merges, this PR's diff against main will include #807's commits; once #807 merges, only this PR's content remains.

Generated-by Claude Code.

potiuk added 4 commits May 6, 2026 09:25
Add a repo-scoped Claude Code skill at .claude/skills/analyze-action-pr/
that triages allowlist PRs end-to-end: extract action refs via
verify-action-build --from-pr, classify each finding (pipe-to-shell,
unverified-download, nested-action-issue, verify-script-bug, all-clean),
look up what verification material upstream already publishes, and
draft the right next moves — recommend approval, open an upstream issue
+ ping the PR author, or fix verify-action-build itself with a
regression test.

Includes an "Improve this skill" step so future runs that hit a new
shape (false positive, novel verification mechanism, asset-naming
convention) leave the skill better than they found it: the SKILL.md
grows by a row in the case table or a line in the precedents table,
not by re-deriving the analysis.

The skill encodes shapes recently triaged: PR apache#795 / apache#798 (TS-generic
regex hole), PR apache#802 (carabiner-dev nested install actions), PR apache#803 /
apache#804 (multi-action extraction), PR apache#806 (jbangdev pipe-to-shell).

Replace the broad .claude/ rule in .gitignore with specific entries
for personal state (settings*.json, worktrees/, debug/) so .claude/
itself can host shared assets without leaking per-user files.
Pre-commit on PR apache#807 failed because .claude/skills/analyze-action-pr/
SKILL.md was missing the Apache license header.  The insert-license
hook auto-fixes locally but aborts CI because there's no follow-up
commit to land the change.  Add the header so CI passes.

Document the local pre-commit workflow in AGENTS.md so future agent
runs install prek and run ``prek run --all-files`` before pushing,
catching the same class of bounce locally instead of in CI.
Case E previously read as "the script has a bug" — too narrow.  Real
gaps over the life of verify-action-build include whole-action-type
support (Deno, Dart), new build flows (npm run start, multi-step
Docker), new verification heuristics (sibling sha256sum, JSON data
fetches, *Json helpers), false positives on legitimate inputs
(multi-stage FROM, vendored node_modules), and extraction-shape gaps
(hashes under an existing actions.yml key).

Reword the case E row to cover all of these, and add a sub-table
under step 5/E that lists 15 historical extensions with the PR or
commit that closed each.  The table is the template a future agent
reaches for when "the verdict is wrong but not for a security
reason" — instead of waving the finding off, they can match it to
the closest precedent and propose a similar extension.

Also tighten the steps: name each module under
utils/verify_action_build/ and what it owns (pr_extraction, security,
verification, docker_build, action_ref/release_lookup/github_client),
so picking the right place for the fix isn't a treasure hunt.  Add
an explicit "run prek before push" step pointing at AGENTS.md.
…n-tree

Add `analyze_in_tree_binaries` to flag actions that commit native
binaries (Go cross-compile, .exe/.dll/.so/.dylib/.jar/.wasm, etc.)
directly in their repo and exec them from a small launcher.  The
JS-rebuild check verifies the launcher; the binaries are opaque
executable code that no part of our pipeline can reconcile with
source.  runs-on/[email protected] (apache#809)
is the case in point — ~10 MB of UPX-packed Go binaries run as root.

The check is path-only (cheap, no fetch): known binary extensions
plus the <name>-<os>-<arch>(.exe)? cross-compile suffix.  Add the
new failure path to the verification summary and overall result.

Also document the criterion in the security review checklist and
add case F (in-tree native binaries) + a runs-on/action precedent
to the analyze-action-pr skill.
@potiuk potiuk requested a review from dfoulks1 as a code owner May 7, 2026 16:46
@potiuk potiuk requested review from dave2wave and raboof May 7, 2026 16:46
@dave2wave
Copy link
Copy Markdown
Member

My approval is contingent on @gmcdonald confirming that runs-on has been rejected as a vendor.

If it still needs to be used then I think we will need an allow-list of actions that pass verify. Maybe these are ones we can wildcard.

@potiuk
Copy link
Copy Markdown
Member Author

potiuk commented May 7, 2026

My approval is contingent on @gmcdonald confirming that runs-on has been rejected as a vendor.

If it still needs to be used then I think we will need an allow-list of actions that pass verify. Maybe these are ones we can wildcard.

Note that failing the test does not mean rejection. It just means failing the test. It can still be approved.

@potiuk
Copy link
Copy Markdown
Member Author

potiuk commented May 7, 2026

My approval is contingent on @gmcdonald confirming that runs-on has been rejected as a vendor.

If it still needs to be used then I think we will need an allow-list of actions that pass verify. Maybe these are ones we can wildcard.

Also - if you look there runs-on/action#36 The maintainer had been very responsive and implemented attestation for building those binaries (cc: @ppkarwasz ) - so we still might allow the actions where attestations are present - they do not give us 100% reproducibility - but I think the trust in this case moves from the author to GitHub + review of the build steps. Am I right Piotr?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants