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.
# .gitlab-ci.yml — ❌ Uses Docker-in-Docker servicebuild-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# .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
detectInsecureDaemonoption (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 fromscript:(e.g.,dockerd &) or embedded in a custom image is not detected (known limitation). - Only images with
docker:prefix and a tag containingdindorlatestare 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 key:
controls:
pipelineMustNotUseDockerInDocker:
enabled: trueSee the CLI documentation for the full configuration reference.