CoursesSecure CI/CD with GitLabSecurity scanning stages

SAST & code scanning

Find bugs in your own source.

Intermediate12 min · lesson 8 of 17

Static Application Security Testing (SAST) reads your source code without running it and flags likely vulnerabilities — SQL injection, hardcoded credentials, unsafe deserialization, path traversal. It runs early in the pipeline (the code is right there, no deploy needed) and it is the first scanning stage to add because it finds bugs you wrote, in code you can fix immediately. GitLab ships a built-in SAST template; Semgrep and CodeQL are the common standalone engines.

.gitlab-ci.yml
include:
- template: Jobs/SAST.gitlab-ci.yml # GitLab’s built-in SAST
# or a standalone engine you control:
semgrep:
stage: test
image: returntocorp/semgrep
script: [semgrep ci --config auto] # findings surface in the MR

Tune it or lose it

A SAST tool out of the box is noisy — false positives train developers to ignore it, and an ignored scanner is worse than none. The skill is tuning: start in report-only mode so nothing blocks, triage the findings, suppress the confirmed false positives with inline annotations, and only then gate the merge on real, high-confidence categories. A scanner developers trust is one they keep enabled.

Where SAST fits among the scanners

SAST is one of a family, and it helps to know its lane: SAST reads your code, secret detection reads your commits for credentials, dependency scanning reads your libraries for known CVEs, image scanning reads the built container, and DAST tests the running app. Each finds a different class of problem, and a complete pipeline runs all of them. SAST’s niche is flaws in the logic you wrote — the ones only your source reveals.

The scanners and what each reads
reads code / repo
SAST
your source for vuln patterns
secret detection
commits for credentials
reads dependencies / build / runtime
SCA
libraries for known CVEs
image scan
the built container
DAST
the running application
Different tools, different blind spots. Complete coverage runs all five as pipeline stages.
Report before you block
Turning a fresh SAST tool straight to "fail the merge" floods developers with false positives and gets it disabled within a sprint. Run it report-only first, tune the rules and suppress confirmed noise, then gate only on the high-signal findings. The goal is a scanner that stays on, not one that looks strict on day one and is bypassed by day thirty.