Skip to content

Harden CI supply chain: pin actions, drop stray id-token, add CODEOWNERS - #393

Merged
stbenjam merged 4 commits into
mainfrom
harden-ci-supply-chain
Jul 6, 2026
Merged

stbenjam merged 4 commits into
mainfrom
harden-ci-supply-chain

Conversation

@stbenjam

@stbenjam stbenjam commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Security hardening for the GitHub Actions footprint, from an audit of the
write-token surface. No behavior change — same actions, same versions,
same jobs; only how they're referenced and scoped.

What & why

SHA-pin every action. All third-party and first-party uses: are now
pinned to a full 40-char commit SHA with a # vX comment. A floating tag or
branch can be silently repointed to attacker code that runs with the
workflow's token. Highest-value pins (write scope + secrets, previously on
mutable refs):

  • anthropics/claude-code-action — was @v1 (mutable tag)
  • pypa/gh-action-pypi-publish — was @release/v1 (mutable branch), on the PyPI publish job

security-scan.yml/codeql were already SHA-pinned and are untouched. The
generated issue-triage.lock.yml is intentionally not hand-edited (regenerate
via gh aw compile if its pins need bumping).

Drop unnecessary id-token: write. Removed from the five LLM agent jobs
(issue-solver, pr-review, maintenance, ecosystem-scout, review-panel)
— none publish via OIDC, so the scope was over-provisioned. It now survives
only in release.yml (PyPI trusted publishing) and pages.yml (Pages deploy),
where OIDC is actually used.

Add CODEOWNERS. @stbenjam as default owner, with explicit ownership on
the write-token surface (.github/, action.yml, review/) and supply-chain
paths (release.yml, pyproject.toml, requirements*).

Not in this PR — repo settings you still need to click

CODEOWNERS is inert until main requires ≥1 approving review and
"Require review from Code Owners" is enabled. Today main requires 0
approvals, which means an agent with contents: write can merge a green PR
with no human sign-off. Also recommend adding a required reviewer to the
pypi environment (currently no protection rules) so every publish needs
explicit approval. These are account settings, not files.

🤖 Generated with Claude Code


Open in Devin Review

Summary by CodeRabbit

  • Chores
    • Strengthened repository automation by adding ownership rules for the full repository path set.
    • Improved CI/CD reliability by pinning GitHub Actions to fixed revisions across testing, security scanning, releases, docs publishing, and maintenance workflows.
    • Tightened automation security by removing elevated token permissions from pull request review and related workflows.

Security hardening for the GitHub Actions footprint. No behavior change to
any workflow — same actions, same versions, same jobs.

- SHA-pin every third-party and first-party action to a full commit SHA
  (with a `# vX` comment) across all workflows. Most important: the two
  that previously floated on mutable refs and carry write scope/secrets —
  anthropics/claude-code-action (@v1 tag) and pypa/gh-action-pypi-publish
  (@release/v1 *branch*). Leaves the already-pinned security-scan.yml and
  the generated issue-triage.lock.yml alone.

- Remove `id-token: write` from the five LLM agent jobs (issue-solver,
  pr-review, maintenance, ecosystem-scout, review-panel). None of them
  publish via OIDC, so the scope was unnecessary. It now remains only in
  release.yml (PyPI trusted publishing) and pages.yml (Pages deploy).

- Add .github/CODEOWNERS assigning @stbenjam as default owner with explicit
  ownership on the write-token surface (.github/, action.yml, review/) and
  supply-chain paths (release.yml, pyproject.toml, requirements*). Note it
  only becomes enforcing once main requires >=1 approval and "Require review
  from Code Owners" is enabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@stbenjam, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 04085f73-784c-4544-a44f-7e61fd5d9df5

📥 Commits

Reviewing files that changed from the base of the PR and between fb6fa39 and 0127a35.

📒 Files selected for processing (1)
  • .github/dependabot.yml
📝 Walkthrough

Walkthrough

This PR adds a .github/CODEOWNERS file and updates GitHub Actions workflows to use pinned commit SHAs for third-party actions. It also removes id-token: write from two skillsaw workflows.

Changes

CODEOWNERS and workflow pinning

