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
44 changes: 44 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
# 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
Comment on lines +22 to +26

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

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/claude-code-review.yml

Repository: z8dn/advanced-android-project-view

Length of output: 1819


🌐 Web query:

anthropics/claude-code-action permissions documentation

💡 Result:

Anthropic/Claude Code Action “permissions” documentation is split into two related areas: 1) Claude Code (the local/IDE agent) permission system - Official docs: https://docs.anthropic.com/en/docs/claude-code/permissions - These define fine-grained tool permissions and permission modes (e.g., default, acceptEdits, plan, auto, dontAsk, bypassPermissions), including rules precedence (deny → ask → allow) and how permissions are configured/managed. 2) anthropics/claude-code-action (the GitHub Action that runs Claude Code for PRs/issues) - Official docs live in the repository: https://github.com/anthropics/claude-code-action - Security/access control docs for the Action are here: https://github.com/anthropics/claude-code-action/blob/main/docs/security.md Key points stated there: - Repository Access: the Action can only be triggered by users with write access to the repository. - Bot/User controls: - By default, GitHub Apps/bots cannot trigger it; you can enable specific bots via allowed_bots. - “allowed_bots” matches bots even if they do not have repo permissions (and on public repos, external parties could trigger events that invoke the Action if allowed_bots is '*', so scope workflow permissions to minimum). - Non-write user bypass (risky): allowed_non_write_users can bypass the write requirement (only works with github_token input, and is described as a significant security risk). - Token scoping: the Claude Code GitHub app receives a short-lived token scoped to the repository, with no cross-repo access. - GitHub App permissions requested by the Action include (currently used): Contents (Read & Write), Pull Requests (Read & Write), Issues (Read & Write), with additional permissions noted for future features. - FAQ for common permission/auth issues (including workflow “write permissions” requirement and OIDC id-token write): https://github.com/anthropics/claude-code-action/blob/main/docs/faq.md - The Action’s configuration inputs (including additional_permissions like actions: read) are also reflected in the repo docs and action.yml; see the Action repository root for the full setup/usage guides. If you meant “Claude Code Action permissions” specifically for the GitHub Action, start with the repo security.md + faq.md links above. If you meant “Claude Code permission rules” for the agent itself (allowed/deny/ask modes and tool-level rules), start with the Anthropic Claude Code permissions docs link above.

Citations:


🌐 Web query:

anthropics/claude-code-action official examples pull-requests write

💡 Result:

The official GitHub repository for Anthropic's Claude Code Action is https://github.com/anthropics/claude-code-action. It provides a general-purpose action for GitHub PRs and issues where Claude can answer questions, perform code reviews, and implement code changes, including creating pull requests. Official examples are in the /examples directory (e.g., https://github.com/anthropics/claude-code-action/blob/main/examples/claude.yml) and detailed solutions in /docs/solutions.md (https://github.com/anthropics/claude-code-action/blob/main/docs/solutions.md). To write pull requests: 1. Set up a workflow in .github/workflows/ (e.g., claude.yml) using anthropics/claude-code-action@v1 with permissions: contents: write, pull-requests: write, issues: write. 2. Require ANTHROPIC_API_KEY secret. 3. Trigger on issue_comment, issues opened/assigned, etc., with if condition checking for '@claude'. 4. Example basic workflow (from examples/claude.yml): 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: write pull-requests: write issues: write id-token: write actions: read steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 1 - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} 5. Usage: In an issue or PR comment, say "@claude Please implement a new API endpoint for user preferences following existing patterns." Claude will edit files, commit, push to a new branch, and create a PR (requires contents:write, pull-requests:write permissions). For automation without @claude (e.g., auto doc sync on API changes), use 'prompt' input with specific instructions and trigger on pull_request paths. See Anthropic docs: https://docs.anthropic.com/en/docs/claude-code/github-actions

Citations:


Change pull-requests: read to pull-requests: write to align with official action examples.

