Debug GitHub Actions skipping on Claude tag#74
Conversation
Add repository check to allow PRs from the same repository to trigger the Claude workflow, even if author_association is CONTRIBUTOR. This handles private organization members who appear as CONTRIBUTOR instead of MEMBER. External contributors (from forks) are still blocked for security.
Code ReviewI found 2 critical issues in this PR: Issue 1: Incorrect context object for
|
| ( | ||
| (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && | ||
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')) || | ||
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR' || |
There was a problem hiding this comment.
@claude
is this safe chage to give permission internal contributors to trigger claude github actions?
There was a problem hiding this comment.
Claude finished @piatoss3612's task in 1m 14s —— View job
Security Analysis
TL;DR: No, this change is NOT safe. It introduces a critical security vulnerability that allows any GitHub user to trigger the Claude workflow with your repository's secrets and permissions.
Critical Security Vulnerability
The current implementation has a fundamental flaw: it checks WHERE the PR came from, not WHO is commenting. This creates an authorization bypass that allows any GitHub user to trigger Claude on internal PRs.
Attack Scenario
- An organization member creates a PR from a branch in
chainapsis/keplr-example(not a fork) - Any random GitHub user comments
@claudeon that PR - The workflow triggers because
github.event.pull_request.head.repo.full_name == github.repositoryis true - The
author_associationcheck is completely bypassed via the OR condition - The attacker now has Claude executing with your repository secrets and write permissions
Why This Happens
The logic uses OR conditions:
(author is OWNER/MEMBER/COLLABORATOR) OR (PR is from same repo)This means if EITHER condition is true, the workflow runs. The second condition doesn't care who's commenting.
Additional Technical Issue
For issue_comment events (line 19), github.event.pull_request doesn't exist in the event payload. You're checking github.event.pull_request.head.repo.full_name, but this object is only available for pull_request, pull_request_review, and pull_request_review_comment events.
For issue_comment on a PR, you need to:
- Use
github.event.issue.pull_request.urlto detect if it's a PR - Fetch PR details via GitHub API to get the head repo information
Reference: GitHub issue_comment event payload docs
Recommended Fix
Use AND logic to require BOTH a valid association AND same-repo for CONTRIBUTOR level:
if: |
(
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR' ||
(github.event.comment.author_association == 'CONTRIBUTOR' &&
github.event.issue.pull_request != null &&
/* fetch PR via API to check head repo */))) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR' ||
(github.event.comment.author_association == 'CONTRIBUTOR' &&
github.event.pull_request.head.repo.full_name == github.repository))) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') &&
(github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER' ||
github.event.review.author_association == 'COLLABORATOR' ||
(github.event.review.author_association == 'CONTRIBUTOR' &&
github.event.pull_request.head.repo.full_name == github.repository))) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
(github.event.issue.author_association == 'OWNER' ||
github.event.issue.author_association == 'MEMBER' ||
github.event.issue.author_association == 'COLLABORATOR'))
)This ensures:
- OWNER/MEMBER/COLLABORATOR can trigger from anywhere (existing behavior)
- CONTRIBUTOR can only trigger on non-fork PRs (your goal)
- Random users cannot trigger on any PRs (closes the vulnerability)
Alternative Approach
If private organization members truly appear as CONTRIBUTOR, consider:
- Grant them MEMBER status in the organization (preferred)
- Use a GitHub App with more granular permissions
- Add specific users to an allowlist in the workflow
My Assessment
Do not merge this PR. The security risk outweighs the convenience. I recommend addressing the root cause (organization member permissions) rather than loosening the security model in a way that creates vulnerabilities.
Reverted the previous changes that added repository checks with OR logic, which created a critical security vulnerability allowing any user to trigger the workflow by commenting on internal PRs. The original OWNER/MEMBER/COLLABORATOR check is safer. For private org members appearing as CONTRIBUTOR, alternatives: 1. Make org membership public 2. Add as repository collaborator 3. Use allowlist of specific usernames
Allow specific trusted users (piatoss3612, Thunnini) to trigger the Claude workflow even if their author_association is CONTRIBUTOR. This safely handles private organization members who appear as CONTRIBUTOR instead of MEMBER, without creating security vulnerabilities. Allowlist users: - piatoss3612 (team member) - Thunnini (chainapsis organization admin)
Switch from automatic code review on PR open/update to manual trigger via 'claude-review' label. This gives users control over when to run expensive code review operations. Changes: - Trigger only on 'labeled' event - Check for 'claude-review' label presence - Add allowlist (piatoss3612, Thunnini) for CONTRIBUTOR users - Maintain security checks for authorized users only Usage: Add 'claude-review' label to PR to trigger code review
Add repository check to allow PRs from the same repository to trigger the Claude workflow, even if author_association is CONTRIBUTOR. This handles private organization members who appear as CONTRIBUTOR instead of MEMBER.
External contributors (from forks) are still blocked for security.