Skip to content

ci(security): Semgrep SAST gate (report-only) (#1797)#1822

Draft
ktursunov wants to merge 5 commits into
mainfrom
semgrep-collection
Draft

ci(security): Semgrep SAST gate (report-only) (#1797)#1822
ktursunov wants to merge 5 commits into
mainfrom
semgrep-collection

Conversation

@ktursunov

Copy link
Copy Markdown
Contributor

What

Stands up Semgrep (SAST) as its own report-only CI gate, split out of the
closed omnibus PR #1463 so the baseline can be triaged and ratcheted to blocking
independently (per the security-scanner umbrella #1478).

  • New .github/workflows/semgrep.yml — single sast job:
    • semgrep scan --config p/default --exclude-rule generic.secrets.security.detected-generic-secret
      (secret detection is owned by the separate TruffleHog gate).
    • Report-only: runs without --error, so findings surface but never block.
    • Findings surface in Security → Code scanning (SARIF upload) and as a count in the job summary.
    • Triggers: PRs to main + nightly schedule (03:27 UTC) + workflow_dispatch; no path filter.
    • Digest-pinned Semgrep image run via docker run on ubuntu-latest (so checkout/upload-sarif
      keep the host runner's Node); SHA-pinned actions; job-scoped security-events: write;
      concurrency cancel-in-progress; fork-PR-safe SARIF upload.
  • New .semgrepignore — prunes build/dependency artifacts (target/, .venv/, node_modules/, dist/);
    application and test source stay in scope.
  • Program.cs — the pre-existing JWT ValidateLifetime = false finding is waived inline
    (// nosemgrep: … + #346), the one known high-severity item in the baseline.

Baseline (first p/default run: 124 findings)

Report-only on purpose — the baseline is not clean yet. Dominant category is 109
github-actions-mutable-action-tag
findings in the existing workflows (a repo-wide
SHA-pin effort, tracked separately), plus ~13 product/tooling findings and 2 Dockerfile
missing-user findings. Triage happens in Code Scanning after this lands.

Exit condition (separate follow-up PR)

Flip to blocking by adding --error and marking sast a required check once the baseline is
clean (zero un-waived findings)
— which depends on the mutable-tag follow-up + triaging the
remaining findings. Not part of this PR.

Test plan

  • actionlint clean; the new workflow self-scans to 0 p/default findings (fully pinned).
  • Baseline scan reproduced locally with the exact pinned image + command.
  • JWT waiver verified to suppress the finding.

Closes #1797.
Part of #1478. Split from #1463.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8fc1c21-f987-45cd-9e69-8412df58679e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch semgrep-collection

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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.

Comment thread src/backend/services/identity/src/Insight.Identity.Api/Program.cs Fixed
Comment thread src/backend/services/identity/src/Insight.Identity.Api/Program.cs Fixed
Konstantin Tursunov added 3 commits July 17, 2026 21:00
Standalone semgrep.yml running p/default (secrets excluded — TruffleHog owns
those) in report-only mode: findings upload to Code Scanning (SARIF) and a
job-summary count, but no --error so the check never blocks. PR + nightly +
dispatch triggers, digest-pinned image, SHA-pinned actions. Adds .semgrepignore
for build/dep artifacts and waives the known JWT ValidateLifetime finding inline
(#346). Split from #1463; part of #1478.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
- Bump actions/checkout v4.2.2 -> v5.0.1 and codeql-action/upload-sarif
  v3.32.0 -> v4.32.6 (SHA-pinned) to clear the Node-20 deprecation and the
  CodeQL Action v3 sunset warnings from the first run.
- Switch the JWT #346 waiver from an inline rule-id nosemgrep to a bare
  // nosemgrep: under the full p/default ruleset the fully-namespaced rule id
  does not match, so no suppression was emitted and the alert stayed open. The
  bare form reliably emits SARIF suppressions[inSource], which Code Scanning
  honors as a dismissed alert.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
Inline nosemgrep does not dismiss a GitHub Code Scanning alert (GitHub does
not honor third-party SARIF suppressions[inSource]), so the marker touched
product code for no effect. Restore Program.cs; the JWT #346 finding — like
the rest of the report-only baseline — will be dismissed in the Code Scanning
UI/API (state=dismissed, won't-fix, ref #346) during the Phase-6 triage, before
the --error flip.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov
ktursunov force-pushed the semgrep-collection branch from c82a7c8 to 74356a3 Compare July 17, 2026 18:00
Konstantin Tursunov added 2 commits July 17, 2026 21:08
Replace the bare finding count with a severity table plus a collapsible
per-rule breakdown rendered from the SARIF (stdlib only, no jq).

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
p/default has thin Rust/C# security coverage (0 findings across 184 Rust
files); add the dedicated language packs so the actual backend code is scanned,
not just CI/YAML. Surfaces real Rust (unsafe-usage, temp-dir) and C#
(unsigned-security-token) findings p/default missed. Still report-only.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
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.

ci(security): Semgrep SAST gate (split from #1463)

2 participants