Layer / File(s) Summary
Add CODEOWNERS file
.github/CODEOWNERS
Adds a wildcard ownership rule for @stbenjam with an inline comment.
Pin actions in core CI/build/release workflows
.github/workflows/codeql.yml, .github/workflows/docker.yml, .github/workflows/pages.yml, .github/workflows/release.yml, .github/workflows/rule-impact.yml, .github/workflows/test.yml
Switches checkout, setup-python, artifact, deployment, code scanning, Codecov, and uv-related steps from version tags to pinned commit SHAs.
Pin actions and tighten permissions in skillsaw workflows
.github/workflows/skillsaw-ecosystem-scout.yml, .github/workflows/skillsaw-issue-solver.yml, .github/workflows/skillsaw-maintenance.yml, .github/workflows/skillsaw-pr-review.yml, .github/workflows/skillsaw-review-panel.yml
Pins checkout, Claude, cache, and artifact steps to commit SHAs and removes id-token: write from two workflows.
Pin actions in test-related workflows
.github/workflows/test-action-review.yml, .github/workflows/test-action.yml, .github/workflows/test-promptfoo-compat.yml
Updates checkout and setup-python references to pinned commit SHAs.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • stbenjam/skillsaw#140: Introduced the actions/checkout step in test-action-review.yml that this PR later pins to a commit SHA.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main CI hardening changes: pinning actions, removing an unnecessary id-token permission, and adding CODEOWNERS.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch harden-ci-supply-chain

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a .github/CODEOWNERS file to define code ownership and review requirements for the repository, assigning @stbenjam as the default owner and the primary reviewer for CI, automation, and release-critical paths. There are no review comments, and I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@codecov-commenter

codecov-commenter commented Jul 6, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.83%. Comparing base (ea979ef) to head (0127a35).
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #393   +/-   ##
=======================================
  Coverage   84.83%   84.83%           
=======================================
  Files         135      135           
  Lines        9943     9943           
=======================================
  Hits         8435     8435           
  Misses       1508     1508           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread .github/workflows/rule-impact.yml Outdated

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5

@devin-ai-integration devin-ai-integration Bot Jul 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: setup-python bumped from v5 to v6 in rule-impact workflow as part of SHA pinning

In .github/workflows/rule-impact.yml:34, actions/setup-python was upgraded from @v5 to @ece7cb06caefa5fff74198d8649806c4678c61a1 # v6. This is the only workflow where the version actually changed (all others were already on v6). This aligns it with the rest of the workflows and is likely intentional, but it's a behavioral change beyond pure SHA pinning — setup-python v6 may have different defaults or behavior.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

- CODEOWNERS: drop the per-path entries, just `* @stbenjam`.
- rule-impact.yml: bump actions/setup-python v5 -> v6 SHA so every
  workflow is on the same version (per Devin review on #393).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 new potential issue.

Open in Devin Review


steps:
- uses: actions/checkout@v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Version comment on actions/checkout SHA may warrant verification

Every workflow pins actions/checkout to SHA 93cb6efe18208431cddfb8368fd83d5badbf9bfd with the comment # v5. Based on older public references, this SHA has been associated with actions/checkout@v4.2.2 rather than v5. If the comment is wrong, the action still works correctly (it just runs v4 instead of v5), but the mislabeled comment could cause confusion during future version audits or Dependabot updates. Worth a quick cross-check against the actions/checkout releases page to confirm the SHA-to-tag mapping.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

stbenjam and others added 2 commits July 6, 2026 07:15
Keeps the SHA-pinned actions patched without PR spam: all GitHub Actions
bumps land in one grouped PR per month (updates both the SHA and the
`# vX` comment), and Python deps in another.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stbenjam
stbenjam merged commit babac37 into main Jul 6, 2026
17 checks passed
stbenjam added a commit that referenced this pull request Jul 22, 2026
#393 removed `id-token: write` from the five claude-code-action jobs on the
grounds that "none of them publish via OIDC". The action does use OIDC: it
exchanges a GitHub OIDC token for its app token as the first thing it does
at startup, so every one of those jobs now aborts before running:

    Requesting OIDC token...
    error: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable
    Could not fetch an OIDC token. Did you remember to add
    `id-token: write` to your workflow permissions?

This went unnoticed because the issue-solver, pr-review and review-panel
jobs gate their claude-code-action step behind an `if:` that has been false
on every scheduled run since. Skillsaw Maintenance is dispatch-only, so its
first manual run after #393 surfaced it (run 29915664997).

Restore the permission on all five, with a comment explaining why it is
needed so it does not get pruned as "stray" again.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stbenjam
stbenjam deleted the harden-ci-supply-chain branch July 27, 2026 20:07
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