Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/check_review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: 'Check: Code Review'
on:
pull_request_target:
types: [opened, synchronize]
Comment on lines +2 to +4
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 17, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

git ls-files | grep -E "(check_review|\.github)" | head -20

Repository: musescore/MuseScore

Length of output: 761


🏁 Script executed:

cat -n .github/workflows/check_review.yml 2>/dev/null || echo "File not found in standard location"

Repository: musescore/MuseScore

Length of output: 601


🏁 Script executed:

# Check if there are other workflows using similar patterns
grep -r "pull_request:" .github/workflows/ -A 2 | head -40

Repository: musescore/MuseScore

Length of output: 1707


🏁 Script executed:

# Search for any documentation or usage of anthropics/claude-code-action in the repo
rg "anthropics/claude-code-action" -A 3 -B 3

Repository: musescore/MuseScore

Length of output: 45


🏁 Script executed:

# Check if there are any other workflows that handle fork PRs specially
grep -r "pull_request_target" .github/workflows/ || echo "No pull_request_target found"

Repository: musescore/MuseScore

Length of output: 118


🌐 Web query:

GitHub Actions fork pull_request secrets not available documentation

💡 Result:

In GitHub Actions, repository secrets (and organization/environment secrets) are not available to workflows triggered by pull_request events from forked repositories. This is a security feature to prevent malicious actors from accessing secrets via PRs from forks. Official documentation explicitly states: "With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository." (Using secrets in GitHub Actions). Also, "Actions secrets are not passed to workflows that are triggered by a pull request from a fork." (Understanding GitHub secret types). To use secrets in workflows for PRs from forks: - Use the pull_request_target event instead of pull_request. This runs the workflow in the context of the base branch (trusted), providing access to secrets and a read/write GITHUB_TOKEN. - Critical security warning: Do not checkout or execute untrusted code from the PR (e.g., avoid actions/checkout with ref: ${{ github.event.pull_request.head.sha }} unchecked). Use only for safe actions like labeling, commenting, or metadata checks. Always review PR changes, especially to .github/workflows/. For private repositories, repo settings allow limited options like "Send secrets to workflows from pull requests" under Fork pull request workflows (requires org/repo admin), but this is not recommended for public repos and still has risks. GITHUB_TOKEN is always available but read-only for pull_request from forks. Primary docs: - https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions (Result 6) - https://docs.github.com/en/code-security/getting-started/understanding-github-secret-types (Result 19) - https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository (Result 10)

Citations:


🌐 Web query:

anthropics claude-code-action requirements checkout permissions

💡 Result:

Anthropic's claude-code-action is a GitHub Action for integrating Claude Code into GitHub workflows, enabling AI-powered code reviews, edits, and automation on PRs and issues via @claude mentions. Requirements: - Repository admin access. - Anthropic API key (ANTHROPIC_API_KEY) or Claude Code OAuth token (CLAUDE_CODE_OAUTH_TOKEN) as repo secret. - actions/checkout@v4 step in workflow to check out repository code (standard for GitHub Actions; Claude uses native Read/Glob/Grep tools on checked-out files). Permissions (GitHub App): Official Claude app (https://github.com/apps/claude): Install to repo; requests: - Repository permissions: Contents (Read & Write), Issues (Read & Write), Pull requests (Read & Write). - Account permissions: None. Custom GitHub App (minimum): - Repository: Contents (Read & Write), Issues (Read & Write), Pull requests (Read & Write). Workflow example: jobs: claude: runs-on: ubuntu-latest permissions: contents: write issues: write pull-requests: write steps: - uses: actions/checkout@v4 - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} Claude Code permissions (tool use): Configurable via claude_args (e.g., --allowed-tools), /permissions command, or settings.json. Read-only tools (Read, Grep) need no approval; Bash etc. do. Note: Tool restrictions may not fully block native file reads in CI. Security: Use secrets, minimal permissions, sandbox (e.g., Docker). Known issue: Restricted tools may still allow file reads on checked-out repo.

Citations:


🏁 Script executed:

