Docker-in-Docker with insecure daemon configuration
Control: Pipeline must not use Docker-in-Docker · Config key: pipelineMustNotUseDockerInDocker
📋 What is this?
A CI/CD job uses Docker-in-Docker with an insecure daemon configuration. Setting DOCKER_TLS_CERTDIR to an empty string or using DOCKER_HOST with tcp://docker:2375 disables TLS encryption between the CI job and the Docker daemon.
⚠️ Impact
Without TLS, all communication between the CI job and the Docker daemon is in plaintext. On shared infrastructure, this allows network-level eavesdropping, man-in-the-middle attacks, and Docker API command injection by other containers on the same network.
🔧 How to fix
If Docker-in-Docker is required, do not set DOCKER_TLS_CERTDIR to an empty string and use tcp://docker:2376 (TLS) instead of tcp://docker:2375 (plaintext). Prefer Kaniko or Buildah to avoid this pattern entirely.
# .gitlab-ci.yml — ❌ DinD with TLS disabledbuild-image: image: docker:27 services: - docker:27-dind variables: DOCKER_TLS_CERTDIR: "" DOCKER_HOST: tcp://docker:2375 script: - docker build -t $CI_REGISTRY_IMAGE . - docker push $CI_REGISTRY_IMAGE# .gitlab-ci.yml — ✅ DinD with TLS enabled (if DinD is truly required)build-image: image: docker:27 services: - docker:27-dind variables: DOCKER_TLS_CERTDIR: "/certs" DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "/certs/client" script: - docker build -t $CI_REGISTRY_IMAGE . - docker push $CI_REGISTRY_IMAGE
# Better: use Kaniko instead of DinD entirely# (see ISSUE-412 for examples)💡 Tips
- Port 2375 is Docker's unencrypted port. Port 2376 is the TLS-encrypted port.
- Setting
DOCKER_TLS_CERTDIR: ""explicitly disables TLS certificate generation in the DinD service. - This issue only fires when a DinD service is also present in the same job. Insecure variables without DinD are not flagged.
- The best fix is to replace Docker-in-Docker entirely with Kaniko or Buildah (see ISSUE-412).
- Only
DOCKER_TLS_CERTDIRandDOCKER_HOSTvariables declared in YAML (variables:) are checked. TLS disabled viadockerdflags inscript:or via runtime exports inbefore_script:is not detected (known limitation). - Only port 2375 is flagged as insecure. Custom non-TLS ports (e.g.,
tcp://docker:12345) 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.