Chapter 25Lesson 01~320 minutes

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.

Mental modelSASTSecret detectionReportsTrust boundaryGitLab 19.3

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.
Availability baseline — verified 2026-08-22 against current GitLab 19.3 documentation. Basic SAST, pipeline secret detection, and pipeline container scanning run on Free/Premium/Ultimate across GitLab.com, Self-Managed, and Dedicated, and Free/Premium users can download their JSON report artifacts. Rich merge-request security presentation, vulnerability-management workflows, security dashboards, policy enforcement, and several advanced analyzer features are Ultimate. GitLab Dependency Scanning is currently Ultimate. GitLab DAST is currently Ultimate. The curriculum phrase “Coverage-Guided Security” is retained for path/title stability, but GitLab coverage-guided fuzz testing was deprecated in 18.0 and removed in 19.0; it is therefore taught as historical/migration context, not as a runnable GitLab 19.3 feature. Required labs use only SAST/secret-detection raw evidence or safe fixtures and do not require a paid tier.

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.

Security evidence flow
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.

Credential incident rule: if a real secret is exposed, revoke/rotate/disable it first, then investigate use and contain access. Removing the string from Git history is cleanup, not revocation.

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?

Which identity is stronger for container-scanning evidence: app:latest or an OCI digest?

Why might a Free user see a SAST JSON artifact but not the same vulnerability-management UI shown in an Ultimate demo?

Is GitLab coverage-guided fuzz testing runnable in GitLab 19.3?

What is the first response to a real exposed credential found by secret detection?

Why is runner choice part of the scanner threat model?

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:

Next lesson

Guided Hands-On Workflow and Core Operations

Create a disposable Free-compatible evidence path with SAST and pipeline secret detection, then compare raw evidence with paid/UI-only capabilities and scanner-scope fixtures.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.