# Check the GitHub documentation examples or any CI configuration in the repo
find . -name "*.md" -path "./.github/*" -o -name "README*" | xargs grep -l "ANTHROPIC" 2>/dev/null || echo "No ANTHROPIC refs in .github docs"

Repository: musescore/MuseScore

Length of output: 96


🏁 Script executed:

# Look for any GitHub Actions security or fork handling guidance in issues or discussions
git log --oneline --all | grep -iE "(fork|security|action|secret)" | head -10 || echo "No relevant commit messages"

Repository: musescore/MuseScore

Length of output: 645


Fork PRs will fail: ANTHROPIC_API_KEY is not exposed to workflows triggered by pull_request from forks, and actions/checkout is missing.

GitHub does not pass repository secrets to pull_request runs originating from forked repositories—external contributors' PRs will execute with an empty ANTHROPIC_API_KEY and fail silently. Additionally, anthropics/claude-code-action@v1 requires an actions/checkout@v4 step (the action uses native Read/Glob/Grep tools on checked-out files), which is currently missing.

Two options:

  • Accept the limitation for forks and short-circuit early (e.g., if: github.event.pull_request.head.repo.full_name == github.repository) to avoid red X's on every external PR. If pursuing this path, still add actions/checkout@v4 for non-fork runs.
  • Use pull_request_target instead, which runs in the context of the base branch with write-scoped secrets and secret access. Do not combine this with actions/checkout of the PR head, and keep the prompt/config entirely in-repo to avoid privilege-escalation via malicious PR content. Add this step for checkout: - uses: actions/checkout@v4 (checks out the base branch by default under pull_request_target).

Additionally:

  • Add explicit permissions block (contents, issues, pull-requests all read/write) per the official example.
  • Add a concurrency group to prevent multiple expensive Claude API runs from racing when rapid pushes occur on synchronize events.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/check_review.yml around lines 2 - 4, The workflow
currently triggers only on pull_request which prevents secrets like
ANTROPIC_API_KEY from being available to fork PRs and also omits
actions/checkout required by anthropics/claude-code-action@v1; update the
workflow to either (A) keep pull_request but add an early short-circuit
conditional (if: github.event.pull_request.head.repo.full_name ==
github.repository) and add actions/checkout@v4 when running in-repo, or (B)
switch the trigger to pull_request_target (which runs with base-branch secrets)
and use actions/checkout@v4 to check out the base branch only (do NOT check out
the PR head), and in both cases add an explicit permissions block (e.g.,
contents, issues, pull-requests read/write) and a concurrency group to prevent
overlapping Claude runs; reference the on: pull_request trigger, the missing
actions/checkout@v4 step, and anthropics/claude-code-action@v1 when making these
changes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@CodeRabbit please check again

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the current content of the workflow file
cat -n .github/workflows/check_review.yml

Length of output: 538


@igorkorsukov, the file has not changed since my initial review — all four issues are still present. Here's a summary and a suggested corrected workflow:


Issues still present

# Issue Impact
1 pull_request trigger — secrets not available to fork PRs ANTHROPIC_API_KEY will be empty for external contributors; workflow fails silently
2 Missing actions/checkout@v4 Community examples and the official documentation consistently place a Checkout repository step (using actions/checkout@v4 with fetch-depth: 0) before anthropics/claude-code-action@v1 — Claude needs the repo files to analyse the diff
3 Missing permissions block The official example sets contents: write, pull-requests: write, issues: write, and id-token: write at the job level; without these the action cannot post review comments
4 Missing concurrency group On synchronize events, rapid pushes will queue up multiple expensive Claude API runs

Suggested fix

name: 'Check: Code Review'
on:
  pull_request:
    types: [opened, synchronize]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  review:
    # Skip fork PRs — ANTHROPIC_API_KEY is not available in that context
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Run Claude Code Review
        uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: "Review this pull request for code quality, correctness, and security. Analyze the diff, then post your findings as review comments."
          claude_args: "--max-turns 5"

