Skip to content

Comments

Refactor Claude Code Review workflow#1257

Merged
sbryngelson merged 1 commit intoMFlowCode:masterfrom
sbryngelson:claude-moderate
Feb 24, 2026
Merged

Refactor Claude Code Review workflow#1257
sbryngelson merged 1 commit intoMFlowCode:masterfrom
sbryngelson:claude-moderate

Conversation

@sbryngelson
Copy link
Member

@sbryngelson sbryngelson commented Feb 24, 2026

CodeAnt-AI Description

Update Claude Code Review workflow: preserve previous comments and restrict allowed CLI actions

What Changed

  • The workflow no longer deletes an existing "Claude Code Review" comment; new runs will post a new comment and include instructions for marking updates
  • Claude is given explicit, narrower command permissions (specific gh api patterns) and a shorter, safer tool set (removed broad gh api, python3, git; added find)
  • Review runner now requires numeric PR commands with --repo, disables the sandbox option, and limits interaction turns to 10
  • If posting a comment is blocked, the action will write the full review to the GitHub Actions job summary

Impact

✅ Preserve prior review comments so past feedback remains visible
✅ Narrower CLI access during reviews reduces risk of broad repository operations
✅ Clearer and more reliable review posting when previous reviews exist

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • Chores
    • Updated internal code review workflow configuration to enhance automation capabilities and improve tooling permissions.

Note: This release contains no user-facing changes. Updates are infrastructure-related adjustments to development processes.

Removed the step to delete prior Claude review comments and updated allowed tools for Claude Code Review.
Copilot AI review requested due to automatic review settings February 24, 2026 03:22
@codeant-ai
Copy link
Contributor

codeant-ai bot commented Feb 24, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Modified .github/workflows/claude-code-review.yml to remove the prior comment deletion step, enable Claude sandbox bypass with max-turns setting, expand allowed gh API tools, introduce Bash tooling, and update prompt guidance requiring numeric PR form with --repo for operations.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow Configuration
.github/workflows/claude-code-review.yml
Removed prior comment deletion step; added Claude sandbox bypass and max-turns settings; expanded gh API command permissions (repos//pulls/, repos//issues//comments); introduced Bash tool set with find; updated prompt guidance to require numeric PR form with --repo flag for pr view/diff/comment operations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

size:M

Poem

🐰 No more old comments clutter the way,
With tools expanded, fresh reviews take flight!
Sandbox bypassed, prompts refined today,
Numeric PRs guide each step just right! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided by the author, missing all required sections from the template. Add a comprehensive description including: a summary of changes and motivation, the issue being fixed (if applicable), type of change, testing details, and relevant checklist items. Refer to the provided template.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Refactor Claude Code Review workflow' accurately reflects the main changes made to the GitHub workflow file, which involve restructuring and improving the Claude Code Review workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@codeant-ai codeant-ai bot added the size:S This PR changes 10-29 lines, ignoring generated files label Feb 24, 2026
@codeant-ai
Copy link
Contributor

codeant-ai bot commented Feb 24, 2026

CodeAnt AI finished reviewing your PR.

@sbryngelson sbryngelson merged commit c0da7ca into MFlowCode:master Feb 24, 2026
19 of 21 checks passed
@sbryngelson sbryngelson deleted the claude-moderate branch February 24, 2026 03:24
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/claude-code-review.yml (1)

18-22: ⚠️ Potential issue | 🔴 Critical

Critical: pull_request_target + fork checkout + --dangerouslyDisableSandbox creates a "pwn request" vulnerability.

This workflow combines three dangerous elements documented by GitHub Security Lab as a high-risk pattern:

  1. pull_request_target trigger — Runs workflows in the context of the base repository with access to secrets and a write-scoped GITHUB_TOKEN. This is by design a privileged execution context.

  2. Checkout of the fork's HEAD (ref: ${{ github.event.pull_request.head.sha }}, lines 18-22) — When combined with pull_request_target, this means untrusted PR code is executed with full access to repository secrets and elevated permissions, enabling token exfiltration or repo takeover.

  3. --dangerouslyDisableSandbox (line 35) — Removes filesystem and network isolation that protects against prompt injection attacks. Even with --allowedTools restrictions, the sandbox was the last OS-level defense.

Attack path: An external contributor opens a PR with embedded prompt-injection payloads in files (e.g., source code or CLAUDE.md). Claude reads them via the allowed cat/find/grep tools, gets manipulated to exfiltrate the GITHUB_TOKEN (which persists to disk in .git/config because persist-credentials: false is not set, defaulting to true), or to post malicious comments using the write-scoped token. The absence of an author-association guard means this runs automatically for all external contributors.

Additional risks:

  • Lines 41-42: gh api repos/*/issues/*/comments:* is an overly broad API wildcard that could allow Claude to operate on comments across multiple repositories.
  • Lines 18-22: No persist-credentials: false means the GITHUB_TOKEN is stored in .git/config, accessible to any code executed during the workflow.
  • No if: condition guards to limit the workflow to trusted contributors.

Recommended mitigations (choose one or a combination):

  • Add persist-credentials: false to the checkout step to prevent token storage on disk.
  • Remove --dangerouslyDisableSandbox — it removes essential protections and was absent in prior versions for good reason.
  • Add an author-association guard so only trusted contributors trigger the privileged steps (e.g., if: github.event.pull_request.author_association == 'OWNER').
  • Split into an unprivileged pull_request workflow (no secrets) for code review, and a privileged workflow_run or manual approval workflow for comment posting.
🛡️ Minimum-impact hardening for the checkout step
       - name: Checkout PR head (fork)
         uses: actions/checkout@v4
         with:
           ref: ${{ github.event.pull_request.head.sha }}
           fetch-depth: 1
+          persist-credentials: false
🛡️ Remove the sandbox bypass from claude_args
           claude_args: >
-            --dangerouslyDisableSandbox
-            --max-turns 10
+            --max-turns 10
             --allowedTools
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 18 - 22, The workflow
currently checks out the fork's HEAD (ref: ${{
github.event.pull_request.head.sha }}) under a privileged pull_request_target
context and disables sandboxing via the claude_args flag
(--dangerouslyDisableSandbox), creating a token-exfiltration vulnerability; to
fix, change the checkout step to set persist-credentials: false to prevent
GITHUB_TOKEN from being written to .git/config, remove the
--dangerouslyDisableSandbox flag from claude_args, and add an author-association
guard (e.g., if: github.event.pull_request.author_association == 'OWNER' or
restrict to trusted associations) or split into an unprivileged pull_request
workflow and a separate privileged workflow for posting comments; also narrow
the gh api wildcard (gh api repos/*/issues/*/comments:*) to the specific
repo/issue endpoints the workflow must use.
🧹 Nitpick comments (2)
.github/workflows/claude-code-review.yml (2)

