GitLab 18 🦊 DevSecOps Scanning: SAST, Secret Detection, and Dependency Scanning
A pipeline that builds and tests without scanning for vulnerabilities is a pipeline that ships risk. GitLab provides three core security scanners as CI/CD templates: Static Application Security Testing (SAST) analyzes source code for injection flaws and insecure patterns, Secret Detection scans for accidentally committed credentials, and Dependency Scanning checks third-party libraries against known vulnerability databases. The exam tests the template names, the pipeline integration, and the distinction between the scanners. The critical point is that these scanners are not enabled by default; they must be included in .gitlab-ci.yml or enabled through the security configuration UI. Once included, the scanners run automatically and upload their findings to the Security Dashboard and the merge request widget.
Key point: SAST scans your code. Secret Detection scans for secrets. Dependency Scanning scans your dependencies. Each is enabled by including a template in .gitlab-ci.yml: Security/SAST.gitlab-ci.yml, Security/Secret-Detection.gitlab-ci.yml, and Jobs/Dependency-Scanning.gitlab-ci.yml . The scanners run in the test stage by default and produce JSON report artifacts that GitLab parses.
Why DevSecOps scanning requires explicit configuration
The opt-in problem. GitLab does not scan your code by default. The scanners are templates that must be included in the pipeline configuration. The UI offers a “Security configuration” page that can enable them via a merge request, but the underlying change is still an include statement in .gitlab-ci.yml . Without the include, the scanners do not run, and the Security Dashboard remains empty.
The SAST language detection problem. The SAST template does not run every analyzer on every project. It detects the programming languages in the repository and selects the matching analyzers. A JavaScript project uses the Semgrep analyzer. A Ruby project uses the Brakeman analyzer. A Python project uses the Bandit analyzer. The SAST.gitlab-ci.yml template handles the detection and dispatch automatically . The exam tests the template name, not the individual analyzer.
The Secret Detection pattern problem. Secret Detection uses Gitleaks as its underlying engine. It scans the repository for patterns that match known secret formats: AWS access keys, GitHub tokens, private keys, and hundreds of other credential types . It does not scan dependencies, and it does not analyze code logic. It scans for strings that look like secrets. The Secret-Detection.gitlab-ci.yml template enables it.
The Dependency Scanning lockfile problem. Dependency Scanning does not scan code. It reads the project’s lockfiles (package-lock.json, Gemfile.lock, poetry.lock) and compares the listed packages against the GitLab Advisory Database . If a lockfile is missing or outdated, the scan is incomplete. The scanner requires a supported package manager and a lockfile that reflects the actual dependency tree.
The trade-off. The scanners add time to the pipeline. SAST is the slowest because it parses and analyzes source code. Secret Detection is the fastest because it only scans strings. Dependency Scanning is fast but limited to the lockfile’s contents. The exam tests the template names, the report artifacts, and the purpose of each scanner.
a. SAST: scanning source code
The SAST template is included at the top level of .gitlab-ci.yml. It creates the sast job automatically.
include:
- template: Security/SAST.gitlab-ci.yml
The sast job runs in the test stage by default. It detects the languages in the repository and runs the matching analyzers. The findings are uploaded as a sast report artifact, which GitLab parses and displays in the Security Dashboard and the merge request widget .
The template can be customized with variables. The SAST_EXCLUDED_PATHS variable excludes directories from the scan. The SAST_EXCLUDED_ANALYZERS variable disables specific analyzers. The GITLAB_ADVANCED_SAST_ENABLED variable (Ultimate only) enables the advanced SAST engine .
variables:
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
The SAST findings are categorized by severity: Critical, High, Medium, Low, and Info. A Critical finding is a vulnerability that is directly exploitable. A High finding is a vulnerability that is likely exploitable. The merge request widget shows the number of new findings compared to the target branch.
b. Secret Detection: scanning for credentials
The Secret Detection template is included the same way.
include:
- template: Security/Secret-Detection.gitlab-ci.yml
The secret_detection job scans the repository for patterns that match known secret formats. The findings are uploaded as a secret_detection report artifact . The Security Dashboard displays the findings, and the merge request widget shows new secrets that were introduced in the branch.
The scanner supports custom rules. A gitleaks.toml file can be added to the repository, and the SECRET_DETECTION_RULESET_GIT_REFERENCE variable can point to a remote ruleset repository . This allows an organization to extend the default ruleset with internal secret formats, such as proprietary API keys or internal password patterns.
The scanner also supports a historic scan. The SECRET_DETECTION_HISTORIC_SCAN variable scans the entire Git history, not just the current state. This is useful for finding secrets that were committed in the past and later removed from the working tree .
c. Dependency Scanning: scanning third-party libraries
The Dependency Scanning template is included in the same way.
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
The dependency_scanning job reads the project’s lockfiles and compares the listed packages against the GitLab Advisory Database. It does not execute the code. It does not need the code to compile. It only needs the lockfile .
The scanner supports a range of package managers: npm, yarn, pnpm, Bundler, pip, Maven, Gradle, NuGet, and others. The lockfile must be present and up to date. A package.json without a package-lock.json is not sufficient for the npm scanner.
The findings are uploaded as a dependency_scanning report artifact. The Security Dashboard displays the vulnerable packages, the CVE identifiers, and the patched versions. The merge request widget shows the new vulnerabilities introduced by the branch.
The scanner also produces a CycloneDX Software Bill of Materials (SBOM) for each supported lockfile. The SBOM is saved as gl-sbom-<package-type>-<package-manager>.cdx.json and can be used for continuous vulnerability scanning, which checks for new advisories without requiring a new pipeline run .
Complete Example Session
# ============================================
# PART 1: INCLUDE THE SCANNERS
# ============================================
cat > .gitlab-ci.yml <<'EOF'
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
stages:
- test
EOF
# ============================================
# PART 2: COMMIT AND PUSH
# ============================================
git add .gitlab-ci.yml
git commit -m "Add DevSecOps scanning"
git push origin main
# ============================================
# PART 3: OBSERVE THE PIPELINE
# ============================================
# Build → Pipelines → click the pipeline
# The pipeline shows three new jobs:
# - sast
# - secret_detection
# - dependency_scanning
# ============================================
# PART 4: VIEW THE SECURITY DASHBOARD
# ============================================
# Secure → Security dashboard
# The dashboard shows the findings from all three scanners.
# ============================================
# PART 5: CUSTOMIZE SAST
# ============================================
variables:
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
SAST_EXCLUDED_ANALYZERS: "eslint"
# ============================================
# PART 6: CUSTOMIZE SECRET DETECTION
# ============================================
variables:
SECRET_DETECTION_HISTORIC_SCAN: "true"
# ============================================
# PART 7: VIEW FINDINGS IN MERGE REQUEST
# ============================================
# Create a merge request.
# The MR widget shows:
# - SAST findings
# - Secret detection findings
# - Dependency scanning findings
# ============================================
# PART 8: OBSERVE THE SBOM
# ============================================
# The dependency_scanning job produces:
# gl-sbom-npm-npm.cdx.json
# The SBOM is available as an artifact.
# ============================================
# PART 9: CHECK THE VULNERABILITY REPORT
# ============================================
# Secure → Vulnerability report
# Filter by scanner: SAST, Secret Detection, Dependency Scanning
The nine parts trace the scanning workflow: template inclusion, commit, pipeline observation, dashboard view, SAST customization, Secret Detection customization, merge request findings, SBOM observation, and vulnerability report.
Quick Reference
Scanner Templates
| Scanner | Template | Job Name |
|---|---|---|
| SAST | Security/SAST.gitlab-ci.yml | sast |
| Secret Detection | Security/Secret-Detection.gitlab-ci.yml | secret_detection |
| Dependency Scanning | Jobs/Dependency-Scanning.gitlab-ci.yml | dependency_scanning |
Scanner Purposes
| Scanner | Scans | Input |
|---|---|---|
| SAST | Source code | Repository files |
| Secret Detection | Credentials | Repository files and history |
| Dependency Scanning | Libraries | Lockfiles |
Key Variables
| Variable | Scanner | Purpose |
|---|---|---|
SAST_EXCLUDED_PATHS | SAST | Exclude directories |
SAST_EXCLUDED_ANALYZERS | SAST | Disable analyzers |
SECRET_DETECTION_HISTORIC_SCAN | Secret Detection | Scan full history |
SECRET_DETECTION_RULESET_GIT_REFERENCE | Secret Detection | Remote ruleset |
Report Artifacts
| Scanner | Artifact |
|---|---|
| SAST | gl-sast-report.json |
| Secret Detection | gl-secret-detection-report.json |
| Dependency Scanning | gl-dependency-scanning-report.json |
| Dependency Scanning (SBOM) | gl-sbom-*.cdx.json |
Best Practices
✅ Do This:
include:
- template: Security/SAST.gitlab-ci.yml
<!-- Include the SAST template explicitly --> # ✅
variables:
SAST_EXCLUDED_PATHS: "test, spec"
<!-- Exclude test files from SAST --> # ✅
variables:
SECRET_DETECTION_HISTORIC_SCAN: "true"
<!-- Scan history for leaked secrets --> # ✅
❌ Don’t Do This:
# Assume scanners run by default
<!-- They must be included or enabled --> # ❌
# Rely on Dependency Scanning without a lockfile
<!-- The scan is incomplete without it --> # ❌
# Ignore Critical findings in the merge request
<!-- They indicate exploitable vulnerabilities --> # ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| SAST job not running | Template not included | Add include statement |
| Secret Detection finds nothing | No secrets in code | Expected; scanner is working |
| Dependency scan incomplete | No lockfile | Generate and commit lockfile |
| Custom rules not applied | Wrong variable | Use SECRET_DETECTION_RULESET_GIT_REFERENCE |
| Findings not in MR | Scanner not enabled on target | Run scanner on target branch first |
Real-World Examples
1. Include SAST
include:
- template: Security/SAST.gitlab-ci.yml
2. Include Secret Detection
include:
- template: Security/Secret-Detection.gitlab-ci.yml
3. Include Dependency Scanning
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
4. Exclude Paths
variables:
SAST_EXCLUDED_PATHS: "vendor, node_modules"
5. Historic Secret Scan
variables:
SECRET_DETECTION_HISTORIC_SCAN: "true"
6. Custom Secret Ruleset
variables:
SECRET_DETECTION_RULESET_GIT_REFERENCE: "my-org/secret-config@main"
7. View Dashboard
Secure → Security dashboard
8. View Vulnerability Report
Secure → Vulnerability report
9. SBOM Artifact
gl-sbom-npm-npm.cdx.json
10. Check MR Widget
Merge request → Security scanning widget
Visual
Scanner Responsibilities
┌──────────────────────────────────────────────┐
│ SAST │
│ ├── Scans: source code │
│ ├── Finds: injection, XSS, insecure patterns│
│ └── Template: Security/SAST.gitlab-ci.yml │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Secret Detection │
│ ├── Scans: repository files + history │
│ ├── Finds: API keys, tokens, passwords │
│ └── Template: Security/Secret-Detection... │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Dependency Scanning │
│ ├── Scans: lockfiles │
│ ├── Finds: vulnerable libraries │
│ └── Template: Jobs/Dependency-Scanning... │
└──────────────────────────────────────────────┘
Pipeline Integration
┌──────────────────────────────────────────────┐
│ .gitlab-ci.yml │
│ include: │
│ - Security/SAST.gitlab-ci.yml │
│ - Security/Secret-Detection.gitlab-ci.yml │
│ - Jobs/Dependency-Scanning.gitlab-ci.yml │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Pipeline runs │
│ ├── sast job │
│ ├── secret_detection job │
│ └── dependency_scanning job │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Security Dashboard + MR widget │
└──────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| SAST template | Security/SAST.gitlab-ci.yml |
| Secret Detection template | Security/Secret-Detection.gitlab-ci.yml |
| Dependency Scanning template | Jobs/Dependency-Scanning.gitlab-ci.yml |
| SAST scans | Source code |
| Secret Detection scans | Repository files and history |
| Dependency Scanning scans | Lockfiles |
| SAST exclusion | SAST_EXCLUDED_PATHS |
| Historic secret scan | SECRET_DETECTION_HISTORIC_SCAN |
| Findings location | Security Dashboard + MR widget |
Key takeaways:
- The scanners are opt-in. They must be included in
.gitlab-ci.ymlor enabled through the security configuration UI. Without the include, no scan runs and no findings appear . - SAST scans source code. It detects the languages in the repository and runs the matching analyzers. The findings are categorized by severity and displayed in the merge request widget .
- Secret Detection scans for credentials. It uses Gitleaks to find patterns that match known secret formats. It can scan the full Git history with
SECRET_DETECTION_HISTORIC_SCAN. - Dependency Scanning reads lockfiles. It compares the listed packages against the GitLab Advisory Database. It does not scan code and does not need the code to compile. A missing lockfile produces an incomplete scan .
- The findings appear in two places. The Security Dashboard shows the aggregate view. The merge request widget shows the new findings introduced by the branch compared to the target branch.
Remember: SAST scans your code. Secret Detection scans for secrets. Dependency Scanning scans your dependencies. Each is a template. Each produces a report artifact. Each feeds the Security Dashboard. The exam tests the template names and the purpose of each scanner. The findings are not automatic; the include is the gate.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!