surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
Move the three workflow jobs that sign in to the Claude API (claude.yml, claude-issue-triage.yml, claude-dedupe-issues.yml) from ubuntu-latest to GitHub's egress-firewall runner (ubuntu-24.04-firewall), and pass --permission-mode auto to the Claude Code action in the triage and dedupe steps. In auto permission mode Claude Code reviews each tool call that needs permission and that the command's allowed-tools list does not cover, and runs it only if Claude Code's safety review passes it. Until now these runs, which have nobody to ask, refused every such call. Anyone can start both jobs by opening an issue, and the triage job also by commenting on one, so both steps also pass a --disallowedTools list for tools they never need. claude.yml answers @claude mentions, and for those the action sets --permission-mode acceptEdits itself. Its permission mode is unchanged. Allowed tools, models, triggers and permissions are unchanged. The network allow list for the firewall follows in the next change.
| M.github/workflows/claude-dedupe-issues.yml |
| M.github/workflows/claude-issue-triage.yml |
| M.github/workflows/claude.yml |
| @@ -12,7 +12,9 @@ | ||
| 12 | 12 | |
| 13 | 13 | jobs: |
| 14 | 14 | claude-dedupe-issues: |
| 15 | - runs-on: ubuntu-latest | |
| 15 | + # This job calls Claude, so it runs on GitHub's egress-firewall runner, which | |
| 16 | + # filters the job's outbound network traffic (allow list: .github/egress-firewall.yaml). | |
| 17 | + runs-on: ubuntu-24.04-firewall | |
| 16 | 18 | timeout-minutes: 10 |
| 17 | 19 | permissions: |
| 18 | 20 | contents: read |
| @@ -40,7 +42,10 @@ | ||
| 40 | 42 | anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }} |
| 41 | 43 | anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }} |
| 42 | 44 | anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }} |
| 43 | - claude_args: "--model claude-sonnet-4-5-20250929" | |
| 45 | + # --permission-mode auto: a tool call that needs permission and is outside the allowed-tools | |
| 46 | + # list in .claude/commands/dedupe.md runs only if Claude Code's safety review passes it. | |
| 47 | + # Tools in --disallowedTools never run. | |
| 48 | + claude_args: '--model claude-sonnet-4-5-20250929 --permission-mode auto --disallowedTools "WebFetch,WebSearch,Write,Edit,MultiEdit,NotebookEdit"' | |
| 44 | 49 | |
| 45 | 50 | - name: Log duplicate comment event to Statsig |
| 46 | 51 | if: always() |
| @@ -7,7 +7,9 @@ | ||
| 7 | 7 | |
| 8 | 8 | jobs: |
| 9 | 9 | triage-issue: |
| 10 | - runs-on: ubuntu-latest | |
| 10 | + # This job calls Claude, so it runs on GitHub's egress-firewall runner, which | |
| 11 | + # filters the job's outbound network traffic (allow list: .github/egress-firewall.yaml). | |
| 12 | + runs-on: ubuntu-24.04-firewall | |
| 11 | 13 | timeout-minutes: 10 |
| 12 | 14 | if: >- |
| 13 | 15 | github.event_name == 'issues' || |
| @@ -43,5 +45,10 @@ | ||
| 43 | 45 | anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }} |
| 44 | 46 | anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }} |
| 45 | 47 | anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }} |
| 48 | + # --permission-mode auto: a tool call that needs permission and is outside the allowed-tools | |
| 49 | + # list in .claude/commands/triage-issue.md runs only if Claude Code's safety review passes | |
| 50 | + # it. Tools in --disallowedTools never run. | |
| 46 | 51 | claude_args: | |
| 52 | + --permission-mode auto | |
| 53 | + --disallowedTools "WebFetch,WebSearch,Write,Edit,MultiEdit,NotebookEdit" | |
| 47 | 54 | --model claude-opus-4-6 |
| @@ -17,7 +17,9 @@ | ||
| 17 | 17 | (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || |
| 18 | 18 | (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || |
| 19 | 19 | (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) |
| 20 | - runs-on: ubuntu-latest | |
| 20 | + # This job calls Claude, so it runs on GitHub's egress-firewall runner, which | |
| 21 | + # filters the job's outbound network traffic (allow list: .github/egress-firewall.yaml). | |
| 22 | + runs-on: ubuntu-24.04-firewall | |
| 21 | 23 | permissions: |
| 22 | 24 | contents: read |
| 23 | 25 | pull-requests: read |