Key changes:

  • if: condition — skips the job for fork PRs to avoid red check failures from missing secrets.
  • actions/checkout@v4 — required by the action to read repository files.
  • permissions — grants the action the rights to post PR review comments.
  • concurrency — cancels in-progress runs when a new push arrives on the same PR.

🧠 Learnings used
Learnt from: mathesoncalum
Repo: musescore/MuseScore PR: 32954
File: .github/workflows/triage_prs.yml:14-14
Timestamp: 2026-04-08T15:43:32.666Z
Learning: In the musescore/MuseScore repository, do not flag GitHub Actions workflow steps that use the mutable ref `actions/add-to-projectmain` as a supply-chain security issue. This is an intentional, consistent pattern in this repo’s `.github/workflows/` (notably `triage_issues.yml` and `triage_prs.yml`), so reviews should not require pinning to a full commit SHA for this specific action reference.

Comment on lines +3 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

anthropics/claude-code-action v1 pull_request_target security guidance checkout PR head

💡 Result:

For the anthropics/claude-code-action v1 used with the pull_request_target trigger, the key security guidance for checking out the PR head follows GitHub Actions best practices to avoid executing untrusted code in a privileged context. Do not check out the PR head (github.event.pull_request.head.sha) directly in pull_request_target workflows, as this grants attackers access to secrets like ANTHROPIC_API_KEY while running potentially malicious code from the PR branch. This is a well-documented supply chain attack vector. Official examples in anthropics/claude-code-action docs/solutions.md and security.md use 'on: pull_request' (not _target) with standard actions/checkout@v4+ (fetch-depth:1), which checks out the merge commit safely in a read-only context without secrets. The action supports pull_request_target (added in PR #579, merged Sep 2025) for cases like Dependabot needing write permissions, treating it as PR context internally. However, no official examples show PR head checkout with _target. Safe configuration for pull_request_target (e.g., automated reviews of external PRs): - Use minimal permissions: contents: read, pull-requests: write, id-token: write - Skip actions/checkout entirely if possible—the action accesses repo via GitHub API/MCP tools (Read, Bash(gh pr:), etc.), not local filesystem. Claude analyzes PR diff remotely. - If checkout needed (rare), checkout base branch only: ref: ${{ github.ref }} or default branch, with persist-credentials: false. - Restrict tools: claude_args: '--allowed-tools "Bash(gh pr comment:)"' to limit to safe GitHub CLI ops. - Add runtime protections: step-security/harden-runner@v2 with egress-policy: audit/block. - Use allowed_non_write_users cautiously (RISKY, per security.md); prefer write-access triggers. - Enable branch protections, require approvals for external contributors. - Review prompts for injection risks. For untrusted PR analysis, prefer 'on: pull_request' or separate jobs: one safe review job (no secrets/checkout head), gated approval job (pull_request_target with head checkout). Sources confirm action runs post-checkout but relies on API context, not local files for PR review—avoiding head checkout mitigates risks while enabling _target for privileged ops like commenting.

Citations:


🏁 Script executed:

cat -n .github/workflows/check_review.yml

Repository: musescore/MuseScore

Length of output: 608


🏁 Script executed:

fd -e yml -e yaml .github/workflows/ | head -20

Repository: musescore/MuseScore

Length of output: 440


🏁 Script executed:

fd . '.github/workflows/' -e yml -e yaml

Repository: musescore/MuseScore

Length of output: 960


🏁 Script executed:

cat -n .github/workflows/triage_prs.yml

Repository: musescore/MuseScore

Length of output: 1036


🏁 Script executed:

cat -n .github/workflows/claude.yml

Repository: musescore/MuseScore

Length of output: 2461


Security: pull_request_target needs explicit permission scoping and tool restrictions.

This workflow uses pull_request_target to grant ANTHROPIC_API_KEY and full GitHub permissions to a job triggered by untrusted PR content. While the workflow does not explicitly check out the PR head (reducing the direct execution risk), it still lacks two critical mitigations:

  1. No explicit permissions block — defaults to full permissions instead of least-privilege (compare to triage_prs.yml which declares permissions: { pull-requests: read, contents: read }).
  2. No tool restrictionsclaude_args: "--max-turns 5" should include --allowed-tools to restrict Claude to read-only operations (e.g., avoid Bash(...) on untrusted input). See claude.yml line 49 for an example of tool scoping.

Apply these mitigations together:

  • Add permissions block: { contents: read, pull-requests: read, id-token: write } (minimal write scope if comment-back is needed).
  • Add to claude_args: --allowed-tools "Bash(gh pr:*)" or similar read-only tools only.
  • Optionally gate fork PRs: if: contains(github.event.pull_request.labels.*.name, 'safe-to-review') so a maintainer reviews the diff before secrets are exposed.

Note: The @v1 mutable ref is a documented pattern in this repository; this is a separate supply-chain concern.

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

In @.github/workflows/check_review.yml around lines 3 - 4, The workflow using
pull_request_target grants too-broad privileges: add an explicit permissions
block with minimal scopes (permissions: { contents: read, pull-requests: read,
id-token: write }) to the pull_request_target job, and restrict Claude by
appending an allowed-tools flag to claude_args (e.g., include --allowed-tools
"Bash(gh pr:*)" or another read-only tool list) to prevent executing arbitrary
commands via ANTHROPIC_API_KEY; optionally gate fork PRs by adding an if
condition such as contains(github.event.pull_request.labels.*.name,
'safe-to-review') to require a maintainer label before exposing secrets or
running the job.

jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: anthropics/claude-code-action@v1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider pinning anthropics/claude-code-action to a commit SHA.

This action ships with an API key and is granted write access to PRs/issues. A mutable @v1 tag means any future tag move (or tag compromise) lands in CI automatically. Pinning to a full commit SHA (with a # v1.x.y comment) is the standard hardening recommendation for third-party actions handling secrets.

Note: this repo's convention for actions/add-to-projectmain intentionally uses a mutable ref, but that's a first-party GitHub action with no secrets; the calculus differs for a third-party action that consumes ANTHROPIC_API_KEY and writes to PRs.

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

In @.github/workflows/check_review.yml at line 9, Replace the mutable ref on the
third‑party GitHub Action by pinning anthropics/claude-code-action@v1 to a
specific commit SHA: update the usage of anthropics/claude-code-action@v1 in the
workflow to anthropics/claude-code-action@<full-commit-sha> and add a trailing
comment like "# v1.x.y" to document the intended tag; this hardens CI by
ensuring the action that consumes ANTHROPIC_API_KEY and writes to PRs cannot
change unexpectedly.

with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
Comment on lines +6 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Declare an explicit least-privilege permissions: block and verify whether actions/checkout is required.

Two concerns based on the upstream anthropics/claude-code-action@v1 docs:

  1. The official example workflow sets an explicit permissions block (contents, pull-requests, issues, id-token, and actions: read to read CI results). Although the action states "standard permissions (contents: write, pull_requests: write, issues: write) are always included", relying on the default GITHUB_TOKEN permissions of this repo is fragile — if the org default is read-only, Claude won't be able to post review comments. Declaring them explicitly is both more secure (least privilege, scoped to this job) and more robust.
  2. The upstream example also includes actions/checkout@v... before the Claude step. Review-only usage with a prompt may work without a checkout, but this isn't documented as guaranteed.
♻️ Suggested baseline
 jobs:
   review:
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      pull-requests: write
+      issues: write
     steps:
+      - uses: actions/checkout@v4
+        with:
+          fetch-depth: 1
       - uses: anthropics/claude-code-action@v1
         with:
           anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
           prompt: "Review this pull request for code quality, correctness, and security. Analyze the diff, then post your findings as review comments."
           claude_args: "--max-turns 5"

Please confirm against the pinned v1 version whether a prior actions/checkout step is required for diff-review mode, and whether the default GITHUB_TOKEN permissions in this repository allow writing PR review comments.

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

In @.github/workflows/check_review.yml around lines 6 - 11, Add an explicit
least-privilege permissions block to the "review" job and add a preceding
actions/checkout step if needed: declare permissions matching the upstream
example (e.g., contents: write, pull-requests: write, issues: write, id-token:
write, actions: read) scoped under the review job, insert actions/checkout@v3
before the anthropics/claude-code-action@v1 step if the action requires
repository files, and verify against the pinned anthropics/claude-code-action@v1
docs whether checkout is required and whether this repository’s default
GITHUB_TOKEN permissions permit writing PR review comments.

prompt: "Review this pull request for code quality, correctness, and security. Analyze the diff, then post your findings as review comments."
claude_args: "--max-turns 5"
58 changes: 58 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
Comment on lines +15 to +19
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Consider gating @claude triggers to trusted actors to avoid API-credit abuse.

Any user who can comment on an issue/PR (including drive-by accounts) can invoke this workflow by typing @claude, consuming ANTHROPIC_API_KEY credits and running the action with contents: write / pull-requests: write. Consider adding an author-association check to the if: condition, e.g.:

      (github.event.comment.author_association == 'OWNER' ||
       github.event.comment.author_association == 'MEMBER' ||
       github.event.comment.author_association == 'COLLABORATOR')

applied per event type. This prevents anonymous cost/abuse exposure while keeping the feature available to maintainers.

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

In @.github/workflows/claude.yml around lines 15 - 19, Update the workflow `if:`
conditional to require a trusted author_association for each event type that
triggers on comment/review/issue; specifically, for the clauses checking
github.event.comment, github.event.review, and github.event.issue, add checks
that github.event.*.author_association is one of OWNER, MEMBER, or COLLABORATOR
(e.g., ensure github.event.comment.author_association == 'OWNER' || ...); keep
the existing contains(..., '@claude') checks but combine them with the
author_association guard for pull_request_review_comment, pull_request_review,
issue_comment, and issues so only trusted actors can trigger the run.

runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Same mutable-ref concern as check_review.yml: anthropics/claude-code-action@v1 runs with write scopes and a secret API key — consider pinning to a commit SHA.

This is consistent with the prior review on the sibling workflow; the repo's add-to-projectmain learning (first-party, no secrets) does not apply here. A tag move or tag compromise would silently land in CI with full write access.

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

In @.github/workflows/claude.yml at line 35, The workflow currently uses the
mutable tag anthropics/claude-code-action@v1 which grants code execution with
write scopes and a secret API key; replace the tag with a pinned commit SHA for
anthropics/claude-code-action (use the specific commit hash for the version you
trust) so the action cannot be silently upgraded—update the uses entry
(anthropics/claude-code-action@v1 → anthropics/claude-code-action@<commit-sha>)
in the claude.yml workflow and ensure any related workflows (e.g.,
check_review.yml) follow the same pinning practice.

with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

# Optional: Customize the trigger phrase (default: @claude)
# trigger_phrase: "/claude"

# Optional: Trigger when specific user is assigned to an issue
# assignee_trigger: "claude-bot"

# Optional: Configure Claude's behavior with CLI arguments
# claude_args: |
# --model claude-opus-4-1-20250805
# --max-turns 10
# --allowedTools "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
# --system-prompt "Follow our coding standards. Ensure all new code has tests. Use TypeScript for new files."

# Optional: Advanced settings configuration
# settings: |
# {
# "env": {
# "NODE_ENV": "test"
# }
# }
Comment on lines +39 to +58
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Strip commented-out boilerplate before merging.

~20 lines of vendor-example comments add no value in a production workflow and will decay over time as the upstream example changes. If any of these options are planned (e.g., claude_args), enable them; otherwise remove the block and rely on the upstream docs.

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

In @.github/workflows/claude.yml around lines 39 - 58, Remove the large block of
commented vendor-example options (the commented keys like trigger_phrase,
assignee_trigger, claude_args, and settings) from the workflow to avoid noisy,
decaying boilerplate; if any option is intended to be used, replace its
commented example with an enabled configuration (uncomment and set the real
value) otherwise delete the entire commented section so only active
configuration remains.

Loading