ci: scan issue and comment bodies — this repo has never scanned one - #56
ci: scan issue and comment bodies — this repo has never scanned one#56yakimoto wants to merge 6 commits into
Conversation
…ment body Measured across all 28 public wave-av repos (claude-workstation#1747, #1794): TWO coverage shapes satisfy the one required check name `Secrets + content policy`. 27 repos triggers: pull_request, push, workflow_dispatch jobs: guard 1 repo triggers: + issues, issue_comment jobs: + body-guard This repo is in the 27. All 28 report the same green check. The outlier is wave-moq-edge, and its own comment says why it matters: "`edited` matters as much as `opened`: a body can be made to leak long after the PR is first raised, and until this workflow covered it, nothing ever re-scanned." A PR/issue/comment BODY is exactly as world-readable as the tree, and until now it was scanned by nothing server-side. That gap was not theoretical on wave-moq-edge: a PR was blocked for naming a private repo in wrangler.toml while the very same name, with more operational detail attached, sat unchallenged in its body. WHAT LANDS HERE — the bundle the workflow's own header names, minus what this repo already has (.gitleaks.toml and content-policy.sh are already vendored): .github/workflows/public-repo-guard.yml replaced (73 -> 163 lines) scripts/public-repo-guard/body-policy.sh new, mode 100755 scripts/public-repo-guard/tests/body-policy.test.sh new, mode 100755 Copied from wave-moq-edge, which has run this shape in production. Modes preserved via the git trees API — the contents API would have created both scripts 100644. HONEST ABOUT WHAT IT CAN DO. On a PR this PREVENTS the merge. On an issue or comment the text is already public the moment it posts, so this is DETECTION: it says go redact, fast. Only a client-side pre-write hook stops that class before publication. Also inherited from the reference: concurrency moves from workflow-level to PER JOB, because the two jobs want opposite behaviour. A workflow-level group forced one policy on both, and rapid body edits cancelled the tree job repeatedly — every cancelled check-run stays attached to the commit, so the PR reported UNSTABLE while the live runs were green. The body gate ships with its own fixtures and runs them in CI. Its NEGATIVE cases are the load-bearing half: a leak gate that blocks legitimate cross-repo references gets switched off, and then it protects nothing. Refs wave-av/claude-workstation#1747. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are limited based on label configuration. 🚫 Excluded labels (none allowed) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_11ee7f73-d241-42ec-9bb8-7afe2dd756e1) |
|
Running ultrareview automatically — This rewires the org's security gate: new body-scanning job, event triggers, concurrency policy, and a fail-closed regex scanner with its own allowlist — a bug here could silently miss leaks or break the required check across repos, so it warrants a deeper pass.. I'll post findings when complete. |
ApprovabilityVerdict: Needs human review Unable to check for correctness in 3716e82. This PR introduces a new body-scanning security gate with significant scope. The author does not own the modified files (owned by wave-av/sdk-owners), and there's an unresolved comment identifying a potential bug where some review comments could silently go unscanned due to concurrency grouping. You can customize Macroscope's approvability policy. Learn more. |
PR Summary by QodoAdd issue/comment body scanning to public-repo-guard CI
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1.
|
Qodo Fixer🍒 Ready to be cherry-picked — ✅ Merged (0) · ☑ Fixed (1) 🔗 Fix PR: #57 This fix PR was closed automatically. Its branch is preserved so you can cherry pick the changes into the original PR. Prompt for coding agent Process — 1 fixed
|
…scoping Review follow-ups: - body-guard now checks out the base repo's default branch, so a fork PR can no longer ship a neutered body-policy.sh that passes its own body; a loud, documented bootstrap skip covers the installing PR itself - the about-the-control allowlist is scoped to the prose rules (internal-marker, private-repo-ops); credential/infra rules are never exempted by merely mentioning the gate or SECURITY.md - (?i) in private-repo-ops is scoped to the repo names only, so lowercase prose (auth_token, api_key) near a private repo name no longer blocks - ripgrep is verified to have PCRE2 and, when missing, installed from the pinned checksum-verified release binary instead of apt; body-policy.sh fails closed with a clear message on a PCRE2-less build Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The allowlist filter stages ended in '|| true', so an rg error (>=2) during filtering was indistinguishable from 'every line allowlisted' and produced a pass. Capture each stage's exit code: 0/1 proceed, >=2 exits 2, matching the primary scan's fail-closed contract. Redaction behavior unchanged. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Reviews were the remaining public text channel the body gate did not see: pull_request_review carries the review summary in .review.body and pull_request_review_comment carries line comments in .comment.body, and neither arrives as issue_comment. Subscribe to both, admit them into body-guard, and extract .review.body in the materialize step. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
| if: >- | ||
| (github.event_name == 'pull_request' && github.event.action != 'edited') | ||
| || github.event_name == 'push' | ||
| || github.event_name == 'workflow_dispatch' |
There was a problem hiding this comment.
🔍 Tree scan is skipped on edited, which changes what the required check reports
With edited added to the pull_request types, every body/title edit now starts a workflow run in which the guard job is skipped, producing a fresh check-run with conclusion skipped on the head commit. GitHub treats skipped as passing for required checks, so this should not block merges, but it does mean the visible status for "Secrets + content policy" on a PR can end up being a skip rather than the earlier green tree scan. Worth confirming against the repo's branch-protection configuration if that check is required.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
GitHub treats a skipped check-run as passing for required checks, so the intentional edited skip on the tree job cannot block merges; the behavior is by design and documented in the workflow, and branch-protection configuration is not verifiable or changeable from this repo's code.
… with synthetic placeholders Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
…to a path start Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
| # already-reviewed copy of the scanner. A PR that changes body-policy.sh | ||
| # still has its copy exercised — by the self-test step in `guard`, against | ||
| # fixtures on the tree, where the required check reviews it. | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
There was a problem hiding this comment.
🔍 actions/checkout bumped to an unverified v7.0.1 pin, out of step with the rest of the repo
This PR changes the checkout pin from 93cb6efe… # v5.0.1 to 3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 in both jobs, while every other workflow in this repo pins actions/checkout@v4 (see .github/workflows/_checks.yml:23 and the test-*.yml files pinning @v4). The bump is unrelated to the stated purpose of the PR (body scanning) and cannot be verified offline. If the SHA/tag comment do not correspond to a real published release, both jobs fail at the very first step and the whole gate goes red. Worth confirming the SHA against the upstream release, and confirming the version actually supports the sparse-checkout / sparse-checkout-cone-mode inputs used at .github/workflows/public-repo-guard.yml:181-182.
Was this helpful? React with 👍 or 👎 to provide feedback.
This repo's
public-repo-guardhas never scanned a single issue or comment body.Measured across all 28 public wave-av repos (
wave-av/claude-workstation#1747,#1794): two coverage shapes satisfy the one required check nameSecrets + content policy.pull_request, push, workflow_dispatchguardissues,issue_commentbody-guardThis repo is in the 27. All 28 report the same green check — because a required check asserts that something named X passed, never what X examined.
The outlier is
wave-moq-edge, and its own comment says why it matters:That gap was not theoretical there: a PR was blocked for naming a private repo in
wrangler.tomlwhile the very same name, with more operational detail attached, sat unchallenged in its body.What lands
Three files — the bundle the workflow's own header names, minus what this repo already has (
.gitleaks.tomlandcontent-policy.share already vendored, and are checked as prerequisites; a repo missing either is refused rather than half-installed):The workflow's header names four files as the install unit but executes a fifth —
tests/body-policy.test.sh, in its own self-test step. Omitting it installs a workflow that fails on a step nobody read, so the manifest ships it. Modes are preserved via the git trees API; the contents API creates100644regardless, which would silently break running these scripts as executables.Planned by
governance/lib/vendor-bundle.mjs(claude-workstation#1850) against a checked-in manifest, not by ad-hoc shell.One deliberate divergence from the reference, stated rather than silent
The shipped workflow is
wave-moq-edge's withactions/checkoutbumped from v5.0.1 to v7.0.1 (3d3c42e5aac5ba805825da76410c181273ba90b1), the pin already used byclaude-workstation's own gate.Copying verbatim was checked first and rejected on evidence: of the 18 target repos, 17 carry a byte-identical guard, and
wave-realtime-edgealready runs v7.0.0 — so a verbatim copy would have downgraded it, and shipped a stale pin to the other 17. A separate PR brings the reference itself up to the same pin.Honest about what this can and cannot do
On a PR this PREVENTS the merge. On an issue or comment the text is already public the moment it posts, so this is DETECTION: it says go redact, fast. Only a client-side pre-write hook stops that class before publication.
Also inherited from the reference: concurrency moves from workflow-level to per job, because the two jobs want opposite behaviour. A workflow-level group forced one policy on both, and rapid body edits cancelled the tree job repeatedly — every cancelled check-run stays attached to the commit, so the PR reported UNSTABLE while the live runs were green.
The body gate ships with its own fixtures and runs them in CI. Its negative cases are the load-bearing half: a leak gate that blocks legitimate cross-repo references gets switched off, and then it protects nothing.
Refs
wave-av/claude-workstation#1747.Note
Cursor Bugbot is generating a summary for commit 5b4efc0. Configure here.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is enabled.Note
Scan PR/issue/comment/review bodies for secrets and internal markers in CI
body-guardjob to public-repo-guard.yml that runs on PRs, issues, comments, and reviews; it materializes untrusted body text from$GITHUB_EVENT_PATHand scans it with the new body-policy.sh.guard:allow <reason>inline comments; self-referential prose about the control is filtered for select rules to avoid false positives.guardjob now runs these tests as a self-test step.guardjob skips purely body-edit and issue/comment events; both jobs install a version-pinned, SHA-256-verified PCRE2-capable ripgrep binary instead of the apt package.Macroscope summarized 3716e82.