SAST, Dependency Scanning, Secret Detection, Container Scanning, DAST, IaC Scanning, and Security Gates: Concepts, Architecture, and Mental Model
Model application-security scanning as evidence production: exact input and source revision, scanner/template identity, standardized report, findings, explicit policy outcome, exception workflow, and remediation proof.
Learning objectives
- Explain what SAST, dependency, secret, container, DAST, and IaC scanners actually inspect—and what they do not inspect.
- Trace exact source/input → scanner/template/version → standardized report → finding/policy → remediation evidence.
- Separate scanner job status, report ingestion, finding severity, and gate outcome.
- State current GitLab tier boundaries and the dependency-scanning migration direction without making paid features mandatory.
- Inspect source SHA, scanner identity, report path/schema, findings, and policy state before changing anything.
1. The practical problem: “the security job passed” is not a security conclusion
Chapter 24 treated test and quality reports as evidence rather than as magic widgets. Security scanning needs the same discipline, with an additional complication: each scanner sees a different input and threat model. A SAST analyzer can report no source-code weakness while a vulnerable dependency remains. A dependency scanner can be clean while a secret is committed. A container scan can be clean while the running service exposes an insecure endpoint. A DAST result can be technically correct but operationally unacceptable if the target was production.
This chapter therefore treats a security pipeline as an evidence-producing control, not as a green shield icon. The scanner must be identified, its input bounded, its report preserved, its findings interpreted, and any blocking policy made explicit. Exceptions need an owner, rationale, and expiry rather than an invisible bypass.
2. Scanner classes before configuration
| Scanner class | Primary input | Question it can answer | Important blind spot |
|---|---|---|---|
| SAST | Source code / compiled representation | Does code contain patterns/data flows associated with vulnerabilities? | Does not prove dependencies, runtime configuration, or a live service are safe. |
| Dependency scanning / SCA | Lockfiles, dependency graph, or SBOM | Are resolved third-party components associated with known advisories? | Does not prove a vulnerable path is reachable unless reachability analysis is available/configured. |
| Secret detection | Repository content/history or push content | Does committed/pushed text resemble a secret pattern? | Cannot guarantee a leaked secret was never copied before removal; real leaks require rotation. |
| Container scanning | Container image layers/packages | Do image OS/language packages match vulnerability data? | Does not test the live application or deployment configuration. |
| DAST | Running web application/API URL | Does the live target exhibit exploitable behavior or misconfiguration? | Needs a deployed, authorized test target and network access; scope errors can hit real systems. |
| IaC scanning | Terraform/Kubernetes/CloudFormation and similar definitions | Do infrastructure definitions contain insecure configuration patterns? | Does not prove the deployed cloud/resource state matches the files. |
3. Mental model: input → scanner → report → finding → policy → proof
The left side of the chain is technical detection; the right side is governance. The scanner reads an exact target with an exact engine/ruleset version. It emits a report. GitLab or another parser ingests that report. A policy may then classify or gate findings. The remediation is a new change that must be rescanned; dismissing or excepting a finding is not the same as fixing it.
| State layer | Evidence to capture | Why it matters |
|---|---|---|
| Source/revision |
CI_PIPELINE_SOURCE, ref,
CI_COMMIT_SHA, pipeline/job IDs
|
Findings are meaningful only when bound to the exact revision and pipeline that produced them. |
| Compiled configuration | Merged YAML, effective rules, included template/component identity | Proves which scanners were actually selected instead of which scanners an author intended. |
| Scanner/tool | Scanner/analyzer name and version, image identity, rule/config version | Detection changes as engines, rules, and vulnerability databases change. |
| Input target | Source tree, lockfile/SBOM, container digest, URL, or IaC files | Each scanner class sees a different attack surface and trust boundary. |
| Report artifact | Path, report type/schema, checksum, raw finding count | Separates raw evidence from UI ingestion or policy decisions. |
| Finding/policy | Finding ID, severity/confidence, gate rule, exception record | A finding is evidence; a gate is a separate governance decision. |
| Identity/trust | Runner/executor, token class, protected-variable exposure | Untrusted code must not receive production credentials merely because it is being scanned. |
| External state | DAST target identity/URL, container registry digest, deployment state if any | Prevents scans from accidentally testing or mutating production. |
4. Current GitLab availability: scanner execution is not the same as security management
| Capability | Current required path | What the chapter does |
|---|---|---|
| SAST basic scanning | Free / Premium / Ultimate | Teach Free basic scanning and raw reports; advanced MR vulnerability-management workflows remain optional. |
| Pipeline Secret Detection | Free / Premium / Ultimate | Teach synthetic-secret scanning without using real credentials. |
| Container Scanning | Free / Premium / Ultimate | Teach image-digest identity and optional GitLab/Trivy paths. |
| IaC scanning | Free / Premium / Ultimate | Teach source/IaC report evidence; Ultimate adds richer MR/vulnerability-management workflows. |
| Dependency Scanning | Ultimate in current primary docs | Mandatory path uses local/open-source dependency/SBOM concepts; GitLab native workflow is optional. |
| DAST | Ultimate | Mandatory path uses a local target-boundary simulation; no production endpoint is scanned. |
| Security policies / centralized enforcement | Ultimate | Model the policy logic locally so learners understand the contract without requiring a paid tier. |
Tier availability can differ between running a scanner and viewing/managing findings in merge-request or vulnerability-management UI. Always verify the current feature page for the exact workflow you intend to rely on.
5. Version and template identity are security evidence
GitLab-managed analyzers are container images and their detection
behavior changes over time. Stable security templates are designed
for production stability; Latest templates can change between minor
GitLab versions and should not be mixed with Stable templates in the
same project. GitLab also publishes CI/CD components for several
security scanners, but a component reference such as
@main is a moving reference. Production reuse should
have an explicit update policy rather than silently following
mutable configuration.
Dependency Scanning deserves special attention. Current docs
recommend the SBOM-based path. The legacy Gemnasium-based
implementation was deprecated in GitLab 17.9 and is proposed for
removal in GitLab 20.0. The migration guide directs stable/latest
template users to the v2 dependency-scanning template
and component users to major version 2 of the main component.
6. A security report has a schema, not just JSON syntax
A custom scanner integration must emit a GitLab-supported security-report schema. Valid JSON is insufficient. GitLab validates the declared report schema; invalid reports are not ingested, deprecated schemas can warn, and removed schema versions are rejected. For local/external scanner labs in this chapter, raw scanner JSON is preserved as a normal artifact unless the tool is deliberately adapted to a valid GitLab schema.
This distinction prevents a common teaching error: relabeling
arbitrary Semgrep, Trivy, or custom JSON as
artifacts:reports:sast. A report becomes a GitLab
security report only when its schema and category contract are
correct.
7. Read-only inspection before any repair
printf 'source=%s ref=%s sha=%s pipeline=%s job=%s\n' \
"$CI_PIPELINE_SOURCE" "$CI_COMMIT_REF_NAME" "$CI_COMMIT_SHA" \
"$CI_PIPELINE_ID" "$CI_JOB_ID"
# Record scanner/report evidence without printing secret-bearing variables.
find security-reports -maxdepth 1 -type f -print 2>/dev/null || true
sha256sum security-reports/* 2>/dev/null || true
# Inspect versions through the tool itself, not by guessing an image tag.
semgrep --version 2>/dev/null || true
trivy --version 2>/dev/null || true
8. Trust boundary: scanning untrusted code does not justify privileged credentials
Security scanners often execute against merge-request content, containers, or URLs. That does not make the input trusted. A fork or untrusted branch should not receive production secrets, cloud-admin credentials, a privileged runner, or a route to production simply because the job is named “security.” DAST is especially sensitive: GitLab documentation explicitly advises running DAST against a test server. If a target cannot be proven disposable/authorized, do not scan it.
Knowledge check
Why can a security scanner job be green while the pipeline still contains serious findings?
Many scanners return success when execution completed and encode findings in the report. A separate gate or policy decides whether findings block delivery.
What is the most important difference between SAST and DAST inputs?
SAST analyzes source/compiled code; DAST actively examines a running authorized web/API target. Their trust and network boundaries are different.
Why should arbitrary Semgrep JSON not be declared as a GitLab SAST report?
GitLab security reports must conform to the supported SAST security-report schema. Arbitrary JSON may be valid JSON but still fail ingestion.
Which current GitLab-native scanner classes in this chapter require Ultimate for the feature workflow?
Current primary docs list Dependency Scanning and DAST as Ultimate. SAST basic scanning, Secret Detection, Container Scanning, and IaC basic scanning have Free paths.
What evidence binds a finding to a reproducible scan?
Exact input/source identity, pipeline/job IDs, scanner/analyzer and rules/config version, raw report path/checksum, and the policy/exception decision.
Version and compatibility note
GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.
Official references and version notes
Documentation verification date: 2026-09-12. Basic
GitLab SAST, pipeline Secret Detection, Container Scanning, and IaC
scanning are documented for Free/Premium/Ultimate. Current GitLab
Dependency Scanning and DAST are Ultimate. Security policy
enforcement is Ultimate. GitLab's current Dependency Scanning
direction is SBOM-based; the legacy Gemnasium-based implementation
was deprecated in GitLab 17.9 and is proposed for removal in GitLab
20.0. Stable security templates are recommended for production
workflows; Latest templates change more frequently.
AST_ENABLE_MR_PIPELINES="true" is the current
recommended switch for supported application-security scans in
merge-request pipelines. SAST and IaC scanner jobs require supported
Linux runner/executor/architecture conditions in GitLab-managed
paths; DAST requires a running authorized test target. Recheck
analyzer prerequisites before production rollout.
- SAST — official reference.
- SAST analyzers — official reference.
- Secret detection — official reference.
- Secret detection configuration — official reference.
- Container scanning — official reference.
- Dependency scanning — official reference.
- Dependency scanning migration to SBOM — official reference.
- DAST — official reference.
- DAST browser analyzer — official reference.
- IaC scanning — official reference.
- Security configuration — official reference.
- Security policies — official reference.
- Security scanner integration and report schemas — official reference.
- CI/CD YAML syntax — official reference.
Current assumptions used in this chapter: Version-sensitive YAML, Runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations must be verified against the exact GitLab, GitLab Runner, tool, and external-system versions used in production. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for reproducible work.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.