SAST, Secret Detection, Dependency Scanning, Container Scanning, DAST, and Coverage-Guided Security: Concepts, Architecture, and Mental Model
Model GitLab application-security scanning as pipeline-produced evidence with explicit scan targets, analyzers, report schemas, finding lifecycle, tier boundaries, runner trust, and coverage limits.
Learning objectives
- Distinguish SAST, secret detection, dependency scanning, container scanning, DAST, and retired coverage-guided fuzzing by the asset each actually analyzes.
- Explain analyzer → scanner → Secure report artifact → schema validation → GitLab presentation as separate steps.
- Separate a pipeline job’s exit status from the presence or absence of vulnerability findings.
- Map Free raw-report capability to Ultimate hosted triage/policy features without overstating either tier.
- Treat runner, fork/MR configuration, analyzer images, and report artifacts as security trust boundaries.
1. The practical problem: a green pipeline is not a security proof
Chapter 24 established a release chain from source commit to immutable package/image identity. Before promotion, teams want evidence about source weaknesses, exposed credentials, vulnerable dependencies, vulnerable container packages, and runtime attack surfaces. These are different questions. One scanner cannot answer all of them, and a pipeline that contains scanner jobs is not automatically “secure.”
The useful mental model is scan target → analyzer/scanner → raw evidence → GitLab ingestion/presentation → human or policy decision. Each arrow can fail independently. A job can run against the wrong commit, a container scan can inspect the wrong digest, a report can be invalid JSON, or a finding can be real but irrelevant to the deployed artifact. Security engineering begins by proving scope and identity.
2. Six names, six different analysis domains
| Capability | What it analyzes | Typical evidence | Current GitLab 19.3 availability |
|---|---|---|---|
| SAST | Repository source files. | Secure SAST JSON; file/line/rule identifiers. | Basic scanning + downloadable report: Free/Premium/Ultimate. Advanced SAST and vulnerability-management UI: Ultimate. |
| Pipeline secret detection | Committed Git repository content/history according to scan mode. | Secret-detection JSON with rule/location information. | Scanning + downloadable report: Free/Premium/Ultimate. Rich triage/policy/UI features: Ultimate. |
| Dependency scanning | Declared/resolved application dependencies, increasingly SBOM-oriented. | Dependency findings tied to package/version/file/SBOM. | Ultimate. |
| Container scanning | A container image and its packages/components. | Container-scanning JSON + optional CycloneDX SBOM. | Basic scanning + downloadable reports: Free/Premium/Ultimate; richer vulnerability workflow: Ultimate. |
| DAST | A running web application/API target from the outside. | DAST findings tied to URL/request/response context. | Ultimate; never point an educational active scan at production. |
| Coverage-guided fuzz testing | Instrumented program executed with generated inputs. | Historically coverage-fuzzing reports/crashes. | Deprecated in 18.0 and removed in 19.0. Not a runnable GitLab 19.3 product feature. |
3. Analyzer, scanner, job, and report are not synonyms
A GitLab security analyzer is the integration wrapper that runs a scanner, converts output into GitLab’s Secure report format, and participates in CI/CD. The scanner performs the analysis. The job is the CI execution unit on a runner. The report artifact is machine-readable evidence uploaded after the job. GitLab then validates the report schema and, where the subscription enables it, presents findings in pipeline/MR/vulnerability-management surfaces.
flowchart TD A[Commit / image / URL] --> B[CI job] B --> C[Analyzer image] C --> D[Scanner engine] D --> E[Secure JSON report] E --> F[Schema validation] F --> G[Raw artifact] F --> H[GitLab security presentation] H --> I[Human or policy decision]
The runner executes analyzer-controlled code against a specific target. The analyzer converts scanner output into a report. GitLab validates that report before it can become hosted security data. The raw artifact and the richer UI are therefore separate evidence surfaces.
4. Findings do not normally mean the scanner job failed
GitLab’s scanner-integration contract treats “scanner executed successfully and found vulnerabilities” as a successful scan. This matters: if ordinary CI failure semantics were used as the vulnerability gate, teams would conflate tool execution failures with risk decisions. A scanner job that genuinely fails can leave artifacts, but GitLab does not ingest its security report as normal findings when the job itself fails. Conversely, a successful analyzer can return many findings.
Production pattern: let scanners produce evidence, then implement deliberate vulnerability policies/approvals where your tier and operating model support them. Do not change analyzer exit codes casually just to turn every finding into a red pipeline.
5. Secure report schemas are an API contract
Reports declared under artifacts:reports:sast,
secret_detection, container_scanning,
dependency_scanning, or dast are validated
against GitLab-supported security report schemas. The filename is
conventional, not magical; the artifacts:reports key
declares the report type.
my_sast_job:
script:
- ./scanner --output report.json
artifacts:
reports:
sast: report.json
If the report declares an unsupported/malformed schema, GitLab can show a validation/ingestion error even though the shell script exited zero. That distinction becomes a core diagnostic in Lesson 4.
6. Finding, vulnerability, triage, and false positive
A finding is scanner evidence at a particular point in development. GitLab’s current terminology distinguishes findings on development branches from vulnerabilities managed after findings reach the default branch. The exact hosted presentation and state-management capabilities depend on tier. Severity estimates impact; confidence expresses how strongly a tool believes its rule matched; neither is a business-risk decision by itself.
A false positive is a scanner assertion that does not correspond to an actual exploitable weakness in the analyzed context. “We do not plan to fix it” is not the same as “false positive.” Record why a finding is false, remediated, accepted, or outside scope, and retain enough identity to know which commit/image/report the decision covered.
7. Scanner scope is part of the evidence
Every report needs a scope ledger. For source scanners record project, pipeline source, ref, commit SHA, analyzer job and report. For dependency evidence record lockfile/SBOM identity. For container evidence record the exact OCI digest rather than only a mutable tag. For DAST record the exact test URL/environment and deployment identity. If those fields do not match the release candidate, findings are not release evidence.
| Scanner | Minimum identity to preserve |
|---|---|
| SAST / secret detection |
Project + pipeline ID/source + CI_COMMIT_SHA +
analyzer version + report artifact.
|
| Dependency scanning | Source SHA + dependency file/SBOM + package versions + advisory-data time/source. |
| Container scanning | Image repository + immutable digest + analyzer/database version/time. |
| DAST | Test environment URL + deployment/source identity + profile/config + scan time. |
8. The runner and pipeline source are security boundaries
Security jobs execute repository/configuration-controlled code. A fork or merge request can be untrusted input even when the scanner itself is trusted. Do not expose protected variables, internal-network access, privileged persistent runners, or production credentials merely so a scanner can run. The safest required labs use GitLab-hosted/isolated runners with no production secret and tiny synthetic targets.
Analyzer images are supply-chain dependencies too. GitLab-managed templates deliberately receive updates; third-party components/images should have reviewed provenance and immutable references/digests where supported. Temporarily pinning a GitLab analyzer version can mitigate a regression, but indefinite pinning can also freeze security fixes and advisory updates.
9. Security reports can themselves be sensitive
Secret-detection reports can contain details about a matched secret and its location. DAST reports can contain request/response evidence. Source snippets and file paths can reveal private implementation details. Restrict project/artifact access accordingly; do not attach raw reports to public tickets or paste them into chat. This chapter uses only synthetic data.
10. Raw evidence versus hosted security presentation
Free users can run basic SAST, pipeline secret detection, and container scanning and obtain their raw report artifacts. Ultimate adds significant hosted analysis: merge-request security reports, vulnerability management, dashboards, approval/policy integrations, Advanced SAST, DAST, Dependency Scanning, and other advanced capabilities. Therefore the mandatory learning path proves raw report scope independently; paid UI tours are explicitly optional.
11. What “coverage-guided” means in this curriculum now
The title is stable because the academy curriculum is stable. Product reality changed: GitLab coverage-guided fuzz testing was deprecated in 18.0 and removed in 19.0. On GitLab 19.3, do not add old coverage-fuzzing templates and assume they work. If fuzzing still matters to your program, run an actively maintained external/open-source fuzzer as ordinary CI, preserve its crash/corpus/coverage evidence, and integrate results through a supported interface only when that interface is current. The general lesson survives: fuzzing explores execution behavior; it does not replace SAST, dependency analysis, or DAST.
12. Read-only inspection before any scanner change
Before enabling a scanner, inspect the current CI configuration and pipeline/runner context:
git rev-parse HEAD
git status --short
# In GitLab: Build > Pipeline editor > Validate / merged configuration
# Read-only API examples:
glab api "projects/$PROJECT_ID/pipelines/$PIPELINE_ID" | jq '{id,sha,ref,source,status}'
glab api "projects/$PROJECT_ID/pipelines/$PIPELINE_ID/jobs" | jq 'map({id,name,status,runner:(.runner.description // null)})'
Do not dump all environment variables or runner configuration. You need only the fields that prove scope.
Knowledge check
A SAST job exits zero and reports five vulnerabilities. Is that contradictory?
No. Scanner execution success and vulnerability findings are separate states; security scanners generally report findings in artifacts while the scan job itself succeeds.
Which identity is stronger for container-scanning evidence:
app:latest or an OCI digest?
The OCI digest. A tag can move; a digest identifies immutable manifest content.
Why might a Free user see a SAST JSON artifact but not the same vulnerability-management UI shown in an Ultimate demo?
Basic scanning and downloadable reports are Free-compatible, while richer MR/security dashboard/vulnerability-management presentation is tier-gated.
Is GitLab coverage-guided fuzz testing runnable in GitLab 19.3?
No. It was deprecated in 18.0 and removed in 19.0; use current standalone fuzzing approaches if needed.
What is the first response to a real exposed credential found by secret detection?
Revoke/rotate/disable the credential and contain access before history cleanup.
Why is runner choice part of the scanner threat model?
The scanner executes code/content from the project. A privileged or internal runner can turn untrusted MR content into access to host/network/secrets.
Summary
GitLab security scanners are evidence producers. Their value depends on exact scan scope, trusted execution, analyzer provenance, valid report schemas, and a deliberate decision process. Different scanners cover different assets, and no absence-of-findings result proves the software is secure.
Official references
Primary sources used for the current GitLab 19.3 behavior taught in this lesson:
- GitLab Docs — Application security testing
- GitLab Docs — SAST
- GitLab Docs — SAST analyzers
- GitLab Docs — Pipeline secret detection
- GitLab Docs — Customize pipeline secret detection
- GitLab Docs — Dependency scanning
- GitLab Docs — Container scanning
- GitLab Docs — DAST
- GitLab Docs — Security scanning results
- GitLab Docs — Security report validation
- GitLab Docs — CI/CD artifacts report types
- GitLab Docs — Security scanner integration
- GitLab Docs — Coverage-guided fuzz testing (deprecated)
- GitLab Docs — Deprecations and removals
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.