Rules / GL017
GL017 Deploy/publish job has no tags: restriction
Severity: warn
OWASP: CICD-SEC-5 – Insufficient PBAC
What glsec checks
glsec flags deployment and publish jobs that do not restrict which runner can execute them via tags:. Without a tags: filter, the job runs on any available runner — including compromised or untrusted self-hosted runners that a team may not intend to use for production workloads.
A job is considered a deployment/publish job if it has:
- An
environment:key (any value), or - A
stage:value containingdeploy,release,publish, orship
Trigger example
deploy-prod:
stage: deploy
environment: production
script:
- ./deploy.sh
# no tags: — runs on any available runner
Safe alternative
deploy-prod:
stage: deploy
environment: production
tags:
- production
- docker
script:
- ./deploy.sh
Why this matters
In organisations that mix GitLab SaaS runners with self-hosted runners, a deploy job without tags: may land on a shared or less-trusted runner. If that runner is compromised, secrets injected into the deployment environment (SSH keys, cloud credentials, API tokens) are exposed to the attacker.
Restricting runners with tags: ensures only explicitly trusted infrastructure executes sensitive jobs.
False positives
If you intentionally run all jobs — including deployments — on GitLab SaaS shared runners and have no self-hosted runners in the project, this finding can be suppressed:
deploy-prod:
stage: deploy
script:
- ./deploy.sh
# glsec:ignore GL017 -- SaaS-only project, no self-hosted runners
Documentation for glsec 1.23.0. Source of this page · Rule implementation