63-74: Comment accumulation: prompt-based deduplication is less reliable than the removed programmatic cleanup.

Without the prior-comment deletion step, every synchronize push creates a new comment instead of updating the existing one. The prompt instructs Claude to detect a prior comment and post "Claude Code Review (updated)", but this relies on Claude consistently reasoning about prior comments — which is not guaranteed across different model versions or context sizes.

On an actively reviewed PR this will accumulate multiple review comments per push. Consider reinstating the programmatic deletion step (or using the gh api to find and delete/update the previous comment before posting the new one) rather than depending on a prompt instruction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 63 - 74, The workflow
currently relies on the model prompt to avoid duplicate comments which can cause
repeated PR comments on each synchronize event; update the workflow step that
posts the PR comment (the step that posts "Claude Code Review") to
programmatically find and delete or update the prior comment before posting the
new one (for example: add a step that uses the GitHub REST API or gh api to
search for a prior comment by title/body and delete or PATCH it), or implement a
dedicated “find-and-update” action prior to the post step so the existing
comment is replaced instead of a new one being created.

26-32: Pin claude-code-action to a commit SHA to prevent supply-chain drift.

anthropics/claude-code-action@v1 is a mutable tag that can be moved at any time by the maintainer or attacker with repository access. When the tag is moved, the next workflow run silently picks up whatever code it points to—including the plugin fetched at runtime. Combined with this workflow's elevated privileges (CLAUDE_CODE_OAUTH_TOKEN + pull-requests: write) and the --dangerouslyDisableSandbox flag, a silently-updated action is a significant supply-chain target.

Use the commit SHA 1e78a9a73ab1efa7590f5c777b2ffe9d32084ef9 (current v1 HEAD) or verify the latest:

-        uses: anthropics/claude-code-action@v1
+        uses: anthropics/claude-code-action@1e78a9a73ab1efa7590f5c777b2ffe9d32084ef9
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 26 - 32, Replace the
mutable tag anthropics/claude-code-action@v1 with the specific commit SHA to
prevent supply-chain drift: change the uses reference to
anthropics/claude-code-action@1e78a9a73ab1efa7590f5c777b2ffe9d32084ef9 (the
current v1 HEAD) and keep the existing inputs (claude_code_oauth_token,
github_token, plugin_marketplaces, plugins) unchanged; ensure the uses line in
the workflow is the only change so the action is pinned to that exact commit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/claude-code-review.yml:
- Around line 41-42: The workflow exposes an overly broad gh api pattern
"Bash(gh api repos/*/issues/*/comments:*)" which permits arbitrary writes to
issue comments; tighten or remove it—either delete that pattern (since the
existing "gh pr comment" tool already handles posting PR comments) or replace it
with a method- and scope-restricted pattern that only allows POST to issue
comments for the specific repo, and likewise restrict "Bash(gh api
repos/*/pulls/*:*)" to only allow GET on pull requests (or target the specific
:owner/:repo) so the tools only permit the minimal required API verbs and
repository scope.

---

Outside diff comments:
In @.github/workflows/claude-code-review.yml:
- Around line 18-22: The workflow currently checks out the fork's HEAD (ref: ${{
github.event.pull_request.head.sha }}) under a privileged pull_request_target
context and disables sandboxing via the claude_args flag
(--dangerouslyDisableSandbox), creating a token-exfiltration vulnerability; to
fix, change the checkout step to set persist-credentials: false to prevent
GITHUB_TOKEN from being written to .git/config, remove the
--dangerouslyDisableSandbox flag from claude_args, and add an author-association
guard (e.g., if: github.event.pull_request.author_association == 'OWNER' or
restrict to trusted associations) or split into an unprivileged pull_request
workflow and a separate privileged workflow for posting comments; also narrow
the gh api wildcard (gh api repos/*/issues/*/comments:*) to the specific
repo/issue endpoints the workflow must use.

---

Nitpick comments:
In @.github/workflows/claude-code-review.yml:
- Around line 63-74: The workflow currently relies on the model prompt to avoid
duplicate comments which can cause repeated PR comments on each synchronize
event; update the workflow step that posts the PR comment (the step that posts
"Claude Code Review") to programmatically find and delete or update the prior
comment before posting the new one (for example: add a step that uses the GitHub
REST API or gh api to search for a prior comment by title/body and delete or
PATCH it), or implement a dedicated “find-and-update” action prior to the post
step so the existing comment is replaced instead of a new one being created.
- Around line 26-32: Replace the mutable tag anthropics/claude-code-action@v1
with the specific commit SHA to prevent supply-chain drift: change the uses
reference to
anthropics/claude-code-action@1e78a9a73ab1efa7590f5c777b2ffe9d32084ef9 (the
current v1 HEAD) and keep the existing inputs (claude_code_oauth_token,
github_token, plugin_marketplaces, plugins) unchanged; ensure the uses line in
the workflow is the only change so the action is pinned to that exact commit.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b528867 and 1c1fd61.

📒 Files selected for processing (1)
  • .github/workflows/claude-code-review.yml

Comment on lines +41 to +42
"Bash(gh api repos/*/pulls/*:*)"
"Bash(gh api repos/*/issues/*/comments:*)"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's find and examine the workflow file
fd "claude-code-review.yml" --type f

Repository: MFlowCode/MFC

Length of output: 39


🏁 Script executed:

#!/bin/bash
# Examine the workflow file around lines 41-42
cat -n ".github/workflows/claude-code-review.yml" | sed -n '30,55p'

Repository: MFlowCode/MFC

Length of output: 1296


🏁 Script executed:

#!/bin/bash
# Search for information about claude-code-action and how allowed-tool patterns work
rg -i "allowedTools|allowed-tool|gh api" --type yaml -A 2 -B 2

Repository: MFlowCode/MFC

Length of output: 39


🏁 Script executed:

#!/bin/bash
# Check if there's documentation or configuration for the claude-code-action
fd "claude-code-action" -o -name "action.yml" -o -name "action.yaml" | head -20

Repository: MFlowCode/MFC

Length of output: 287


🌐 Web query:

claude-code-action allowed-tool gh api syntax :*

💡 Result:

In Claude Code Action, allowed_tools uses Claude Code’s --allowedTools pattern syntax: for Bash commands you generally want the colon + wildcard form Bash(<prefix>:*) (not Bash(<prefix> *)). (skills.sh)

So to allow GitHub CLI gh api calls, use e.g.:

- uses: anthropics/claude-code-action@beta
  with:
    allowed_tools: |
      Bash(gh api:*)

(github.com)

If you want to be more restrictive (recommended), allow only specific methods/flags, for example:

allowed_tools: |
  Bash(gh api --method GET:*)
  Bash(gh api --method POST:*)

(Example of this same pattern style for gh api appears in real-world configs/documentation.) (docs.rs)

Citations:


🏁 Script executed:

#!/bin/bash
# Search for any documentation or README in the repo that might explain the allowed-tool syntax
fd -e md -e txt | xargs rg -l "allowedTools|allowed-tool|gh api" 2>/dev/null || true

Repository: MFlowCode/MFC

Length of output: 39


🏁 Script executed:

#!/bin/bash
# Check if there are any comments in the workflow file explaining the syntax
cat -n ".github/workflows/claude-code-review.yml" | head -60

Repository: MFlowCode/MFC

Length of output: 2566


Overly broad gh api tool patterns could permit write operations on arbitrary issue comments.

"Bash(gh api repos/*/issues/*/comments:*)" allows Claude to call any gh api method on issue comments across all repos accessible by the token. This is broader than needed for posting a single PR comment.

The gh pr comment tool (line 40) already covers posting PR comments. If the gh api endpoint is still needed for specific cases, the patterns can be tightened to restrict both the scope and methods:

🔒 Restrict the API tool patterns to specific methods
-            "Bash(gh api repos/*/pulls/*:*)"
-            "Bash(gh api repos/*/issues/*/comments:*)"
+            "Bash(gh api --method GET repos/*/pulls/*:*)"
+            "Bash(gh api --method POST repos/*/issues/*/comments:*)"

This limits operations to GET on pull requests and POST on issue comments, reducing the blast radius from prompt injection.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Bash(gh api repos/*/pulls/*:*)"
"Bash(gh api repos/*/issues/*/comments:*)"
"Bash(gh api --method GET repos/*/pulls/*:*)"
"Bash(gh api --method POST repos/*/issues/*/comments:*)"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 41 - 42, The workflow
exposes an overly broad gh api pattern "Bash(gh api
repos/*/issues/*/comments:*)" which permits arbitrary writes to issue comments;
tighten or remove it—either delete that pattern (since the existing "gh pr
comment" tool already handles posting PR comments) or replace it with a method-
and scope-restricted pattern that only allows POST to issue comments for the
specific repo, and likewise restrict "Bash(gh api repos/*/pulls/*:*)" to only
allow GET on pull requests (or target the specific :owner/:repo) so the tools
only permit the minimal required API verbs and repository scope.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors the Claude Code Review GitHub Actions workflow by simplifying rerun behavior and tightening/adjusting the tool allowlist while adding additional execution flags for the Claude action.

Changes:

  • Removed the step that deleted a prior “Claude Code Review” PR comment before running.
  • Added --dangerouslyDisableSandbox and set --max-turns 10 for the Claude run.
  • Narrowed gh api allowlist from gh api:* to specific endpoint patterns and added guidance to use --repo with numeric PR commands.

plugins: 'code-review@claude-code-plugins'

claude_args: >
--dangerouslyDisableSandbox
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Using --dangerouslyDisableSandbox meaningfully increases the blast radius if the model is ever tricked into executing unsafe operations (especially with Bash(...) tools enabled). Prefer keeping the sandbox enabled; if disabling is truly required, add compensating controls (e.g., restrict workflow execution to trusted actors/branches, minimize GITHUB_TOKEN permissions, and further constrain allowed tools/commands) and document why sandboxing can’t be used here.

Suggested change
--dangerouslyDisableSandbox

Copilot uses AI. Check for mistakes.
"Bash(gh api:*)"
"Bash(gh search code:*)"
"Bash(gh api repos/*/pulls/*:*)"
"Bash(gh api repos/*/issues/*/comments:*)"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The gh api ...:* patterns still allow arbitrary arguments/methods against these endpoints (including destructive methods like DELETE where applicable, and broad query construction). To reduce risk, constrain these to the minimal set of operations needed (e.g., only GET for reading PR metadata/diff, and only the specific POST needed for commenting), or remove gh api entirely if gh pr comment/view/diff cover the required behavior.

Suggested change
"Bash(gh api repos/*/issues/*/comments:*)"

Copilot uses AI. Check for mistakes.
Comment on lines 20 to 24
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 1

- name: Remove prior Claude review comment (so review runs again)
env:
GH_TOKEN: ${{ github.token }}
run: |
pr=${{ github.event.pull_request.number }}
repo=${{ github.repository }}

# Find first issue comment whose body starts with "## Claude Code Review"
comment_id=$(gh api repos/$repo/issues/$pr/comments \
--jq '.[] | select(.body | startswith("## Claude Code Review")) | .id' | head -n 1)

if [ -n "$comment_id" ]; then
echo "Deleting prior Claude review comment id=$comment_id"
gh api -X DELETE repos/$repo/issues/comments/$comment_id
else
echo "No prior Claude review comment found."
fi


- name: Run Claude Code Review
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This removes the prior idempotency step that deleted the existing 'Claude Code Review' comment before running. That can lead to clutter across reruns (multiple top-level reviews) and makes the workflow behavior dependent on how the action posts comments. Consider restoring idempotent behavior by updating/editing an existing comment (preferred) or deleting the prior one before posting a new single top-level review.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files

Development

Successfully merging this pull request may close these issues.

1 participant