CI/CD provider
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 gitlab section:
gitlab:
controls:
pipelineMustNotUseDockerInDocker:
enabled: trueSee the CLI documentation for the full configuration reference.
Docker-in-Docker service detected
Control: Workflow must not use Docker-in-Dockerยท Config key: pipelineMustNotUseDockerInDocker
๐ What is this?
A workflow job declares a docker:dind service. On self-hosted runners with privileged mode enabled, this opens a container-escape path; on GitHub-hosted runners it requires the --privileged flag to actually function.
โ ๏ธ Impact
A DinD service runs a full Docker daemon inside the job container. On shared self-hosted runners this means a compromised job can list other containers, mount their volumes, and exfiltrate secrets across jobs.
๐ง How to fix
Replace the DinD service with a rootless container builder. docker/build-push-action works without DinD by using BuildKit; Kaniko is another drop-in replacement.
# .github/workflows/image.yml: โ Docker-in-Docker servicejobs: build: runs-on: [self-hosted, privileged] services: dind: image: docker:27-dind options: --privileged steps: - uses: actions/checkout@v4 - run: docker build -t myimg .# .github/workflows/image.yml: โ
BuildKit via docker/build-push-actionjobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/build-push-action@v6 with: context: . push: false tags: myimg:${{ github.sha }}
# .plumber.yamlgithub: controls: pipelineMustNotUseDockerInDocker: enabled: true๐ก Tips
- If DinD is unavoidable (rare on GitHub-hosted runners), use Kaniko or Buildah instead; both run rootless.
- Pair with ISSUE-413 to catch insecure daemon configuration when DinD is actually present.
โ๏ธ Configuration
This control is configured in .plumber.yaml under the github section:
github:
controls:
pipelineMustNotUseDockerInDocker:
enabled: trueSee the CLI documentation for the full configuration reference.