The official examples from the Anthropic Claude Code Action repository (https://github.com/anthropics/claude-code-action) specify permissions: contents: write, pull-requests: write, issues: write. The GitHub App requested by the action includes Read & Write permissions for Pull Requests. While the action uses a custom OAuth token (CLAUDE_CODE_OAUTH_TOKEN) rather than GITHUB_TOKEN, the workflow permissions define the baseline access level for all steps in the environment. Changing to write eliminates potential fallback failures and matches the reference configurations provided by Anthropic.

-      pull-requests: read
+      pull-requests: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
permissions:
contents: read
pull-requests: write
issues: read
id-token: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 22 - 26, Update the
workflow permissions block so the pull-requests permission is set to write
instead of read: locate the permissions mapping (the permissions: block
containing contents, pull-requests, issues, id-token) and change the
pull-requests entry from pull-requests: read to pull-requests: write to match
the Anthropic Claude Code Action examples and allow the workflow full PR write
access.


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 }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# 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

Comment on lines +29 to +44

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

🧩 Analysis chain

🏁 Script executed:

git ls-remote https://github.com/anthropics/claude-code-action refs/tags/v1
git ls-remote https://github.com/actions/checkout refs/tags/v4

Repository: z8dn/advanced-android-project-view

Length of output: 186


🏁 Script executed:

# Check if the file exists and examine the relevant lines
find . -name "claude-code-review.yml" -type f

Repository: z8dn/advanced-android-project-view

Length of output: 121


🏁 Script executed:

# Verify the v4.2.2 tag for actions/checkout to explain the SHA discrepancy
git ls-remote https://github.com/actions/checkout refs/tags/v4.2.2

Repository: z8dn/advanced-android-project-view

Length of output: 136


🏁 Script executed:

# Also check for the plugin marketplace tag information
git ls-remote https://github.com/anthropics/claude-code refs/tags/v1

Repository: z8dn/advanced-android-project-view

Length of output: 60


🏁 Script executed:

# Read the workflow file to verify the actual code
cat -n ./.github/workflows/claude-code-review.yml | sed -n '25,50p'

Repository: z8dn/advanced-android-project-view

Length of output: 997


🏁 Script executed:

# Check available refs in anthropics/claude-code-action repo
git ls-remote https://github.com/anthropics/claude-code-action

Repository: z8dn/advanced-android-project-view

Length of output: 50390


Pin both third-party actions and the plugin marketplace to specific commits

Both actions/checkout@v4 (line 30) and anthropics/claude-code-action@v1 (line 36) use mutable floating tags. The claude-code-action step has id-token: write access with the OAuth token in scope. A tag force-push to a malicious commit would execute arbitrary code with those privileges.

plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' (line 39) resolves to the HEAD of main at runtime. Pinning the marketplace URL to a specific commit ref or tag prevents unreviewed upstream changes from silently altering what plugin code runs in your CI.

Recommended approach
      - name: Checkout repository
-       uses: actions/checkout@v4
+       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Run Claude Code Review
        id: claude-review
-       uses: anthropics/claude-code-action@v1
+       uses: anthropics/claude-code-action@8c196b2f61a66bfdf93322bde3a3e668669089ed # v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
-         plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
+         plugin_marketplaces: 'https://github.com/anthropics/claude-code.git@<ref-or-sha>'
🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 44-44: too many blank lines (1 > 0)

(empty-lines)

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

In @.github/workflows/claude-code-review.yml around lines 29 - 44, The workflow
uses mutable tags and an unpinned plugin marketplace URL; update the actions and
marketplace to immutable refs: replace uses: actions/checkout@v4 and uses:
anthropics/claude-code-action@v1 with specific commit SHAs or immutable release
tags (pin the claude-code-action and checkout action to exact commit SHAs), and
change plugin_marketplaces from the bare repo URL to the repository URL pinned
to a commit ref (e.g., the full git+https URL or the repo URL that includes the
specific commit/tag), ensuring the claude-code-action step still passes
claude_code_oauth_token and retains the same inputs but references the pinned
marketplace ref to avoid executing unreviewed upstream changes.

50 changes: 50 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
Comment on lines +8 to +9

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 | 🟡 Minor | ⚡ Quick win

issues: assigned re-triggers Claude for pre-existing @claude body mentions

The assigned type fires every time the issue is (re)assigned. The if: condition evaluates github.event.issue.body, which is the original issue body — not the assignment action itself. Any issue that was originally opened with @claude in its body or title will re-invoke Claude on every subsequent assignment, including routine triage operations.

