Skip to content

Add an org-wide check for locked, exact action refs - #47

Merged
rgarcia merged 2 commits into
mainfrom
hypeship/actions-lock-check
Nov 14, 2026
Merged

rgarcia merged 2 commits into
mainfrom
hypeship/actions-lock-check

Conversation

@rgarcia

@rgarcia rgarcia commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Adds actions-lock-check.yml, a reusable workflow any repo can call on pull requests to enforce the workflow-pinning convention: step-level actions use an exact vX.Y.Z release (or a full SHA only when the commit has no release tag), and actions.lock pins them.

What it checks

  • gh actions-lock --verify-local passes (offline: every ref has a lockfile entry). Online --verify fails on runners because the aquasecurity org has an IP allow list that rejects runner IPs; the runner already rejects a locked commit that isn't reachable from its tag.
  • scripts/action_pins.py (now also a CLI) walks every workflow and in-repo composite action:
    • refs must be an exact tag, a full SHA, $/, ./ or docker://. Floating tags (@v4, @v4.4) and branches fail.
    • a SHA pin of a commit that has a release tag fails, unless the caller passes allow-sha-pins: true (for generator-owned SDK workflows).
    • each workflow with external actions must be onboarded in actions.lock with an entry for that exact ref.
  • Reusable workflow calls (jobs.<id>.uses) aren't covered by lockfiles and are skipped.

The job references no secrets and only has contents: read, because gh-actions-lock is a binary pinned by release tag.

Other changes

  • lock_problem keeps its behaviour for the existing tests; the shared logic moved into ref_problem.
  • semgrep.yml pinned llm-credentials@main to af49085, the commit actions.lock already ran. The lockfile was regenerated from scratch, so the only lock change for existing workflows is that key moving from @main to the SHA (same commit). README examples point at a commit SHA instead of @main.
  • actions-lock-check-self-test.yml runs the unit tests and calls the check on this repo. In this repo the check uses the PR's copy of action_pins.py; callers fetch it from main.

Tested

  • python -m unittest discover -s scripts -p 'test_*.py': 131 pass, including new test_action_pins.py (accepted forms, floating/branch/unlocked/tagged-SHA rejections, allow-sha-pins, onboarding, composite actions).
  • python3 -I scripts/action_pins.py . passes on this repo. Before the fix, running plain gh actions-lock here rewrote the untagged trivy-action SHA to @master, and the check flagged both lines.

Turning it on org-wide needs either a caller workflow per repo or an org ruleset that requires this workflow.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 54ed6cf. Configure here.

Comment thread scripts/action_pins.py
for u in uses:
if problem := ref_problem(u, entries, lock, allow_sha_pins):
problems.append(f"{rel}: {problem}")
return problems

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Local composites outside .github/actions skipped

Medium Severity

repo_problems only opens composite files under .github/actions/**, while ref_problem treats every ./ uses: as local and returns immediately. A workflow can uses: ./some-action whose action.yml pins evil@main, and neither the Python check nor onboarding will see that remote ref.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Keep actions.lock; do not rewrite SHA pins

Reviewed by Cursor Bugbot for commit 54ed6cf. Configure here.

@rgarcia
rgarcia merged commit 612fabd into main Nov 14, 2026
10 checks passed
@rgarcia
rgarcia deleted the hypeship/actions-lock-check branch November 14, 2026 03:21
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.

1 participant