glsec

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:

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