Skip to main content
ISSUE-413 High Quick CLI Pipeline Composition

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.

✗ Before TLS is disabled, exposing all Docker API traffic in plaintext.
# .gitlab-ci.yml — ❌ DinD with TLS disabled
build-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
✓ After TLS is enabled with proper certificate configuration.
# .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_CERTDIR and DOCKER_HOST variables declared in YAML (variables:) are checked. TLS disabled via dockerd flags in script: or via runtime exports in before_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: true

See the CLI documentation for the full configuration reference.