Skip to content
Closed
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
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
pull-requests: write # Required for Claude to post review comments back to the PR
issues: write
id-token: write

steps:
Expand All @@ -33,7 +33,7 @@ jobs:

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251 # v1.0.133
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
Expand Down
18 changes: 10 additions & 8 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ on:

jobs:
claude:
# Only trigger for trusted collaborators so outside accounts can't invoke
# Claude (and consume API quota) by posting "@claude" on an issue/PR.
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')))
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 issues.assigned guard checks the wrong actor

For issues events with type assigned, github.event.issue.author_association is the association of the issue creator, not the person performing the assignment (github.actor). In practice, only collaborators can assign issues on GitHub, so the risk is low — but the intent of the guard ("restrict who can invoke Claude") is better expressed by checking the actor who triggered the assignment. If a trusted collaborator tries to route an external user's issue (which happens to contain @claude) to Claude via assignment, the workflow silently does nothing because the issue author is NONE/CONTRIBUTOR. Using github.actor and checking it against the trusted-association list (or against team membership) would match the declared intent of the guard.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/claude.yml
Line: 21

Comment:
**`issues.assigned` guard checks the wrong actor**

For `issues` events with type `assigned`, `github.event.issue.author_association` is the association of the **issue creator**, not the person performing the assignment (`github.actor`). In practice, only collaborators can assign issues on GitHub, so the risk is low — but the intent of the guard ("restrict who can invoke Claude") is better expressed by checking the actor who triggered the assignment. If a trusted collaborator tries to route an external user's issue (which happens to contain `@claude`) to Claude via assignment, the workflow silently does nothing because the issue author is `NONE`/`CONTRIBUTOR`. Using `github.actor` and checking it against the trusted-association list (or against team membership) would match the declared intent of the guard.

How can I resolve this? If you propose a fix, please make it concise.

runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
contents: write # Required for Claude to push commits / create branches
pull-requests: write # Required for Claude to post comments and open PRs
issues: write
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
Expand All @@ -32,7 +34,7 @@ jobs:

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251 # v1.0.133
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

Expand Down
Loading