feat(security): add GHSA detector-review pipeline and OpenGrep CI workflows (#69483)

* feat(security): add GHSA detector-review pipeline and OpenGrep CI workflows [AI-assisted]

Stand up an end-to-end pipeline that turns every published openclaw GitHub
Security Advisory into a reusable OpenGrep rule, and wire the compiled rules
into manual-dispatch GitHub Actions workflows that publish SARIF to GitHub
Code Scanning.

The pipeline is harness-agnostic: any coding-agent CLI (Rovo Dev, Claude
Code, Codex, OpenCode, or anything you can shell out to) can drive it via
the runner script's --harness flag. Built-in adapters cover the four common
harnesses; --harness-cmd '<template>' supports anything else with shell-style
{prompt}/{model}/{output_file} substitution.

Pipeline pieces:

- scripts/run-ghsa-detector-review-batch.mjs runs your chosen coding harness
  in parallel against every advisory using the agent-agnostic detector-review
  spec at security/detector-review/detector-review-spec.md. Each case
  produces an opengrep general-rule.yml (precise) and broad-rule.yml
  (review-aid), plus a coverage-validated report against the vulnerable
  commit's changed files.
- scripts/compile-opengrep-rules.mjs walks a run directory, rewrites each
  rule's id to ghsa-detector.<ghsa>.<orig-id>, injects ghsa/advisory-url/
  detector-bucket/source-rule-id metadata, and uses opengrep itself to drop
  rules with InvalidRuleSchemaError so the published super-configs load
  cleanly.

Compiled outputs:

- security/opengrep/precise.yml     (336 rules)
- security/opengrep/broad.yml       (459 rules)
- security/opengrep/compile-manifest.json    (per-rule provenance map)

CI workflows (manual workflow_dispatch only):

- .github/workflows/opengrep-precise.yml
- .github/workflows/opengrep-broad.yml

Both install a pinned opengrep, run opengrep scan against src/, upload SARIF
to Code Scanning under categories opengrep-precise / opengrep-broad, and use
continue-on-error: true so findings never block the workflow.

Detector-review spec and assets:

- security/detector-review/detector-review-spec.md   the agent-agnostic spec
  the runner injects into each per-case prompt
- security/detector-review/references/{detector-rubric,report-template}.md
- security/detector-review/scripts/init_case.py
- security/prompt-suffix-coverage-first.md   mandatory prompt addendum that
  enforces coverage-first validation (rule must catch the OG vuln, not just
  pass synthetic fixtures)

Docs:

- security/README.md          end-to-end flow, supported harnesses, regen recipe
- security/opengrep/README.md compiled-config details + recompile recipe

* security: tighten GHSA OpenGrep detector workflow

* chore: refine precise opengrep workflow

* chore: remove stale opengrep metadata

* fix: harden GHSA OpenGrep workflow

* ci: split OpenGrep diff and full scans

* chore: remove performance-only opengrep rule

* ci: use OpenGrep installer path

* chore: enforce opengrep rule metadata provenance

* chore: generalize opengrep rule compilation

* docs: align opengrep rulepack guidance

* chore: support generic opengrep rule sources

* fix: validate opengrep rulepack-only changes

---------

Co-authored-by: Jesse Merhi <security-engineering@atlassian.com>
This commit is contained in:
Jesse Merhi
2026-04-30 02:42:20 +10:00
committed by GitHub
parent c7aaa40848
commit 6de9d71bfb
16 changed files with 6488 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
name: OpenGrep — Full
# Manual repository-wide scan for the high-precision OpenGrep rule super-config.
# This is intentionally separate from PR scanning so broad/backlog findings do
# not block unrelated pull requests.
on:
workflow_dispatch:
concurrency:
group: opengrep-full-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
security-events: write
jobs:
scan:
name: Scan full repository (precise)
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install opengrep
env:
# Pin both the install script (by commit SHA) and the binary version.
# The script SHA must match the v1.19.0 release tag in opengrep/opengrep
# so a compromised or force-pushed `main` cannot RCE in our CI runner.
# Bump both together when upgrading.
OPENGREP_VERSION: v1.19.0
OPENGREP_INSTALL_SHA: 9a4c0a68220618441608cd2bad4ff2eddccf8113
run: |
curl -fsSL "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" \
| bash -s -- -v "$OPENGREP_VERSION"
echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH"
- name: Verify opengrep
run: opengrep --version
- name: Run full opengrep scan
# Manual full scans cover all first-party source paths so maintainers can
# audit the complete rulepack without making PRs inherit unrelated backlog.
run: |
mkdir -p .opengrep-out
scripts/run-opengrep.sh --sarif --error
- name: Upload SARIF to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
# Only upload if the scan actually produced a SARIF file.
if: always() && hashFiles('.opengrep-out/precise.sarif') != ''
with:
sarif_file: .opengrep-out/precise.sarif
category: opengrep-full
- name: Upload SARIF as workflow artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: opengrep-full-sarif
path: .opengrep-out/precise.sarif
if-no-files-found: warn
retention-days: 30

76
.github/workflows/opengrep-precise.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
name: OpenGrep — PR Diff
# Runs the high-precision OpenGrep rule super-config against only first-party
# source paths changed by a pull request. Keeping PR scans diff-scoped makes
# findings attributable to the proposed change instead of surfacing unrelated
# repository-wide backlog.
#
# For a repository-wide scan, use the manual OpenGrep — Full workflow.
on:
pull_request:
concurrency:
group: opengrep-pr-diff-${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
permissions:
contents: read
security-events: write
jobs:
scan:
name: Scan changed paths (precise)
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
# `scripts/run-opengrep.sh --changed` diffs base...HEAD.
fetch-depth: 0
- name: Install opengrep
env:
# Pin both the install script (by commit SHA) and the binary version.
# The script SHA must match the v1.19.0 release tag in opengrep/opengrep
# so a compromised or force-pushed `main` cannot RCE in our CI runner.
# Bump both together when upgrading.
OPENGREP_VERSION: v1.19.0
OPENGREP_INSTALL_SHA: 9a4c0a68220618441608cd2bad4ff2eddccf8113
run: |
curl -fsSL "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" \
| bash -s -- -v "$OPENGREP_VERSION"
echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH"
- name: Verify opengrep
run: opengrep --version
- name: Run opengrep on PR diff
env:
OPENCLAW_OPENGREP_BASE_REF: ${{ github.event.pull_request.base.sha }}...HEAD
# Findings from precise rules block this workflow. Pull requests scan
# changed first-party source paths only so findings stay attributable to
# the PR diff. Test/fixture/QA path exclusions live in `.semgrepignore`
# at the repo root and are picked up automatically.
run: |
mkdir -p .opengrep-out
scripts/run-opengrep.sh --changed --sarif --error
- name: Upload SARIF to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
# Only upload if the scan actually produced a SARIF file.
if: always() && hashFiles('.opengrep-out/precise.sarif') != ''
with:
sarif_file: .opengrep-out/precise.sarif
category: opengrep-pr-diff
- name: Upload SARIF as workflow artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: opengrep-pr-diff-sarif
path: .opengrep-out/precise.sarif
if-no-files-found: warn
retention-days: 30