From 913974fe359adbc4e6376cf29e6f773b377664ff Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Mon, 9 Mar 2026 09:35:36 -0700 Subject: [PATCH 1/2] fix(claude-assistant): remove actions: read from GITHUB_TOKEN permissions The actions: read permission is not included in the default read-only GITHUB_TOKEN scope even when default_workflow_permissions is 'read'. When a reusable workflow requests a permission the caller cannot provide through its inherited defaults, GitHub fails the entire workflow run with startup_failure before creating any jobs. Removing actions: read from the permissions block fixes startup_failure across all consumer repos without requiring changes to any caller. Claude can still read CI results via the claude-code-action's own authentication (additional_permissions: actions: read remains, which the action handles through its own auth, not the GITHUB_TOKEN). Fixes: consistent startup_failure on all Claude Code workflow triggers AI review: pending pre-commit hook --- .github/workflows/claude-assistant.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/claude-assistant.yml b/.github/workflows/claude-assistant.yml index 39b1fbc..371bde4 100644 --- a/.github/workflows/claude-assistant.yml +++ b/.github/workflows/claude-assistant.yml @@ -31,7 +31,6 @@ jobs: contents: read pull-requests: read issues: read - actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 From 4fb65bde3c1c5c13e3a13d90c16db0d24c1e1ebd Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Mon, 9 Mar 2026 09:41:34 -0700 Subject: [PATCH 2/2] fix(claude): add explicit permissions block to thin caller Add permissions block to claude.yml (the github-workflows repo's own thin caller) and update the usage comment in claude-assistant.yml to show callers should include it. Explicit permissions are required because: - GitHub Actions security scanner flags callers without explicit scopes - id-token: write is needed by claude-code-action for internal auth - Without it, the caller inherits default read-only scopes but without the explicit declaration that makes the security scanner happy Addresses security/code-scanning alert #1 (actions/missing-workflow-permissions). --- .github/workflows/claude-assistant.yml | 5 +++++ .github/workflows/claude.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/.github/workflows/claude-assistant.yml b/.github/workflows/claude-assistant.yml index 371bde4..b1052a3 100644 --- a/.github/workflows/claude-assistant.yml +++ b/.github/workflows/claude-assistant.yml @@ -13,6 +13,11 @@ name: Claude Code Assistant # (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)) +# permissions: +# contents: read +# issues: read +# pull-requests: read +# id-token: write # required by claude-code-action for internal authentication # uses: smartwatermelon/github-workflows/.github/workflows/claude-assistant.yml@v1 # secrets: # claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 832c3e5..beb034e 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -17,6 +17,11 @@ jobs: (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)) + permissions: + contents: read + issues: read + pull-requests: read + id-token: write # required by claude-code-action for internal authentication uses: smartwatermelon/github-workflows/.github/workflows/claude-assistant.yml@v1 secrets: claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}