fix: give @claude write access to push commits on PRs#2483
fix: give @claude write access to push commits on PRs#2483robert-inkeep merged 2 commits intomainfrom
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Grants the Claude Code GitHub Action write access so it can push commits on PRs (e.g. when addressing review feedback).
|
There was a problem hiding this comment.
Permissions escalation is correct and well-scoped. All three write permissions (contents, pull-requests, issues) are required by claude-code-action — contents: write for pushing commits, pull-requests: write for updating PR descriptions, and issues: write for posting comments on issues (the workflow triggers on issues events too). The app token integration mirrors the existing pattern in claude-code-review.yml and is correctly wired into both the checkout step and the github_token input for claude-code-action.
There was a problem hiding this comment.
PR Review Summary
(2) Total Issues | Risk: High
🔴❗ Critical (1) ❗🔴
Inline Comments:
- 🔴 Critical:
.github/workflows/claude.yml:15-19Missingauthor_associationcheck allows external users to trigger write operations
🟠⚠️ Major (1) 🟠⚠️
Inline Comments:
- 🟠 Major:
.github/workflows/claude.yml:41-47No--allowedToolsrestriction leaves Claude with unrestricted execution capabilities
💭 Consider (2) 💭
💭 1) .github/workflows/claude.yml:43 Pin claude-code-action to SHA for stability
Issue: The anthropics/claude-code-action@v1 is pinned to a mutable tag while claude-code-review.yml pins to a specific SHA (@01e756b34ef7a1447e9508f674143b07d20c2631).
Why: The SHA pinning in claude-code-review.yml includes a comment citing an AJV validation crash in newer versions (tracking issue #892). For consistency and stability, consider using the same SHA here.
Fix:
uses: anthropics/claude-code-action@01e756b34ef7a1447e9508f674143b07d20c2631 # Pinned for stabilityRefs: claude-code-review.yml:724 — SHA pinning with tracking issue
💭 2) .github/workflows/claude.yml:30 Pin actions/create-github-app-token to SHA
Issue: The action is pinned to @v1 instead of a full SHA.
Why: SHA pinning provides stronger supply chain security guarantees. This is a first-party GitHub action so the risk is lower, but other workflows in this repo use the same tag-based approach, so this is consistent with existing patterns.
Fix: If you prefer SHA pinning: uses: actions/create-github-app-token@5fc8f5d139ad38797bca97a3f6d4ba2a64788cf9 # v1.12.0
🚫 REQUEST CHANGES
Summary: The permission elevation to contents: write and pull-requests: write is valid and necessary for the stated goal of allowing Claude to push commits. However, the workflow is missing critical authorization checks that exist in peer workflows. Without author_association guards, any external user who can comment on issues/PRs can trigger Claude with write access — this is a significant security gap. The fix is straightforward: add the same author_association checks used in claude-code-review.yml. Once that's addressed, also consider adding allowed_bots: "claude[bot]" to prevent re-triggering loops.
Discarded (2)
| Location | Issue | Reason Discarded |
|---|---|---|
.github/workflows/claude.yml:28-33 |
App token scope may be broader than necessary | Not applicable — the workflow needs current repo write access which is the default behavior. Explicit repository scoping is only needed when accessing OTHER repos (like team-skills in claude-code-review.yml). |
.github/workflows/claude.yml:21-26 |
Permissions elevation is justified | Informational finding confirming the changes are correct — not an issue. |
Reviewers (2)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-security-iam |
3 | 0 | 0 | 0 | 2 | 0 | 1 |
pr-review-devops |
5 | 0 | 2 | 0 | 0 | 0 | 3 |
| Total | 8 | 0 | 2 | 0 | 2 | 0 | 4 |
| - name: Run Claude Code | ||
| id: claude | ||
| uses: anthropics/claude-code-action@v1 | ||
| with: | ||
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| github_token: ${{ steps.app-token.outputs.token }} | ||
| claude_args: '--model claude-opus-4-1-20250805' |
There was a problem hiding this comment.
🟠 MAJOR: No --allowedTools restriction leaves Claude with unrestricted execution capabilities
Issue: The claude-code-action invocation doesn't specify --allowedTools, giving Claude unrestricted ability to execute arbitrary bash commands, write any file, and push commits.
Why: Combined with the missing author_association check (see above), this creates an open attack surface. While this workflow's purpose is to let Claude make changes, defense-in-depth suggests scoping the tools to what's actually needed. The peer claude-code-review.yml explicitly restricts tools (line 735).
Fix: Consider adding an --allowedTools restriction scoped to code modification operations. At minimum, add allowed_bots to prevent re-triggering loops:
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ steps.app-token.outputs.token }}
allowed_bots: "claude[bot]"
claude_args: '--model claude-opus-4-1-20250805'If you want to restrict tools more tightly, consider a pattern like:
claude_args: |
--model claude-opus-4-1-20250805
--allowedTools "Read,Grep,Glob,Edit,Write,Bash(git add:*),Bash(git commit:*),Bash(git push:*),Bash(git status:*),Bash(git diff:*),Bash(pnpm:*)"Refs:
There was a problem hiding this comment.
issue with this one is that I've seen all types of requests in PRs. "check vercel deploy" etc to bash scripts. Either we restrict features in terms of what you can ask claude or blacklist highest risk function calls.
There was a problem hiding this comment.
PR Review Summary
(0) Total Issues | Risk: Low
This is a delta review following the prior review's Critical issue being addressed. The author_association guards have been correctly added to all event conditions, closing the security gap that would have allowed external users to trigger write operations.
🔄 Prior Issues Status
| Prior Issue | Status | Notes |
|---|---|---|
🔴 Critical: Missing author_association check |
✅ Resolved | Commit a9431db adds guards to all 4 event types (OWNER/MEMBER/COLLABORATOR only) |
🟠 Major: No --allowedTools restriction |
✅ Reconsidered | Both reviewers agree this is intentional design — see analysis below |
Prior Major Issue Analysis: --allowedTools
The prior review flagged the lack of --allowedTools as a Major concern. Upon deeper analysis, both specialist reviewers independently concluded this is intentional by design and not a security gap:
-
Different threat models:
claude-code-review.ymlruns automatically on all PRs (including from external contributors), requiring strict tool restrictions.claude.ymlis a human-triggered mention handler where trusted collaborators explicitly invoke@claudeto perform arbitrary tasks. -
Authorization is the security boundary: With
author_associationguards now in place, only OWNER/MEMBER/COLLABORATOR can trigger this workflow. These users already have write access to the repository — giving them unrestricted Claude capabilities doesn't expand the attack surface. -
Purpose alignment: The whole point of this workflow is to let trusted collaborators ask Claude to perform ad-hoc tasks (add changesets, make code changes, push commits). Restricting tools would defeat the purpose.
💭 Consider (1)
Inline Comments:
- 💭 Consider:
.github/workflows/claude.yml:43SHA pinning inconsistency withclaude-code-review.yml
✅ APPROVE
Summary: The Critical security issue from the prior review has been properly addressed. The author_association checks are correctly implemented for all event types, matching the pattern used in claude-code-review.yml. The permission elevation (contents: write, pull-requests: write, issues: write) and app token usage are appropriate for the workflow's purpose. Ship it! 🚀
Discarded (1)
| Location | Issue | Reason Discarded |
|---|---|---|
.github/workflows/claude.yml:30 |
SHA pinning for actions/create-github-app-token@v1 |
Matches existing patterns across other workflows (release.yml, claude-code-review.yml, closed-pr-review-auto-improver.yml). Consistency with codebase conventions takes precedence over theoretical supply chain hardening. |
Reviewers (2)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-devops |
4 | 0 | 1 | 0 | 1 | 0 | 1 |
pr-review-security-iam |
0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Total | 4 | 0 | 1 | 0 | 1 | 0 | 1 |
Note: IAM reviewer confirmed the authorization fix is correct and found no new issues — the empty return indicates the delta successfully addresses all prior security concerns.
|
|
||
| - name: Run Claude Code | ||
| id: claude | ||
| uses: anthropics/claude-code-action@v1 |
There was a problem hiding this comment.
💭 Consider: SHA pinning inconsistency with peer workflow
Issue: This workflow pins anthropics/claude-code-action to the mutable @v1 tag, while claude-code-review.yml pins the same action to a specific SHA (@01e756b34ef7a1447e9508f674143b07d20c2631) with a comment citing an AJV validation crash in newer versions (tracking issue #892).
Why: For consistency and to avoid the known AJV validation issue, consider using the same SHA pin here.
Fix:
| uses: anthropics/claude-code-action@v1 | |
| uses: anthropics/claude-code-action@01e756b34ef7a1447e9508f674143b07d20c2631 # Pinned for stability (tracking: #892) |
Refs:
|
@claude can you add a test comment at the start of the yaml file? We'll undo it in a subsequent request. |
51c9657 to
b4e1677
Compare
There was a problem hiding this comment.
PR Review Summary
(0) Total Issues | Risk: Low
This PR correctly elevates permissions for the claude.yml workflow to enable Claude to push commits when collaborators invoke @claude. The security controls are complete and appropriately implemented.
✅ What's Good
- Authorization guards complete: All 4 event types (issue_comment, pull_request_review_comment, pull_request_review, issues) require OWNER/MEMBER/COLLABORATOR association
- Permission scope appropriate:
contents: writefor pushing commits,pull-requests: writefor updating PRs,issues: writefor posting comments — all required byclaude-code-action - App token pattern correct: Uses
INTERNAL_CI_APP_IDmatching established patterns inrelease.yml,claude-code-review.yml, andclosed-pr-review-auto-improver.yml - Different security model than auto-review is intentional: Trusted collaborators already have write access; unrestricted Claude tools doesn't expand the attack surface
🕐 Pending Recommendations (1)
- 💭
.github/workflows/claude.yml:43SHA pinning inconsistency withclaude-code-review.yml
✅ APPROVE
Summary: All prior Critical and Major issues have been addressed. The author_association guards are correctly implemented, the permission elevation is justified for the use case, and the app token usage follows established repository patterns. The only open item is a minor "Consider" about SHA pinning for consistency with claude-code-review.yml (already raised in prior review). Ship it! 🚀
Discarded (2)
| Location | Issue | Reason Discarded |
|---|---|---|
.github/workflows/claude.yml:30 |
SHA pinning for actions/create-github-app-token@v1 |
Consistent with codebase conventions (release.yml, claude-code-review.yml, closed-pr-review-auto-improver.yml all use @v1). |
.github/workflows/claude.yml |
No --allowedTools restriction |
Addressed in prior review — intentional by design for human-triggered ad-hoc automation. |
Reviewers (2)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-devops |
4 | 0 | 0 | 0 | 0 | 1 | 2 |
pr-review-security-iam |
0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Total | 4 | 0 | 0 | 0 | 0 | 1 | 2 |
Note: IAM reviewer confirmed all security controls are appropriate — empty return indicates no security gaps.
Problem
When someone tags `@claude` on a PR to make a code change, Claude runs, makes the changes locally, but cannot push them back to the branch because `claude.yml` only has `contents: read`.
Claude's own comments confirm this has been silently failing:
This has been a recurring pattern across dozens of PRs — especially `@claude add a changeset` requests (PRs #1702, #1731, #1735, #1738, #1699, #1591, etc.) where Claude would run, report success, but the changeset file was never actually in the branch.
Fix
Three changes to `claude.yml`: