|
13 | 13 | jobs: |
14 | 14 | claude: |
15 | 15 | name: Claude Code Action |
| 16 | + # Security: Only allow invocation by trusted contributors. |
| 17 | + # Blocks NONE (anonymous), FIRST_TIMER, and FIRST_TIME_CONTRIBUTOR to |
| 18 | + # prevent prompt-injection attacks from untrusted GitHub users. |
| 19 | + # See: https://docs.github.com/en/graphql/reference/enums#commentauthorassociation |
16 | 20 | if: | |
17 | | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || |
18 | | - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || |
19 | | - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || |
20 | | - (github.event_name == 'issues' && contains(github.event.issue.body, '@claude')) |
| 21 | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && |
| 22 | + github.event.comment.author_association != 'NONE' && |
| 23 | + github.event.comment.author_association != 'FIRST_TIMER' && |
| 24 | + github.event.comment.author_association != 'FIRST_TIME_CONTRIBUTOR') || |
| 25 | + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && |
| 26 | + github.event.comment.author_association != 'NONE' && |
| 27 | + github.event.comment.author_association != 'FIRST_TIMER' && |
| 28 | + github.event.comment.author_association != 'FIRST_TIME_CONTRIBUTOR') || |
| 29 | + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && |
| 30 | + github.event.review.author_association != 'NONE' && |
| 31 | + github.event.review.author_association != 'FIRST_TIMER' && |
| 32 | + github.event.review.author_association != 'FIRST_TIME_CONTRIBUTOR') || |
| 33 | + (github.event_name == 'issues' && contains(github.event.issue.body, '@claude') && |
| 34 | + github.event.issue.author_association != 'NONE' && |
| 35 | + github.event.issue.author_association != 'FIRST_TIMER' && |
| 36 | + github.event.issue.author_association != 'FIRST_TIME_CONTRIBUTOR') |
21 | 37 | runs-on: ubuntu-latest |
22 | 38 | timeout-minutes: 20 |
| 39 | + # Least-privilege permissions for the AI agent workflow. |
| 40 | + # contents:write is required for Claude to push commits on PRs. |
23 | 41 | permissions: |
24 | 42 | contents: write |
25 | 43 | pull-requests: read |
|
44 | 62 | uses: anthropics/claude-code-action@35a9e0292d36f1186f5d842b14eb575074e8b450 # v1 |
45 | 63 | with: |
46 | 64 | anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} |
| 65 | + # Security: Restrict tools to prevent arbitrary code execution. |
| 66 | + # Bash is scoped to known-safe commands (task, go, git, helm-docs). |
| 67 | + # No unrestricted Bash access — prevents prompt injection from |
| 68 | + # executing arbitrary shell commands via crafted issue/PR content. |
| 69 | + allowed_tools: "Read,Edit,Write,Glob,Grep,Bash(task *),Bash(go *),Bash(git *),Bash(helm-docs *),mcp__github__*" |
0 commit comments