fix(reviewer): never post agy's OAuth login prompt to a PR - #332
Conversation
When agy's cached Google OAuth session lapses on the self-hosted runner, `agy --print` emits its INTERACTIVE login flow to stdout instead of a review -- a live-shaped `accounts.google.com/o/oauth2/...` authorization URL plus a "paste the authorization code here" prompt and an "authentication failed or timed out" tail. That text is non-empty, so `have_text()` classified it as a valid review and the script posted it verbatim as a public PR comment. Incident: it landed on PR #330 (a Dependabot bump) as a "github-actions" review comment carrying the OAuth URL -- noise, phishing-shaped content, and an advertisement that the runner's auth had dropped. That comment has been removed. Root cause: the capture pipeline had no notion of "agy produced output, but the output is an auth prompt, not a review." `have_text()` only checks for non-whitespace bytes. Fix -- two independent layers, plus a helper: * is_auth_prompt() (new): true when a captured file carries agy's interactive-login signature -- the accounts.google.com OAuth endpoint URL, "paste the authorization code", "Authentication required. Please visit", "Waiting for authentication", or "authentication failed or timed out". Keyed on agy runtime strings a genuine review never emits, so a review that merely discusses "authentication" is not misclassified (verified against a benign review sample). * Layer 1 (retry loop): after CR-normalizing each attempt's capture and before the have_text() success break, reject an auth-prompt capture as a hard, NON-retryable failure. Re-auth is a human action on the runner host, so retrying only thrashes the backoff. Blank the capture (so no later path can post it), set auth_failed=1, and break. A dedicated post-loop branch then exits non-zero with an actionable message, ahead of the generic empty-output path. * Layer 3 (pre-post): a final hard guard immediately before `gh pr comment` -- if the fully assembled body still trips the auth-prompt signature, refuse to post and fail the job. This is the last line of defense: a public PR comment must never carry an OAuth URL regardless of any upstream change to body assembly. Behavior on a healthy, authenticated runner is unchanged: a real review never matches is_auth_prompt, so it posts exactly as before. Only the lapsed-session path changes -- from "leak the OAuth URL" to "fail loudly in the job log, post nothing." Syntax-checked (`bash -n`) and the signature validated against the exact leaked comment text, a benign authentication-discussing review, and empty output. Synced byte-identical across the shared reviewer template and RustyNES / RustySNES / RustyN64 (single source of truth). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 39 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Comment |
Antigravity review (Gemini via Ultra)This PR adds detection logic ( Blocking issuesNone found. Suggestions
Nitpicks
Automated first-pass review by |
|
@coderabbitai Full Review |
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 40 minutes. |
Summary
The Antigravity (
agy) PR reviewer leaked its interactive Google OAuth login flow into a public PR comment. This hardens the reviewer so that can never happen again — a change shared byte-identical across the reviewer template and all threeRusty*repos.What happened
On PR #330 (a routine Dependabot bump), the
github-actionsreviewer posted an "Authentication required" comment containing a live-shapedaccounts.google.com/o/oauth2/...authorization URL, a "paste the authorization code here" prompt, and an "authentication failed or timed out" tail. That happens when agy's cached Google OAuth session lapses on the self-hosted runner:agy --printemits its interactive login flow to stdout instead of a review. The text is non-empty, sohave_text()classified it as a valid review and the script posted it verbatim.The offending comment has already been deleted from #330.
The fix (defense in depth)
is_auth_prompt()(new helper) — detects agy's interactive-login signature (the OAuth endpoint URL + agy's own prompt strings). Keyed on runtime strings a genuine review never emits, so a review that merely discusses authentication is not misclassified.gh pr comment, if the assembled body still trips the signature, refuse to post and fail the job. Last line of defense — a public comment must never carry an OAuth URL, whatever upstream does.Behavior on a healthy, authenticated runner is unchanged: a real review never matches, so it posts exactly as before. Only the lapsed-session path changes — from "leak the OAuth URL" to "fail loudly in the job log, post nothing."
Verification
bash -nclean.is_auth_prompt()validated against the exact leaked comment text (matches → blocked), a benign review that discusses "authentication" (no match → posts), and empty output (no match).Note for the maintainer
The runner's agy OAuth session is currently lapsed (that is why the prompt appeared). Reviews will resume once agy is re-authenticated on the runner host; until then this change makes the reviewer fail cleanly instead of leaking. Companion PRs sync the same fix into RustySNES and RustyN64.
🤖 Generated with Claude Code