mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 14:07:55 +00:00
The Claude automation workflows (claude-issues.yml, claude-review.yml)
trigger on public, attacker-controllable events (issues, issue_comment,
pull_request_review_comment) and grant the job secrets.ANTHROPIC_API_KEY
plus a write-scoped GITHUB_TOKEN with NO author-association gate.
Because issues / issue_comment / pull_request_review_comment always run in
the base-repo context with full secret access (unlike fork pull_request,
from which GitHub withholds secrets), any external GitHub user could fire
these jobs — draining the API budget and, via contents:write +
pull-requests:write, creating branches/PRs.
Fix:
- Add an author-association gate to every human-triggered, secret-bearing
if: clause, restricting to OWNER / MEMBER / COLLABORATOR. Uses the correct
event payload field per trigger: github.event.issue.author_association for
the `issues` event, github.event.comment.author_association for
issue_comment and pull_request_review_comment. workflow_dispatch stays
trusted (requires repo write to invoke).
- Drop unused id-token: write from both workflows (claude-code-action@v1 is
passed github_token directly, so OIDC is unused).
- Reduce claude-issues.yml timeout-minutes 60 -> 15.
desktop.yml and take-assign.yml are intentionally NOT touched: independently
verified as not exploitable for ANTHROPIC_API_KEY (desktop.yml's only
pull_request job uses no secrets and the trigger is plain pull_request, not
pull_request_target; take-assign.yml uses only GITHUB_TOKEN with issues:write
and no checkout/no Anthropic key). claude-review.yml's stale pull_request
auto-trigger was already removed in 3f2f46e4.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
3.8 KiB
YAML
87 lines
3.8 KiB
YAML
name: Claude Issue Fixer
|
|
|
|
on:
|
|
issues:
|
|
types: [opened, labeled]
|
|
issue_comment:
|
|
types: [created]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: claude-issues-${{ github.event.issue.number || github.run_id }}
|
|
cancel-in-progress: true
|
|
|
|
# Least-privilege: only what the issue-fixer job actually needs.
|
|
# id-token (OIDC) is intentionally omitted — claude-code-action@v1 is passed
|
|
# github_token directly, so OIDC is unused here.
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
issues: write
|
|
|
|
jobs:
|
|
fix:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
# Security gate: this job reaches secrets.ANTHROPIC_API_KEY and holds a
|
|
# write-scoped GITHUB_TOKEN. `issues` / `issue_comment` are public,
|
|
# attacker-controllable events that run in the base-repo context with full
|
|
# secret access, so the human-triggered paths are restricted to actors with
|
|
# write-level association (OWNER / MEMBER / COLLABORATOR). This blocks
|
|
# external / first-time contributors from draining the API budget or
|
|
# creating branches/PRs, while leaving maintainer use unaffected.
|
|
if: |
|
|
github.event_name == 'workflow_dispatch' ||
|
|
(github.event_name == 'issues' &&
|
|
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association) &&
|
|
(contains(github.event.issue.labels.*.name, 'bug') ||
|
|
contains(github.event.issue.labels.*.name, 'autofix'))) ||
|
|
(github.event_name == 'issue_comment' &&
|
|
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&
|
|
!github.event.issue.pull_request &&
|
|
contains(github.event.comment.body, '@claude') &&
|
|
github.actor != 'claude[bot]')
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- uses: anthropics/claude-code-action@v1
|
|
with:
|
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
prompt: |
|
|
You are an automated issue fixer for the OpenJarvis repository. Follow these steps in order:
|
|
|
|
## Step 1: Diagnose
|
|
Read the issue thoroughly. Explore the codebase to understand the problem. If this is a bug report, attempt to reproduce it. Identify the root cause and affected files.
|
|
|
|
## Step 2: Comment your plan
|
|
BEFORE making any code changes, post a comment on this issue describing:
|
|
- Your root cause analysis
|
|
- Which files need to change and why
|
|
- Your implementation approach
|
|
|
|
## Step 3: Implement
|
|
Create a branch named `claude/issue-${{ github.event.issue.number }}` and make the changes. Use conventional commit messages that reference the issue, e.g.:
|
|
`fix: handle empty tool responses in orchestrator (fixes #${{ github.event.issue.number }})`
|
|
|
|
## Step 4: Test
|
|
Run these commands and ensure both pass:
|
|
- `uv run ruff check src/ tests/` (linting)
|
|
- `uv run pytest tests/ -v --tb=short` (tests)
|
|
|
|
If tests fail, fix the issues before proceeding. If you added new functionality, add corresponding tests in `tests/` mirroring the `src/` directory structure.
|
|
|
|
## Step 5: Open PR
|
|
Create a pull request that:
|
|
- Links back to this issue (include `Fixes #${{ github.event.issue.number }}` in the PR body)
|
|
- Describes what was changed and why
|
|
- Includes a summary of test results
|
|
|
|
## If you cannot fix it
|
|
If you cannot reproduce the issue, cannot determine the root cause, or the fix is beyond your capabilities, post a comment explaining:
|
|
- What you investigated
|
|
- What you found (or didn't find)
|
|
- What additional information you need from the reporter
|