ci(security): scanning workflow + CodeRabbit config + sweep design (PR 0) - #135
Conversation
PR 0 of the v0.3.0 stabilization sweep — establishes the automated review + security gate every subsequent plan PR flows through. - .github/workflows/security.yml: gitleaks (gating secret scan), CodeQL (Python + JS/TS), bandit (SARIF), pip-audit + bun audit. Only the secret scan gates; dep/SAST findings are reporting-only to stay consistent with the no-ceremony, continuous-to-main cadence. - .coderabbit.yaml: path filters + constitution constraints encoded as review instructions (local-first, cross-platform parity, alembic, no secret/home-path leakage). Drafts excluded from auto-review. - SECURITY.md: document the automated scanning + bot review. - docs/specs: program design for the full sweep (plan-01..05 + PR triage). CodeRabbit and Greptile apps are already installed and will review on PR open. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds CodeRabbit automated review config, a GitHub Actions security workflow (gitleaks, CodeQL, bandit, dependency audits), documents automated scanning in SECURITY.md, and introduces a v0.3.0 stabilization-sweep specification. Changesv0.3.0 Review and Security Scaffold
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
| Filename | Overview |
|---|---|
| .github/workflows/security.yml | New security workflow with four jobs: gitleaks (gating), CodeQL SAST, bandit SARIF, and dependency audits; well-structured with least-privilege permissions and appropriate continue-on-error guards |
| .coderabbit.yaml | New CodeRabbit config encodes project constraints (local-first, cross-platform parity, alembic, secret/path leakage) as review instructions with path-aware filters; no issues found |
| SECURITY.md | Added Automated scanning section documenting the new workflow and review bots; clean documentation update |
| docs/specs/2026-05-29-v0.3.0-stabilization-sweep.md | New sweep program-design document describing the six-PR execution order, deferred items, and cross-cutting rules; informational only |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
trigger["PR / push to main / weekly schedule"] --> secrets
trigger --> codeql
trigger --> bandit
trigger --> dependencies
subgraph secrets["secrets (GATING)"]
gl_checkout["checkout (fetch-depth: 0)"] --> gitleaks["gitleaks-action@v2"]
gitleaks -- "secrets found" --> HARD_FAIL["Blocks merge"]
gitleaks -- "clean" --> PASS["Gate passes"]
end
subgraph codeql["codeql (matrix: python / javascript-typescript)"]
cql_checkout["checkout"] --> cql_init["CodeQL init (build-mode: none)"]
cql_init --> cql_analyze["CodeQL analyze to Security tab"]
end
subgraph bandit["bandit (reporting only)"]
ban_checkout["checkout"] --> ban_run["pipx run bandit sarif (continue-on-error)"]
ban_run --> ban_upload["upload-sarif to Security tab (continue-on-error)"]
end
subgraph dependencies["dependencies (reporting only)"]
dep_checkout["checkout"] --> uv_sync["uv sync"]
uv_sync --> pip_audit["pip-audit (continue-on-error)"]
dep_checkout --> setup_bun["setup-bun v1 (1.2+)"]
setup_bun --> bun_install["bun install frozen-lockfile"]
bun_install --> bun_audit["bun audit (continue-on-error)"]
end
Reviews (3): Last reviewed commit: "ci(security): harden per bot review — pe..." | Re-trigger Greptile
The bandit SARIF formatter ships in the `bandit[sarif]` extra; plain `bandit` rejects `-f sarif` (exit 2), so no SARIF was written and the upload step failed. Install via `pipx run --spec 'bandit[sarif]'`. Also add FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 (mirrors ci.yml) to silence the Node 20 deprecation warning on checkout/setup-python/upload-sarif. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/security.yml (1)
36-52: MakeSecret scan (gitleaks)a required status check formainmerge gating (or fix the wording).The workflow can fail, but “blocks merge” only applies if branch protection/rulesets for
mainrequire the exact status check contextSecret scan (gitleaks)(fromjobs.secrets.name). The branch-protection config couldn’t be read here (GitHub API returnednull), so this wiring needs to be set/confirmed.GitHub → Settings → Branches → Branch protection rules (main) → Required status checks → require
Secret scan (gitleaks)
[/offer_operational_advice]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/security.yml around lines 36 - 52, The workflow defines a job with jobs.secrets.name = "Secret scan (gitleaks)" but branch protection may not be requiring that exact status check context, so either add the exact status check "Secret scan (gitleaks)" to the main branch protection required status checks or change jobs.secrets.name to match the existing required status-check name used by your ruleset; confirm the branch-protection/ruleset UI (Settings → Branches → Branch protection rules for main → Required status checks) lists exactly "Secret scan (gitleaks)" and update the workflow or branch rule to make the names identical so the gitleaks job actually blocks merges.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/security.yml:
- Around line 43-46: The checkout steps currently leave GITHUB_TOKEN persisted
in repo git config; update the actions/checkout@v4 steps to set
persist-credentials: false by adding "persist-credentials: false" under the
with: block for the shown checkout (used for gitleaks/full-history scanning) and
apply the same change to the other checkout steps in the codeql, bandit, and
dependencies jobs so none of these read-only jobs persist credentials into the
checked-out repository.
---
Nitpick comments:
In @.github/workflows/security.yml:
- Around line 36-52: The workflow defines a job with jobs.secrets.name = "Secret
scan (gitleaks)" but branch protection may not be requiring that exact status
check context, so either add the exact status check "Secret scan (gitleaks)" to
the main branch protection required status checks or change jobs.secrets.name to
match the existing required status-check name used by your ruleset; confirm the
branch-protection/ruleset UI (Settings → Branches → Branch protection rules for
main → Required status checks) lists exactly "Secret scan (gitleaks)" and update
the workflow or branch rule to make the names identical so the gitleaks job
actually blocks merges.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f2654509-857d-44e5-8622-7ec7298eb089
📒 Files selected for processing (4)
.coderabbit.yaml.github/workflows/security.ymlSECURITY.mddocs/specs/2026-05-29-v0.3.0-stabilization-sweep.md
…rd, bun pin Addresses CodeRabbit + Greptile findings on #135: - persist-credentials: false on all checkout steps (don't leave GITHUB_TOKEN in git config; none of these jobs need authed git after clone). [CodeRabbit] - continue-on-error on the bandit SARIF upload so a missing SARIF can't fail this reporting-only job. [Greptile P1] - pin bun-version "1.2" — `bun audit` only exists in bun >=1.2.x. [Greptile P2] Declined: full-SHA action pinning. Meets the major-tag bar set in .coderabbit.yaml and matches ci.yml/release.yml convention; SHA pinning belongs in a repo-wide hardening pass with Dependabot, not one file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/security.yml (1)
157-170:⚠️ Potential issue | 🔴 CriticalFix Bun pin so
bun auditis guaranteed to exist (use1.2.15/1.2.x, not1.2)
bun auditwas added in Bun v1.2.15, butoven-sh/setup-bun@v1is documented around wildcard selectors (e.g.,1.2.x) rather than resolving a barebun-version: "1.2"to the latest 1.2.x. As written, the frontend job can end up on an earlier 1.2 build withoutbun audit, andcontinue-on-error: truewould hide that the audit never ran.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/security.yml around lines 157 - 170, The workflow pins Bun too loosely: change the Setup Bun step's bun-version in the "Setup Bun" job from "1.2" to a version that guarantees the presence of bun audit (e.g., "1.2.15" or the wildcard "1.2.x") so the frontend "bun audit (frontend)" step actually runs the subcommand; update the bun-version value referenced in the Setup Bun step and ensure the frontend job that runs "bun install --frozen-lockfile" and "bun audit" will get a Bun that includes the audit subcommand.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/security.yml:
- Around line 157-170: The workflow pins Bun too loosely: change the Setup Bun
step's bun-version in the "Setup Bun" job from "1.2" to a version that
guarantees the presence of bun audit (e.g., "1.2.15" or the wildcard "1.2.x") so
the frontend "bun audit (frontend)" step actually runs the subcommand; update
the bun-version value referenced in the Setup Bun step and ensure the frontend
job that runs "bun install --frozen-lockfile" and "bun audit" will get a Bun
that includes the audit subcommand.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c18c71c0-e01b-416b-8377-61ca0cdb07d1
📒 Files selected for processing (1)
.github/workflows/security.yml
PR 0 of the v0.3.0 stabilization sweep. Establishes the automated review + security gate that every subsequent plan PR flows through. Intentionally tiny so it's a clean first run through the new pipeline.
What's here
.github/workflows/security.yml— runs on every PR, push tomain, and weekly:gitleaks— secret scanning (hard fail — the only gating check)CodeQL— Python + JavaScript/TypeScript SAST → Security tabbandit— Python SAST → SARIF → Security tab (reporting)pip-audit+bun audit— dependency advisories (reporting).coderabbit.yaml— path filters + the constitution's constraints encoded as review instructions (local-first / no telemetry, cross-platform default parity, alembic for schema changes, no secret/home-path leakage). Drafts excluded from auto-review.SECURITY.md— documents the automated scanning + bot review (kept the existing policy intact).docs/specs/2026-05-29-v0.3.0-stabilization-sweep.md— the program design for the whole sweep.Why only secrets gate
Dependency advisories and SAST findings are surfaced as signal (Security tab / job log) rather than blocking every PR on a transitive upstream advisory — consistent with the no-ceremony, continuous-to-main cadence.
Sweep this unblocks
No version bump, no RC — continuous-to-main per the constitution.
🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation