Rules / GL071
GL071 Manual approval gate without allow_failure: false
Severity: warn
OWASP: CICD-SEC-1 – Insufficient Flow Control Mechanisms
What glsec checks
glsec flags a job that looks like a manual approval gate in front of a production deploy but does not actually block the pipeline.
GitLab distinguishes two kinds of manual jobs (job control docs):
- Optional —
when: manualdefined at the top level of a job.allow_failuredefaults totrue, so the job's status does not contribute to the pipeline status. Later stages run and the pipeline can succeed even if nobody triggers the job. - Blocking —
allow_failure: false(the default whenwhen: manualis set insiderules:). The pipeline stops at that stage until an authorized user triggers the job.
A top-level when: manual job placed before a production deploy is therefore a no-op gate: the deploy runs regardless of whether the "approval" was ever clicked.
A job is flagged when all of the following hold:
- it has a top-level
when: manual(not insiderules:), - it does not set
allow_failure: false, - it has no
environment:of its own (it is a separate approval job, not the deploy), and - a production-like deploy job (an
environment:whose name looks likeprod/production/live/staging) exists in a later stage.
Trigger example
stages: [build, approve, deploy]
approve_prod:
stage: approve
when: manual # optional → allow_failure: true by default
script: [echo approved]
deploy_prod:
stage: deploy
environment: production
script: [./deploy.sh] # runs even if approve_prod was never triggered
Safe alternative
Make the gate blocking with allow_failure: false:
approve_prod:
stage: approve
when: manual
allow_failure: false # pipeline stops here until triggered
script: [echo approved]
Or move the manual condition into rules:, where it is blocking by default:
approve_prod:
stage: approve
rules:
- when: manual
script: [echo approved]
What is not flagged
when: manualinsiderules:— blocking by default.- A manual job with an explicit
allow_failure: false. - A manual job with no later production-deploy job (e.g. an optional cleanup/teardown job — the main false-positive class).
- The deploy job itself being manual — a manual deploy is a legitimate pattern; the gate problem is a separate approval job.
References
- GitLab: Types of manual jobs
- GL012:
when: alwayson a deploy job bypasses upstream quality gates - GL013: production deploy job has no branch restriction
Documentation for glsec 1.23.0. Source of this page · Rule implementation