Skip to content

Guard Claude review workflow against non-collaborator PR authors#7761

Draft
adamsachs wants to merge 2 commits intomainfrom
fix/claude-review-author-association-guard
Draft

Guard Claude review workflow against non-collaborator PR authors#7761
adamsachs wants to merge 2 commits intomainfrom
fix/claude-review-author-association-guard

Conversation

@adamsachs
Copy link
Copy Markdown
Contributor

Description Of Changes

Adds an author_association check to the pull_request trigger condition in the Claude Code Review workflow, matching the existing guard on the issue_comment trigger. This prevents the review from running on PRs opened by non-org-members (e.g., fork PRs on this public repo).

Why: The issue_comment trigger already gates on ["OWNER","MEMBER","COLLABORATOR"] to prevent unauthorized spend. The pull_request trigger lacked the same guard, meaning fork PRs could trigger workflow runs — wasting runner minutes, creating failed-check noise, and leaving the workflow vulnerable if it were ever refactored to pull_request_target (which exposes secrets to fork PRs).

Code Changes

  • .github/workflows/claude-code-review.yml - Added author_association check to the pull_request condition, using the same trusted set as the existing issue_comment guard

Steps to Confirm

  1. Open a PR from a fork account (or check an existing fork PR) — the Claude review workflow should not trigger
  2. Open a PR from an org member — the Claude review workflow should trigger as before
  3. Comment /code-review as an org member — should still work (unchanged path)

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

adamsachs and others added 2 commits March 26, 2026 09:41
Add author_association check to the pull_request trigger condition,
matching the existing guard on issue_comment. Prevents the review
from running on PRs opened by non-org-members (fork PRs on public repo),
saving runner minutes and avoiding failed-check noise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
fides-plus-nightly Ignored Ignored Mar 26, 2026 1:44pm
fides-privacy-center Ignored Ignored Mar 26, 2026 1:44pm

Request Review

@adamsachs adamsachs marked this pull request as ready for review March 26, 2026 13:48
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 26, 2026

Greptile Summary

This PR adds a single-line author_association guard to the pull_request trigger in the Claude Code Review workflow, bringing it into parity with the identical guard that already exists on the issue_comment trigger. The fix prevents fork PRs from non-org-members from triggering the workflow, eliminating wasted runner minutes, spurious check failures, and a potential future attack surface if the workflow were ever migrated to pull_request_target.

  • The field used (github.event.pull_request.author_association) and the allowed-value set (["OWNER","MEMBER","COLLABORATOR"]) are both correct and exactly match the issue_comment counterpart at line 41.
  • No other workflow logic is affected; the issue_comment path is unchanged.
  • The changelog entry is well-formed and accurate.

Confidence Score: 5/5

Safe to merge — minimal, correct, security-improving change with no risk of breakage.

The change is a one-line addition that mirrors an existing, already-working guard. The field reference and allowed-values list are correct for the GitHub Actions event payload. No existing behaviour for trusted authors is altered, and the security gap for fork PRs is properly closed.

No files require special attention.

Important Files Changed

Filename Overview
.github/workflows/claude-code-review.yml Adds author_association guard to the pull_request trigger condition, mirroring the already-present guard on the issue_comment trigger. The field reference and allowed-values list are correct.
changelog/7761-claude-review-author-association-guard.yaml New changelog entry for the PR; type, description, and PR number are all correct.

Reviews (1): Last reviewed commit: "Add changelog entry for #7761" | Re-trigger Greptile

@adamsachs adamsachs requested review from daveqnet and nrxsmith March 26, 2026 13:50
github.event_name == 'pull_request'
&& !github.event.pull_request.draft
&& github.actor != 'dependabot[bot]'
&& contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this change break it? I don't see the Claude review.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for calling this out. so it is expected that claude will abort the review if the workflow definition differs from what's on main, as a security measure - so i thought that's what was happening here.

but actually it looks like the entire workflow was skipped on the 'ready for review' action, which is not the way the above would surface: the workflow should instead be executing but the review step itself should fail with an informative error about how the workflow differs from main.

so it does look like there may be a bug here, let me see 👀

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for visibility, here's claude's analysis:

There's the bug. Your author_association on this PR is CONTRIBUTOR, not MEMBER or COLLABORATOR.

  This is because author_association reflects your relationship to the repo, not the org. Since fides is a public/open-source repo, even org members who don't have direct collaborator permissions on the repo itself get classified as CONTRIBUTOR (meaning: has previously
  had a PR merged).

  The fix is to add "CONTRIBUTOR" to the allowed list. But that partially defeats the purpose — external contributors who've had a PR merged would also get CONTRIBUTOR.

  A better approach: use github.actor against the org membership instead, or just add CONTRIBUTOR since the real secret-protection comes from GitHub's fork PR secret isolation anyway. The author_association guard is defense-in-depth for runner minutes, and CONTRIBUTOR
  still excludes totally unknown first-time PR authors (FIRST_TIME_CONTRIBUTOR, FIRST_TIME_COMMITTER, NONE).

  Let me update the guard:

  Read 1 file (ctrl+o to expand)

:black_circle_for_record: Wait — let me reconsider the right approach here. The possible author_association values are:

  ┌────────────────────────┬──────────────────────────────────────┐
  │         Value          │               Meaning                │
  ├────────────────────────┼──────────────────────────────────────┤
  │ OWNER                  │ Owner of the repo                    │
  ├────────────────────────┼──────────────────────────────────────┤
  │ MEMBER                 │ Member of the org that owns the repo │
  ├────────────────────────┼──────────────────────────────────────┤
  │ COLLABORATOR           │ Invited collaborator on the repo     │
  ├────────────────────────┼──────────────────────────────────────┤
  │ CONTRIBUTOR            │ Has previously merged a PR           │
  ├────────────────────────┼──────────────────────────────────────┤
  │ FIRST_TIME_CONTRIBUTOR │ First PR to this repo                │
  ├────────────────────────┼──────────────────────────────────────┤
  │ FIRST_TIMER            │ First PR on all of GitHub            │
  ├────────────────────────┼──────────────────────────────────────┤
  │ NONE                   │ No association                       │
  └────────────────────────┴──────────────────────────────────────┘

  The fact that you're getting CONTRIBUTOR instead of MEMBER is surprising. You should be MEMBER as an org member. This might be a quirk of how the pull_request event payload populates author_association vs how the REST API returns it — or it could be that your org
  membership visibility is set to private.

  Either way, the safest fix is to include CONTRIBUTOR in the PR trigger's allow-list. This still excludes FIRST_TIME_CONTRIBUTOR, FIRST_TIMER, and NONE — which are the actual threat vectors for the spend concern.

given this info, we're going to see what makes the most sense here...

@adamsachs adamsachs marked this pull request as draft March 26, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants