From 368b2271d1d4c086d2f5bb32c655d0f225fb3474 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Tue, 2 Dec 2025 21:00:18 +0200 Subject: [PATCH 1/6] github: annotate permission requirements So I don't get lost in why each write permission is necessary. --- .github/workflows/dependabot-automerge.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 2db52ea..cf8e5dd 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -31,10 +31,10 @@ on: - '.github/workflows/**' permissions: - contents: write - pull-requests: write - id-token: write # Required for Claude to generate GitHub app tokens - actions: read # Required for Claude to read CI results on PRs + contents: write # Required by: gh pr merge --auto + pull-requests: write # Required by: gh pr review --approve + id-token: write # Required for Claude to generate GitHub app tokens + actions: read # Required for Claude to read CI results on PRs jobs: metadata: From 8ba976d32f4f7044d4405e743a04c5d63ff6aa70 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Tue, 2 Dec 2025 21:18:21 +0200 Subject: [PATCH 2/6] github: remove actions permissions for dependabot jobs There's no value in reading the CI status while reacting to Dependabot PRs, as the interesting statuses are not updated until afterwards in time because CI takes longer to complete. --- .github/workflows/dependabot-automerge.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index cf8e5dd..9075e65 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -34,7 +34,6 @@ permissions: contents: write # Required by: gh pr merge --auto pull-requests: write # Required by: gh pr review --approve id-token: write # Required for Claude to generate GitHub app tokens - actions: read # Required for Claude to read CI results on PRs jobs: metadata: From 44022a3bbae54ce3ff75bd88f7636c9f5b1dbb90 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Tue, 2 Dec 2025 21:56:25 +0200 Subject: [PATCH 3/6] github: review Dependabot pull-requests using gh CLI commands This avoids the security concern of checking out untrusted PR code while running with pull_request_target permissions, which grants write access to the repository. --- .github/workflows/dependabot-automerge.yml | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 9075e65..d48e0d6 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -84,13 +84,6 @@ jobs: needs: metadata if: needs.metadata.outputs.update-type == 'version-update:semver-minor' steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We need the code at PR's head because pull_request_target checks - # out main by default. - ref: ${{ github.event.pull_request.head.sha }} - - name: Review and approve uses: anthropics/claude-code-action@v1 with: @@ -102,9 +95,11 @@ jobs: Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} - Review the changes in this PR. Minor updates should be backwards-compatible. - If the changes look reasonable, approve the PR with a message that includes - your model identifier (e.g. "Reviewed by claude-sonnet-4-20250514"). + Review the changes in this PR using `gh pr diff` and `gh pr view`. + + Minor updates should be backwards-compatible. If the changes look + reasonable, approve the PR with a message that includes your model + identifier (e.g. "Reviewed by claude-sonnet-4-20250514"). Use: gh pr review --approve --body "your message" claude_args: '--allowedTools "Bash(gh pr:*)" --max-turns 25' @@ -127,13 +122,6 @@ jobs: needs.metadata.outputs.update-type == 'version-update:semver-major' && needs.metadata.outputs.package-ecosystem == 'github_actions' steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We need the code at PR's head because pull_request_target checks - # out main by default. - ref: ${{ github.event.pull_request.head.sha }} - - name: Review and suggest fixes uses: anthropics/claude-code-action@v1 with: @@ -145,6 +133,8 @@ jobs: Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} + Review the changes in this PR using `gh pr diff` and `gh pr view`. + Major updates may have breaking changes. Please: 1. Fetch the action's release page and CHANGELOG to understand what changed From e06a2af598d99b44bd615ff10b59f93b5df40b35 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Tue, 2 Dec 2025 23:34:17 +0200 Subject: [PATCH 4/6] github: revert to pull_request trigger for Dependabot workflow The pull_request_target trigger was intended to satisfy OIDC requirements for Claude Code's GitHub app impersonation, but this approach does not work with Dependabot PRs. See anthropics/claude-code-action#713 --- .github/workflows/dependabot-automerge.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index d48e0d6..ddaacfa 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -19,10 +19,13 @@ name: "🤖 ClauDependabot" on: - # Claude Code uses OIDC for GitHub app impersonation, which requires the - # workflow to match main. This trigger satisfies this requirement, even when - # Dependabot updates this file. - pull_request_target: + # Using pull_request (not pull_request_target) because the OIDC approach for + # GitHub app impersonation does not appear to work with Dependabot PRs. + # See: https://github.com/anthropics/claude-code-action/issues/713 + # + # This means Claude jobs will fail if Dependabot updates this file itself, + # but we've minimized actions here to reduce that risk. + pull_request: # Path filter avoids creating workflow runs for unrelated PRs while still # catching all Dependabot updates (Go modules and GitHub Actions). paths: From 9e556a7dd3c41339538a02773fe8621205e36bf9 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Wed, 3 Dec 2025 01:10:02 +0200 Subject: [PATCH 5/6] github: include package ecosystem in Dependabot review prompts The major job now runs for all ecosystems, not just github_actions. GitHub Actions-specific guidance is preserved in a conditional section within the prompt itself. --- .github/workflows/dependabot-automerge.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index ddaacfa..2029b04 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -94,6 +94,7 @@ jobs: prompt: | This is a Dependabot PR for a minor version update. + Package ecosystem: ${{ needs.metadata.outputs.package-ecosystem }} Dependency: ${{ needs.metadata.outputs.dependency-names }} Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} @@ -121,18 +122,17 @@ jobs: name: Advise major runs-on: ubuntu-latest needs: metadata - if: | - needs.metadata.outputs.update-type == 'version-update:semver-major' && - needs.metadata.outputs.package-ecosystem == 'github_actions' + if: needs.metadata.outputs.update-type == 'version-update:semver-major' steps: - name: Review and suggest fixes uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | - This is a Dependabot PR for a MAJOR version update of a GitHub Action. + This is a Dependabot PR for a MAJOR version update. - Action: ${{ needs.metadata.outputs.dependency-names }} + Package ecosystem: ${{ needs.metadata.outputs.package-ecosystem }} + Dependency: ${{ needs.metadata.outputs.dependency-names }} Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} @@ -140,11 +140,15 @@ jobs: Major updates may have breaking changes. Please: - 1. Fetch the action's release page and CHANGELOG to understand what changed + 1. Fetch the dependency's release page and CHANGELOG to understand what changed 2. Check the README for migration guides - 3. Review the workflow files in .github/workflows/ that use this action + 3. Review the codebase for usages of this dependency 4. If changes are needed, comment on the PR with suggested fixes + For github_actions ecosystem specifically: + - Review the workflow files in .github/workflows/ that use this action + - Check for deprecated inputs, outputs, or runner requirements + Do NOT approve, merge, or push commits to this PR. Use `gh pr comment` to post your analysis and any suggested code changes. claude_args: '--allowedTools "Bash(gh pr:*),WebFetch,WebSearch" --max-turns 50' From 9539c0bd02159d36355f9b518586c6509e0f3228 Mon Sep 17 00:00:00 2001 From: Daniel Orbach Date: Wed, 3 Dec 2025 01:51:44 +0200 Subject: [PATCH 6/6] github: tighten Claude tool permissions for Dependabot reviews Prompts now clarify there is no local checkout available. Minor reviews allow gh pr diff, view, and review (but not merge). Major reviews restrict to comment-only with explicit disallow rules for approval commands. --- .github/workflows/dependabot-automerge.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 2029b04..f73374a 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -99,14 +99,17 @@ jobs: Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} - Review the changes in this PR using `gh pr diff` and `gh pr view`. + There is no local checkout of the repository. Use `gh pr diff` and + `gh pr view` to review the changes. Minor updates should be backwards-compatible. If the changes look reasonable, approve the PR with a message that includes your model identifier (e.g. "Reviewed by claude-sonnet-4-20250514"). Use: gh pr review --approve --body "your message" - claude_args: '--allowedTools "Bash(gh pr:*)" --max-turns 25' + claude_args: >- + --allowedTools "Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr review:*)" + --max-turns 25 - name: Enable auto-merge run: gh pr merge --auto --squash "$PR_URL" --body "$BODY" @@ -136,7 +139,8 @@ jobs: Update: ${{ needs.metadata.outputs.previous-version }} → ${{ needs.metadata.outputs.new-version }} PR: ${{ github.event.pull_request.html_url }} - Review the changes in this PR using `gh pr diff` and `gh pr view`. + There is no local checkout of the repository. Use `gh pr diff` and + `gh pr view` to review the changes. Major updates may have breaking changes. Please: @@ -150,6 +154,9 @@ jobs: - Check for deprecated inputs, outputs, or runner requirements Do NOT approve, merge, or push commits to this PR. - Use `gh pr comment` to post your analysis and any suggested code changes. - claude_args: '--allowedTools "Bash(gh pr:*),WebFetch,WebSearch" --max-turns 50' + Use `gh pr review --comment` to post your analysis and any suggested code changes. + claude_args: >- + --allowedTools "Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr review --comment:*),Bash(gh pr review -c:*),WebFetch,WebSearch" + --disallowedTools "Bash(gh pr review --approve:*),Bash(gh pr review -a:*)" + --max-turns 50