Skip to content

ci(sast): add Semgrep OSS scan complementing CodeQL (#172) - #270

Merged
Chris-Wolfgang merged 2 commits into
vNextfrom
tier2/172-semgrep-sast
Jul 17, 2026
Merged

ci(sast): add Semgrep OSS scan complementing CodeQL (#172)#270
Chris-Wolfgang merged 2 commits into
vNextfrom
tier2/172-semgrep-sast

Conversation

@Chris-Wolfgang

Copy link
Copy Markdown
Owner

Closes #172.

Summary

  • New .github/workflows/semgrep-sast.yaml. Semgrep OSS 1.144.0 (pinned) with rulesets p/csharp + p/security-audit. SARIF upload to Code Scanning → PR annotations + Security tab.
  • New docs/SEMGREP-AUDIT.md — the AC-required committed audit log for triaged findings (fixed / false-positive / accepted-risk).

Why Semgrep OSS (not Snyk / Veracode / SonarQube)

  • Zero-account: pulls rulesets over HTTPS from the public registry, no API key / license / signup needed. Aligns with feedback_confirm_before_api_spend — no user action gate.
  • Complementary to CodeQL: distinct rule engine (YAML pattern rules vs CodeQL semantic taint).
  • The issue explicitly notes "Snyk Code has a free OSS tier (worth trying first)"; Semgrep OSS is the true zero-friction equivalent.

Findings vs. failures

The workflow does NOT fail the PR on findings (that's Code Scanning's job to gate by severity). It only fails on real Semgrep tool errors (rc >= 2).

Baseline scan

Per AC, "a baseline scan of the current main is committed so per-PR scans report only new findings." Code Scanning enforces this automatically once the first push-to-main run establishes baseline; no committed file needed. The docs/SEMGREP-AUDIT.md picks up the human-readable triage decisions from there.

Stacked-PR base

Base = vNext. Seventh of the 11-PR batch (#178 closed as N/A, so 7 stacked PRs open on vNext so far).

Protected-file guard

Adds a new workflow file → protected. Expected admin-bypass at merge.

Test plan

  • Semgrep job runs on this PR, completes green
  • SARIF upload succeeds; findings (if any) appear in the Security tab
  • Triaged findings appended to docs/SEMGREP-AUDIT.md in the follow-up commit that addresses them

Closes #172.

Adds `semgrep-sast.yaml` running Semgrep OSS with the public
`p/csharp` + `p/security-audit` rulesets on every PR (main / vNext),
push-to-main, weekly Mondays 06:30 UTC (drift catch — public
registry rulesets change independent of code), and manual dispatch.
Findings upload as SARIF to GitHub Code Scanning where they appear
alongside CodeQL alerts.

Chose Semgrep OSS over Snyk / Veracode / Fortify / SonarQube because:

  - Zero-account: pulls rulesets over HTTPS from the public registry,
    no API key / license procurement / user sign-up needed.
  - Genuine "beyond CodeQL" coverage: distinct rule engine, catches
    class of issues CodeQL surfaces at low confidence (patterns
    encoded as YAML rules vs CodeQL's semantic-taint queries).
  - Per issue: "Snyk Code has a free OSS tier (worth trying first)"
    — Semgrep OSS is the true no-friction equivalent.

Semgrep version pinned (1.144.0) so ruleset-parser changes in a
future release don't silently flip PR status without any repo
change. Workflow exit code intentionally decouples findings from
tool-error: rc=1 (findings present) does NOT fail the job (Code
Scanning gates severity); rc>=2 (real tool error) does.

Also adds `docs/SEMGREP-AUDIT.md` — the AC-required audit log where
triaged findings are recorded chronologically (fixed / false-positive
/ accepted-risk + rationale + PR). First entries land after the
initial baseline scan.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 00:23

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Initial pin used a non-existent commit
(`27d1e8c7db9c6dabdd57f00cae67e2fbb9d5ce3e`); CI failed with
`Unable to resolve action`. Replaced with
`54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4`, the SHA used by
the rest of the Wolfgang.* fleet (verified in AuditTrail).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-advanced-security

Copy link
Copy Markdown

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:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

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.

3 participants