| | |

GitLab 18 🦊 DevSecOps Scanning: SAST, Secret Detection, and Dependency Scanning

⏱️ Estimated read: 10 min | |

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

ScannerTemplateJob Name
SASTSecurity/SAST.gitlab-ci.ymlsast
Secret DetectionSecurity/Secret-Detection.gitlab-ci.ymlsecret_detection
Dependency ScanningJobs/Dependency-Scanning.gitlab-ci.ymldependency_scanning

Scanner Purposes

ScannerScansInput
SASTSource codeRepository files
Secret DetectionCredentialsRepository files and history
Dependency ScanningLibrariesLockfiles

Key Variables

VariableScannerPurpose
SAST_EXCLUDED_PATHSSASTExclude directories
SAST_EXCLUDED_ANALYZERSSASTDisable analyzers
SECRET_DETECTION_HISTORIC_SCANSecret DetectionScan full history
SECRET_DETECTION_RULESET_GIT_REFERENCESecret DetectionRemote ruleset

Report Artifacts

ScannerArtifact
SASTgl-sast-report.json
Secret Detectiongl-secret-detection-report.json
Dependency Scanninggl-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

PitfallWhy It HappensFix
SAST job not runningTemplate not includedAdd include statement
Secret Detection finds nothingNo secrets in codeExpected; scanner is working
Dependency scan incompleteNo lockfileGenerate and commit lockfile
Custom rules not appliedWrong variableUse SECRET_DETECTION_RULESET_GIT_REFERENCE
Findings not in MRScanner not enabled on targetRun 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

ItemValue
SAST templateSecurity/SAST.gitlab-ci.yml
Secret Detection templateSecurity/Secret-Detection.gitlab-ci.yml
Dependency Scanning templateJobs/Dependency-Scanning.gitlab-ci.yml
SAST scansSource code
Secret Detection scansRepository files and history
Dependency Scanning scansLockfiles
SAST exclusionSAST_EXCLUDED_PATHS
Historic secret scanSECRET_DETECTION_HISTORIC_SCAN
Findings locationSecurity Dashboard + MR widget

Key takeaways:

  • The scanners are opt-in. They must be included in .gitlab-ci.yml or 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.

Was this helpful?


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!