The action exposes a trigger_assignee parameter for issue assignment use-cases, which would fire only when the issue is assigned to the Claude bot, avoiding unintended re-invocations. If the intent is only to allow @claude mentions in the issue body to trigger once on open, remove assigned from the event types:

   issues:
-    types: [opened, assigned]
+    types: [opened]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
issues:
types: [opened, assigned]
issues:
types: [opened]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml around lines 8 - 9, The workflow currently
lists issues.types: [opened, assigned], which causes pre-existing issues
containing “@claude” in github.event.issue.body to re-trigger on every
reassignment; fix by either removing "assigned" from issues.types so only issue
opens trigger the run, or, if you need assignment-based runs, replace the
generic assigned trigger with the action's trigger_assignee usage and an if:
guard that checks the assignment target (use the action's trigger_assignee
parameter instead of relying on github.event.issue.body) so the job fires only
when the issue is assigned to the Claude bot.

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 | 🔴 Critical | ⚡ Quick win

🔐 Critical: Any GitHub user can trigger the workflow — OAuth secret is exposed to unauthorized actors

The if: condition has no author_association check, so on public repositories any user who can open an issue or leave a comment containing @claude can trigger the workflow. Because CLAUDE_CODE_OAUTH_TOKEN is passed unconditionally once the if: guard passes, the Claude Code GitHub App — which has read and write access to code, issues, and pull requests — is reachable by any unauthenticated commenter. This drains API credits at minimum and at worst enables arbitrary users to request repository writes through Claude.

The recommended fix is to add author_association checks to every event branch in the if: block to restrict invocations to OWNER, MEMBER, and COLLABORATOR:

🔒 Proposed fix — add author_association guard to each event branch
     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))
🤖 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, The workflow’s if:
condition allows any commenter to trigger the run and thus expose
CLAUDE_CODE_OAUTH_TOKEN; update each branch that checks github.event_name (the
branches containing github.event.comment.body, github.event.review.body,
github.event.issue.body, github.event.issue.title) to also require
github.event.comment.author_association (or
github.event.review.author_association / github.event.issue.author_association
as appropriate) to be one of OWNER, MEMBER, or COLLABORATOR so the secret is
only passed for trusted actors; ensure the final combined boolean for each
branch includes that author_association check before the secret is used.

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 }}
Comment on lines +35 to +37

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

🧩 Analysis chain

🏁 Script executed:

git ls-remote https://github.com/anthropics/claude-code-action refs/tags/v1
git ls-remote https://github.com/actions/checkout refs/tags/v4

Repository: z8dn/advanced-android-project-view

Length of output: 186


🏁 Script executed:

cat -n .github/workflows/claude.yml

Repository: z8dn/advanced-android-project-view

Length of output: 2314


Pin anthropics/claude-code-action and actions/checkout to commit SHAs to prevent supply-chain compromise

@v1 and @v4 are mutable floating tags. If force-pushed to a malicious commit, the runner executes that code with id-token: write permission and CLAUDE_CODE_OAUTH_TOKEN already in the environment.

🔒 Recommended approach
      - name: Checkout repository
-       uses: actions/checkout@v4
+       uses: actions/checkout@34e114876b0b11c390a56381ad13914f8d5 # v4.2.2

      - name: Run Claude Code
        id: claude
-       uses: anthropics/claude-code-action@v1
+       uses: anthropics/claude-code-action@8c196b2f61a66bfdf93322bde3a3e668669089ed # v1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml around lines 35 - 37, The workflow currently
uses mutable tags for third-party actions (uses:
anthropics/claude-code-action@v1 and uses: actions/checkout@v4); pin both
actions to their specific commit SHAs instead of floating tags to prevent
supply‑chain risks: locate the uses entries in the workflow and replace the
`@v1/`@v4 suffixes with the corresponding full commit SHA for
anthropics/claude-code-action and actions/checkout (ensure the SHAs come from
the official repos/tags), then verify the workflow still runs and that secrets
like CLAUDE_CODE_OAUTH_TOKEN and id-token permissions are unchanged.


# 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 *)'

Loading