Skip to main content

CI/CD provider

ISSUE-412HighPipeline Composition

Docker-in-Docker service detected

Control: Pipeline must not use Docker-in-Dockerยท Config key: pipelineMustNotUseDockerInDocker

๐Ÿ“‹ What is this?

A CI/CD job uses a Docker-in-Docker (dind) service. On shared runners running in privileged mode, this creates a Docker daemon inside the CI container that enables container escape, lateral movement between jobs, and access to secrets from other projects on the same runner.

โš ๏ธ Impact

Docker-in-Docker in privileged mode grants near-root access to the host. An attacker (or a compromised dependency) can escape the container, list and inspect other containers on the runner, read volumes mounted by other CI jobs (potentially containing secrets), and probe the runner's internal network.

๐Ÿ”ง How to fix

Replace Docker-in-Docker with a rootless container build tool. Kaniko builds container images inside a container without requiring a Docker daemon or privileged mode.

โœ— BeforeThis job runs a Docker daemon inside the CI container, requiring privileged mode on the runner.
# .gitlab-ci.yml: โŒ Uses Docker-in-Docker service
build-image:
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
โœ“ AfterKaniko builds container images without requiring a Docker daemon or privileged mode.
# .gitlab-ci.yml: โœ… Uses Kaniko (no privileged mode needed)
build-image:
image:
name: gcr.io/kaniko-project/executor:v1.23.2-debug
entrypoint: [""]
script:
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# .plumber.yaml
# pipelineMustNotUseDockerInDocker:
# enabled: true
# detectInsecureDaemon: true

๐Ÿ’ก Tips

  • Kaniko and Buildah are the most common alternatives to Docker-in-Docker for building container images in CI/CD.
  • If Docker-in-Docker is truly required, ensure it runs on dedicated (not shared) runners with proper network isolation.
  • The detectInsecureDaemon option (default: true) also flags jobs where TLS is disabled between the CI job and the DinD daemon.
  • This control inspects the services: declaration in the CI configuration. A Docker daemon started manually from script: (e.g., dockerd &) or embedded in a custom image is not detected (known limitation).
  • Only images with docker: prefix and a tag containing dind or latest are matched. Renamed or aliased DinD images (e.g., myregistry.com/custom-builder:stable) are not detected.

โš™๏ธ Configuration

This control is configured in .plumber.yaml under the gitlab section:

gitlab:
  controls:
    pipelineMustNotUseDockerInDocker:
      enabled: true

See the CLI documentation for the full configuration reference.