Skip to content
oss-kit
Install

A GitLab pipeline pins external execution inputs and restricts inbound job-token access

Rule
R-SEC-06
Area
Security posture · 6 of 15
Forge scope
GitLab only
Fixed by
oss-harden

GitLab has no action-shaped uses: step, so the same mutable-reference problem arrives through image:, services:, and external include: entries. A floating image tag or an include: on a branch name changes what runs without a diff in your repository. Separately, an open inbound job-token scope lets a job token from any project access this project when its triggering user is authorized. The allowlist is a target-project control; it does not describe where this project’s own job token can go.

Observable check

every image: and services: entry in .gitlab-ci.yml and its included files names an image by digest (image@sha256:...), every external include:project and include:component entry resolves to a full commit SHA, every include:remote entry sets integrity:, and GET /projects/:id/job_token_scope reports inbound_enabled true with its allowlist naming only source projects that need access to this target project.

Where this comes from

Last read against these sources on 2026-07-28.

ci_job_token confirms the inbound allowlist is a target-project control defaulting to the project itself, which is the distinction the rule's statement makes. include:integrity is real and documented in the YAML reference, not in includes/: added in GitLab 17.9, 'Use integrity with include:remote to specify a SHA256 hash of the included remote file', value a base64 SHA256 with a sha256- prefix. Scope limit that matters: it covers include:remote only. include:component, the CI/CD Catalog mechanism most GitLab projects actually use for third-party CI content, has no integrity keyword and is pinned by @<version> instead. pipeline_security covers the image digest half.

Read the whole standard