From ae2f32bee679e1354e0a0f12f7986ad6ec591d78 Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Thu, 4 Dec 2025 17:02:07 -0500 Subject: [PATCH 1/7] "Claude PR Assistant workflow" --- .github/workflows/claude.yml | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/claude.yml diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000000000..d300267f1855c --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +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'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr:*)' + From 6c36ebcad31f4aa7b33210a51f8f4255ef3b1434 Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Thu, 4 Dec 2025 17:02:08 -0500 Subject: [PATCH 2/7] "Claude Code Review workflow" --- .github/workflows/claude-code-review.yml | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/claude-code-review.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000000000..8452b0f2ff194 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,57 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + prompt: | + REPO: ${{ github.repository }} + PR NUMBER: ${{ github.event.pull_request.number }} + + Please review this pull request and provide feedback on: + - Code quality and best practices + - Potential bugs or issues + - Performance considerations + - Security concerns + - Test coverage + + Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback. + + Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR. + + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"' + From e8dd105bd6c94e4a7c962840a4d732932c58dcaa Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 8 Dec 2025 16:34:46 -0500 Subject: [PATCH 3/7] security: restrict @claude to trusted contributors only Only allow OWNER, MEMBER, and COLLABORATOR to trigger the @claude assistant workflow. This prevents random external users from consuming API quota on the public repository. --- .github/workflows/claude.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index d300267f1855c..5a21d9c468df8 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -13,10 +13,23 @@ on: 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'))) + ( + github.event_name == 'issue_comment' && + contains(github.event.comment.body, '@claude') && + contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) + ) || ( + github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude') && + contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) + ) || ( + github.event_name == 'pull_request_review' && + contains(github.event.review.body, '@claude') && + contains('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('OWNER,MEMBER,COLLABORATOR', github.event.issue.author_association) + ) runs-on: ubuntu-latest permissions: contents: read From 1d8dc46f641d2714b51fcad0090cf7cf45933a85 Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 8 Dec 2025 16:35:10 -0500 Subject: [PATCH 4/7] security: remove unused id-token: write permission Since we're using claude_code_oauth_token for authentication, we don't need id-token: write (which is only for OIDC auth with Bedrock/Vertex). Keep actions: read in the assistant workflow since it explicitly uses additional_permissions to read CI results. --- .github/workflows/claude-code-review.yml | 1 - .github/workflows/claude.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 8452b0f2ff194..debf00a4fcf70 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -23,7 +23,6 @@ jobs: contents: read pull-requests: read issues: read - id-token: write steps: - name: Checkout repository diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 5a21d9c468df8..cf8072a6bbb78 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -35,7 +35,6 @@ jobs: contents: read pull-requests: read issues: read - id-token: write actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository From 744f1c01cc95c441d16eefdf9e028b7fe4a4d16f Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 8 Dec 2025 16:35:32 -0500 Subject: [PATCH 5/7] security: pin GitHub Actions to commit SHAs Pin actions/checkout and anthropics/claude-code-action to specific commit SHAs to prevent supply-chain attacks via compromised tags. - actions/checkout: v4.2.2 -> 11bd719 - anthropics/claude-code-action: v1 -> 3a38b37 These should be updated periodically when new versions are released. --- .github/workflows/claude-code-review.yml | 4 ++-- .github/workflows/claude.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index debf00a4fcf70..0d9a06f1b438b 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -26,13 +26,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1 - name: Run Claude Code Review id: claude-review - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@3a38b377b30c75102b420405ed9516b57ca2e248 # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} prompt: | diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index cf8072a6bbb78..721677f6ef4d9 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -38,13 +38,13 @@ jobs: actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1 - name: Run Claude Code id: claude - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@3a38b377b30c75102b420405ed9516b57ca2e248 # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} From 34165c06f97b848dc7d92cf9871399440ae33b1b Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 8 Dec 2025 16:35:52 -0500 Subject: [PATCH 6/7] security: limit @claude triggers to comments only Remove issue creation/assignment and PR review submission events, keeping only comment-based triggers. This reduces the event surface area and ensures @claude is only invoked through explicit comment mentions, making it harder to trigger accidentally. --- .github/workflows/claude.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 721677f6ef4d9..e605715b58ebc 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -5,10 +5,6 @@ on: types: [created] pull_request_review_comment: types: [created] - issues: - types: [opened, assigned] - pull_request_review: - types: [submitted] jobs: claude: @@ -21,14 +17,6 @@ jobs: github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) - ) || ( - github.event_name == 'pull_request_review' && - contains(github.event.review.body, '@claude') && - contains('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('OWNER,MEMBER,COLLABORATOR', github.event.issue.author_association) ) runs-on: ubuntu-latest permissions: From b24dcc11cd47ecd010bf9fc51d231f01e96a993c Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 8 Dec 2025 22:59:56 -0500 Subject: [PATCH 7/7] require explicit mention in comment to trigger review --- .github/workflows/claude-code-review.yml | 29 ++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 0d9a06f1b438b..26f4cb15a60f7 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -1,23 +1,24 @@ name: Claude Code Review on: - pull_request: - types: [opened, synchronize] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] jobs: claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - + if: | + ( + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '@claude review') && + contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) + ) || ( + github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude review') && + contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) + ) runs-on: ubuntu-latest permissions: contents: read