Rules / GL008
GL008 Security scan job silenced
Severity: warn
OWASP: CICD-SEC-1 – Insufficient Flow Control Mechanisms
What glsec checks
glsec flags any of GitLab's predefined security scan jobs that has been silenced — its failures ignored, or the job kept from running at all:
| Form | Effect |
|---|---|
allow_failure: true |
The scan runs, but its failure does not block the pipeline |
when: manual (job has no rules:) |
The scan never runs on its own |
rules: whose only entry is an unconditional when: never |
The job is switched off in every context |
rules: whose only entry is an unconditional when: manual |
The job never runs on its own |
The job names, and the templates that define them:
| Job name | Template |
|---|---|
sast (configuration-only, not checked) |
Security/SAST.gitlab-ci.yml |
iac-sast, kics-iac-sast |
Security/SAST-IaC.gitlab-ci.yml |
secret_detection |
Security/Secret-Detection.gitlab-ci.yml |
dast |
Security/DAST.gitlab-ci.yml |
dast_api |
Security/DAST-API.gitlab-ci.yml |
container_scanning |
Security/Container-Scanning.gitlab-ci.yml |
dependency_scanning (configuration-only, not checked) |
Security/Dependency-Scanning.gitlab-ci.yml |
semgrep-sast, gitlab-advanced-sast, gitlab-advanced-sast-cpp, gitlab-advanced-sast-ext, gosec-sast, spotbugs-sast, bandit-sast, eslint-sast, kubesec-sast, pmd-apex-sast, security-code-scan-sast, sobelow-sast |
Security/SAST.gitlab-ci.yml |
gemnasium-dependency_scanning, gemnasium-maven-dependency_scanning, gemnasium-python-dependency_scanning |
Security/Dependency-Scanning.gitlab-ci.yml |
coverage_fuzzing |
Security/Coverage-Fuzzing.gitlab-ci.yml |
api_fuzzing |
Security/API-Fuzzing.gitlab-ci.yml |
license_scanning |
Security/License-Scanning.gitlab-ci.yml |
The analyzer jobs are the ones that actually run the scan, so switching one of them off is the same as switching the scan off. The names are taken from the current templates on gitlab.com; the analyzers deprecated in GitLab 16.8 are not listed. (sast-iac is the template file SAST-IaC.gitlab-ci.yml, not a job — the jobs it creates are iac-sast and kics-iac-sast.)
The two base jobs, sast and dependency_scanning, are configuration-only and are not checked at all. In the current templates both carry rules: - when: never and a script that just exits 1; the analyzers inherit from them through .sast-analyzer / .ds-analyzer, which set allow_failure: true themselves. So sast: allow_failure: true changes nothing, and sast: rules: [when: never] is already the template default and switches no analyzer off, since every analyzer carries its own rules:. Switching a scan off is covered by the analyzer jobs above and by SAST_DISABLED and friends (GL082).
The allow_failure: {exit_codes: [...]} form (exit-code-specific) is not flagged — that is a deliberate choice, not a blanket suppression.
Neither is a template-defaulted allow_failure: true. .sast-analyzer, .ds-analyzer, .secret-analyzer, container_scanning and iac-sast already set it, and every analyzer job above extends one of those hidden jobs, so a pipeline that sets it again on semgrep-sast or secret_detection changes nothing and is not reported. The two configuration-only base jobs are absent from that list because they are not checked at all, which is a stronger statement than an exemption from this one check.
What is deliberately not flagged
The rules: check is narrow, because most when: never entries on a scan job are legitimate:
secret_detection:
rules:
- if: $SECRET_DETECTION_DISABLED # the template's own kill switch — keeping
when: never # it in an override is idiomatic
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
dast:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- when: never # "otherwise don't run" — scoping, not disabling
A conditional when: never scopes the job; only a lone, unconditional entry disables it outright. The dangerous half of the first example — actually setting SECRET_DETECTION_DISABLED — is GL082's job.
Trigger example
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/DAST.gitlab-ci.yml
- template: Security/DAST-API.gitlab-ci.yml
dast:
allow_failure: true # scan failures are silently ignored
script:
- ./build.sh
semgrep-sast:
rules:
- when: never # the analyzer that actually scans, switched off
script:
- ./build.sh
secret_detection:
when: manual # never runs unless somebody clicks it
script:
- ./build.sh
dast_api:
rules:
- when: never # switched off outright
script:
- ./build.sh
Safe alternative
Remove allow_failure: true so the pipeline fails when the security scan fails:
include:
- template: Security/SAST.gitlab-ci.yml
# No allow_failure override — pipeline fails if SAST finds issues
If you need the pipeline to pass during a transition period, use a GitLab security policy to enforce scan requirements separately from pipeline status, rather than silencing failures.
Why this matters
When a GitLab security scan job has allow_failure: true:
- The pipeline passes even if the scan exits with an error
- GitLab's security dashboard may not ingest scan results from a failed job
- Vulnerabilities are not surfaced in merge request widgets or approval rules
- The security gate is effectively disabled, defeating the purpose of including the scan
This is especially dangerous when the job fails due to a misconfiguration (wrong image, expired token) rather than an actual scan finding — the failure is invisible.
Documentation for glsec 1.23.0. Source of this page · Rule implementation