BlogCI/CD

SAST in CI with Semgrep and custom rules

Add fast static analysis to your pipeline and write project-specific rules that catch your own recurring bugs.

Jan 28, 2026·4 min readIntermediate·By the SecOpsLog team · command-tested

Static analysis that only security teams understand gets disabled by week three. Semgrep matches code against patterns that look like the code itself — no proprietary query language, no hour-long scans. It ships thousands of community rules for injection, auth bypass, and dangerous APIs, and lets you encode your own recurring mistakes in a few lines of YAML. That combination is why SAST belongs in every merge request, not in a quarterly audit spreadsheet.

You will run semgrep ci on every MR, write a project-specific rule for a bug your team keeps repeating, baseline legacy findings so only new issues fail the build, and promote rules from WARN to ERROR once the backlog is clean. GitLab and GitHub both fit the same pattern — the broader scanning stack lives in Software supply chain security.

From first scan to enforced custom rule

Introduce gates gradually. A scanner that fails on day one gets `--skip` comments by day three.

1semgrep --configautobaseline findings2CI jobsemgrep ci on MR3Custom ruleencode team anti-pattern4WARN firstfix backlog5Flip ERRORblock merge6Baseline fileonly new fails7Review nosemgrepexceptions in diff

Run it on every merge request

Pin the Semgrep image or CLI version so rule packs and engine behavior do not shift under you mid-sprint. Use --error (or semgrep ci) so findings exit non-zero and block merge on protected branches. Upload SARIF to your Git host if you want inline annotations — developers fix faster when the finding sits on the exact line.

.gitlab-ci.yml
sast:
stage: test
image: semgrep/semgrep:1.90.0
script:
- semgrep ci --config auto --error
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
bash — a first local passlive
semgrep --config auto .
python.lang.security.audit.subprocess-shell-true
app/tasks.py:42 subprocess.run(cmd, shell=True)
ran 1,284 rules on 96 files, 3 findings
fix or baseline before turning on --error in CI

Write a rule for your own bug

Say your codebase must never build SQL with f-strings — a pattern code review catches until someone is tired on a Friday. Encode it once in YAML and Semgrep enforces it on every push. Custom rules are how SAST stops being generic noise and starts catching bugs only your architecture can have.

rules/no-fstring-sql.yaml
rules:
- id: no-fstring-sql
languages: [python]
severity: ERROR
message: Build SQL with parameters, not f-strings (injection risk).
patterns:
- pattern: cursor.execute(f"...")

Keep the signal high

Baseline existing findings with semgrep ci --baseline-commit main or a checked-in baseline file so legacy debt does not block every MR. Use nosemgrep comments sparingly with a ticket reference — every suppression should appear in the diff for review. Pair Semgrep with secret scanning and dependency checks so SAST is one layer, not the whole program. Review custom rules in pull requests the same way you review application code: a bad rule is a permanent false sense of safety.

Rule rollout discipline
Day-one ERROR
Hundreds of findings
Developers add skips
Gate gets disabled
Zero lasting value
WARN then ERROR
Visible in MR, non-blocking
Backlog burn-down sprint
Flip severity in YAML
Gate developers trust
A disabled gate is worse than no gate
If Semgrep fails the build on hundreds of legacy findings, someone will add allow_failure: true or stop running it. Baseline first, enforce new issues only, then tighten. Security scanners developers route around become audit theater.

Where this goes next

SAST catches dangerous code paths; supply-chain tooling catches dangerous dependencies and unsigned artifacts. Wire Semgrep beside Grype on SBOMs, gitleaks on secrets, and Cosign on images so one pipeline covers code, deps, and provenance. Software supply chain security connects those gates from commit to cluster admission.

Go deeper in a courseSoftware supply chain securitySAST, dependency and secret scanning, SBOMs, and signing end to end.View course

Related posts