How to Add SAST Scanning to a CI Pipeline
Add a SAST scanner such as Semgrep to CI, scope it to pull requests, fail the build on high-severity findings, and upload SARIF so issues appear inline in code review. Includes triage guidance.
What and why
Static Application Security Testing (SAST) analyzes source code for vulnerabilities (injection, hardcoded secrets, unsafe deserialization) without running it. Running SAST in CI catches issues before they merge, when they are cheapest to fix. SARIF is the standard format that lets results show up as inline annotations in code review.
Prerequisites
- A code repository.
- A CI provider (GitHub Actions, GitLab CI).
- Basic YAML familiarity.
Steps
1. Choose a SAST tool
Semgrep is language-agnostic and rule-driven; CodeQL is deep and integrates with GitHub; language-specific tools (Bandit for Python, gosec for Go) are lightweight. This example uses Semgrep.
2. Add a scan job to CI
GitHub Actions:
name: sast
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
config: p/default
3. Run on pull requests
Scoping the trigger to pull_request scans only changed code on PRs, keeping feedback fast. Add a scheduled full scan for a complete baseline.
4. Fail the build on severity
Configure the scanner to exit non-zero on high-severity findings so the check blocks merge:
semgrep --config p/default --severity ERROR --error
Start in warn-only mode, fix the backlog, then turn on blocking to avoid breaking every PR on day one.
5. Publish SARIF results
Emit SARIF and upload it so findings appear inline:
- run: semgrep --config p/default --sarif --output semgrep.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
6. Triage and suppress findings
Review findings; for false positives add an inline # nosemgrep comment or a rule exclusion with a justification. Track real findings to remediation rather than blanket-ignoring rules.
Verification
- The scan job runs on every pull request.
- A deliberately vulnerable snippet causes the build to fail.
- Findings appear as annotations in the PR.
Next Steps
Layer dependency scanning and secret scanning alongside SAST, add IaC scanning for Terraform and Kubernetes manifests, and feed all results into one security dashboard so trends are visible over time.
Prerequisites
- A code repository
- A CI provider
- Basic YAML knowledge
Steps
- 1Choose a SAST tool
- 2Add a scan job to CI
- 3Run on pull requests
- 4Fail the build on severity
- 5Publish SARIF results
- 6Triage and suppress findings