Skip to content

Commit 3b70d8a

Browse files
authored
security: replace pull_request_target with pull_request (#111)
1 parent ca87414 commit 3b70d8a

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

.github/workflows/review-pr.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# types: [created]
88
# pull_request_review_comment: # Captures feedback on review comments for learning
99
# types: [created]
10-
# pull_request_target: # Triggers auto-review on PR open; uses base branch context so secrets work with forks
10+
# pull_request: # Triggers auto-review on PR open (same-repo branches only; fork PRs use /review)
1111
# types: [ready_for_review, opened]
1212
#
1313
# jobs:
@@ -108,12 +108,15 @@ jobs:
108108
# ==========================================================================
109109
# AUTOMATIC REVIEW FOR ORG MEMBERS
110110
# Triggers when a PR is marked ready for review or opened (non-draft)
111-
# Only runs for members of the configured org (supports fork-based workflow)
111+
# Only runs for members of the configured org; same-repo branches only — fork PRs use /review command
112+
# Only runs for same-repo PRs (fork PRs don't have access to secrets with pull_request trigger)
113+
# Fork PRs use the /review command instead
112114
# ==========================================================================
113115
auto-review:
114116
if: |
115-
github.event_name == 'pull_request_target' &&
116-
!github.event.pull_request.draft
117+
github.event_name == 'pull_request' &&
118+
!github.event.pull_request.draft &&
119+
github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name
117120
runs-on: ubuntu-latest
118121
env:
119122
HAS_APP_SECRETS: ${{ secrets.CAGENT_REVIEWER_APP_ID != '' }}
@@ -154,7 +157,7 @@ jobs:
154157
}
155158
}
156159
157-
# Safe to checkout PR head because review-pr only READS files (no code execution)
160+
# With pull_request, checking out the PR head is standard behavior
158161
- name: Checkout PR head
159162
if: steps.membership.outputs.is_member == 'true'
160163
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -342,9 +345,8 @@ jobs:
342345
# ==========================================================================
343346
# CAPTURE FEEDBACK
344347
# Saves feedback data as an artifact for lazy processing. This job
345-
# intentionally avoids using secrets so it works for fork PRs in public
346-
# repos. The actual AI processing happens during the next review run,
347-
# which has full secret access via pull_request_target or issue_comment.
348+
# intentionally avoids using secrets. The actual AI processing happens
349+
# during the next review run, which has full secret access via issue_comment.
348350
# ==========================================================================
349351
capture-feedback:
350352
if: github.event_name == 'pull_request_review_comment' && github.event.comment.in_reply_to_id

.github/workflows/self-review-pr.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
types: [created]
1111
pull_request_review_comment:
1212
types: [created]
13-
pull_request_target:
13+
pull_request:
1414
types: [ready_for_review, opened]
1515

1616
permissions:
@@ -23,12 +23,15 @@ jobs:
2323
# ==========================================================================
2424
# AUTOMATIC REVIEW FOR ORG MEMBERS
2525
# Triggers when a PR is marked ready for review or opened (non-draft)
26-
# Only runs for members of the docker org (supports fork-based workflow)
26+
# Only runs for members of the docker org; auto-reviews same-repo PRs from org members
27+
# Only runs for same-repo PRs (fork PRs don't have access to secrets with pull_request trigger)
28+
# Fork PRs use the /review command instead
2729
# ==========================================================================
2830
auto-review:
2931
if: |
30-
github.event_name == 'pull_request_target' &&
31-
!github.event.pull_request.draft
32+
github.event_name == 'pull_request' &&
33+
!github.event.pull_request.draft &&
34+
github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name
3235
runs-on: ubuntu-latest
3336
env:
3437
HAS_APP_SECRETS: ${{ secrets.CAGENT_REVIEWER_APP_ID != '' }}
@@ -67,7 +70,7 @@ jobs:
6770
}
6871
}
6972
70-
# Safe to checkout PR head because review-pr only READS files (no code execution)
73+
# With pull_request, checking out the PR head is standard behavior
7174
- name: Checkout PR head
7275
if: steps.membership.outputs.is_member == 'true'
7376
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -247,10 +250,9 @@ jobs:
247250
# ==========================================================================
248251
# CAPTURE FEEDBACK
249252
# Saves feedback data as an artifact for the workflow_run-triggered
250-
# reply-to-feedback workflow. This job intentionally avoids using secrets
251-
# so it works for fork PRs in public repos. The reply-to-feedback.yml
252-
# workflow runs via workflow_run in the base repo context with full
253-
# permissions and secrets.
253+
# reply-to-feedback workflow. This job intentionally avoids using secrets.
254+
# The reply-to-feedback.yml workflow runs via workflow_run in the base
255+
# repo context with full permissions and secrets.
254256
# ==========================================================================
255257
capture-feedback:
256258
if: github.event_name == 'pull_request_review_comment' && github.event.comment.in_reply_to_id

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ on:
5454
types: [created]
5555
pull_request_review_comment: # Captures feedback on review comments for learning
5656
types: [created]
57-
pull_request_target: # Triggers auto-review on PR open; uses base branch context so secrets work with forks
57+
pull_request: # Triggers auto-review on PR open (same-repo branches only; fork PRs use /review)
5858
types: [ready_for_review, opened]
5959
6060
permissions:
61-
contents: read # This is required to be a top-level permission to give `issue_comment` events (on forked PRs) access to the secrets below.
61+
contents: read # Required at top-level to give `issue_comment` events access to the secrets below.
6262

6363
jobs:
6464
review:
@@ -76,6 +76,8 @@ jobs:
7676
CAGENT_REVIEWER_APP_PRIVATE_KEY: ${{ secrets.CAGENT_REVIEWER_APP_PRIVATE_KEY }} # GitHub App private key; paired with App ID above
7777
```
7878
79+
> **Note:** Auto-review runs on same-repo branches only — fork PRs are automatically skipped (secrets aren't available). For fork PRs, an org member can comment `/review` to trigger a review.
80+
7981
See the [full PR Review documentation](review-pr/README.md) for more details.
8082

8183
### Using a Local Agent File

review-pr/README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ on:
1515
types: [created]
1616
pull_request_review_comment: # Captures feedback on review comments for learning
1717
types: [created]
18-
pull_request_target: # Triggers auto-review on PR open; uses base branch context so secrets work with forks
18+
pull_request: # Triggers auto-review on PR open (same-repo branches only; fork PRs use /review)
1919
types: [ready_for_review, opened]
2020

2121
permissions:
22-
contents: read # This is required to be a top-level permission to give `issue_comment` events (on forked PRs) access to the secrets below.
22+
contents: read # Required at top-level to give `issue_comment` events access to the secrets below.
2323

2424
jobs:
2525
review:
@@ -37,6 +37,8 @@ jobs:
3737
CAGENT_REVIEWER_APP_PRIVATE_KEY: ${{ secrets.CAGENT_REVIEWER_APP_PRIVATE_KEY }} # GitHub App private key; paired with App ID above
3838
```
3939
40+
> **Note:** Auto-review runs on same-repo branches only — fork PRs are automatically skipped (secrets aren't available). For fork PRs, an org member can comment `/review` to trigger a review.
41+
4042
> **Why explicit secrets instead of `secrets: inherit`?** This follows the principle of least privilege — the called workflow only receives the secrets it actually needs, not every secret in your repository. This is the recommended approach for public repos and security-conscious teams.
4143

4244
### Customizing for your organization
@@ -53,7 +55,7 @@ The workflow automatically handles:
5355

5456
| Trigger | Behavior |
5557
| ----------------------- | --------------------------------------------------------------------------------------- |
56-
| PR opened/ready | Auto-reviews PRs from your org members (if `CAGENT_ORG_MEMBERSHIP_TOKEN` is configured) |
58+
| PR opened/ready | Auto-reviews PRs from your org members (same-repo branches only; fork PRs use `/review`) |
5759
| `/review` comment | Manual review on any PR (shows as a check run on the PR if `checks: write` is granted) |
5860
| Reply to review comment | Responds in-thread and learns from feedback to improve future reviews |
5961

@@ -359,7 +361,7 @@ When you reply to a review comment, two things happen in parallel:
359361
5. The agent also stores learnings in the memory database for future reviews
360362

361363
**Async artifact capture** (`capture-feedback` job):
362-
1. Saves the feedback as a GitHub Actions artifact (no secrets required — works for fork PRs)
364+
1. Saves the feedback as a GitHub Actions artifact (no secrets required)
363365
2. On the next review run, pending feedback artifacts are downloaded and processed into the memory database
364366
3. Acts as a resilient fallback if the reply agent fails or isn't configured
365367

@@ -471,7 +473,7 @@ Each eval file in `review-pr/agents/evals/` contains:
471473
**No check run showing on the PR?**
472474

473475
- Add `checks: write` to your workflow permissions (it's optional — the review works without it)
474-
- Check runs are created for manual (`/review`) triggers. Auto-reviews from `pull_request_target` already appear as workflow runs natively
476+
- Check runs are created for manual (`/review`) triggers. Auto-reviews from `pull_request` already appear as workflow runs natively
475477

476478
**Learning doesn't seem to work?**
477479

0 commit comments

Comments
 (0)