Skip to content

feat: SAST — application source code fast scan (pre-commit) #18

Description

@ms280690

Context

Stage: Pre-commit
Tool: semgrep
Scope: Application source code — frontend (JS/TS/React) and backend (Python, Go, Java, Ruby, etc.)
Parent: (see SAST parent issue)

IaC and Helm/Kustomize are out of scope for this step. IaC security scanning is covered by Step 17 (checkov, tflint) and the existing linting issues #10 and #11.

Why semgrep

At pre-commit time, the goal is instant developer feedback on code being committed. semgrep is the right tool:

  • Pattern-based AST scanning — fast enough to run as a blocking hook (sub-second on typical file sets)
  • Language-agnostic: a single hook covers Python, Go, Java, JavaScript, TypeScript, Ruby, PHP, Kotlin, Rust, and more — no stack-specific configuration needed in the workflow
  • semgrep/semgrep-rules registry ships 1000+ security-focused rules maintained by the Semgrep team
  • Native pre-commit hook available — zero custom wrapper code
  • snyk code (the alternative) requires a cloud API call on every commit — too slow and introduces a network dependency in the pre-commit path

Pre-commit local hook

Add to the consuming repo's .pre-commit-config.yaml:

repos:
  - repo: https://github.com/returntocorp/semgrep
    rev: v1.x.x
    hooks:
      - id: semgrep
        args:
          - --config=auto          # uses semgrep registry, auto-selects rules for detected languages
          - --error                # non-zero exit on findings
          - --severity=ERROR       # block on ERROR; WARNING is surfaced but non-blocking

Reusable workflow — sast-precommit.yml

CI enforcement: runs semgrep directly in the workflow so PRs from contributors without the local hook are still gated.

name: SAST Pre-commit
on:
  workflow_call:
    inputs:
      severity:
        description: 'Minimum severity to fail: ERROR|WARNING|INFO'
        default: 'ERROR'
        type: string
      config:
        description: 'Semgrep config — registry alias or path to rules file'
        default: 'auto'
        type: string

Consuming repo usage

# .github/workflows/sast.yml
name: SAST
on: [pull_request]
jobs:
  semgrep:
    uses: sparkgeo/github-actions/.github/workflows/sast-precommit.yml@main
    with:
      severity: ERROR

Rule set strategy

--config=auto automatically selects rules from the Semgrep registry based on the languages detected in the repo. This is the language-agnostic default. For targeted rule sets:

Stack Config value
Python p/python
JavaScript / TypeScript p/javascript + p/typescript
Go p/golang
Java p/java
Django / Flask p/django / p/flask
React p/react
OWASP Top 10 (any language) p/owasp-top-ten

Add a .semgrepignore file to exclude generated code, vendored libraries, and test fixtures from scans.

Metadata

Metadata

Assignees

Labels

Fields

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions