Advanced configuration (original) (raw)

Subscription: Business

For: Administrators

By default, when Enhanced Container Isolation (ECI) is enabled, Docker Desktop does not allow bind-mounting the Docker Engine socket into containers:

This prevents malicious containers from gaining access to the Docker Engine, as such access could allow them to perform supply chain attacks. For example, build and push malicious images into the organization's repositories or similar.

However, some legitimate use cases require containers to have access to the Docker Engine socket. For example, the popularTestcontainersframework sometimes bind-mounts the Docker Engine socket into containers to manage them or perform post-test cleanup. Similarly, some Buildpack frameworks, for examplePaketo, require Docker socket bind-mounts into containers.

Administrators can optionally configure ECI to allow bind mounting the Docker Engine socket into containers, but in a controlled way.

This can be done via the Docker Socket mount permissions section in theadmin-settings.json file. For example:

Tip

You can now also configure these settings in theDocker Admin Console.

As shown above, there are two configurations for bind-mounting the Docker socket into containers: the imageList and the commandList. These are described below.

Image list

The imageList is a list of container images that are allowed to bind-mount the Docker socket. By default the list is empty, no containers are allowed to bind-mount the Docker socket when ECI is enabled. However, an administrator can add images to the list, using either of these formats:

Image Reference Format Description
<image_name>[:] Name of the image, with optional tag. If the tag is omitted, the :latest tag is used. If the tag is the wildcard *, then it means "any tag for that image."
<image_name>@ Name of the image, with a specific repository digest (e.g., as reported by docker buildx imagetools inspect ). This means only the image that matches that name and digest is allowed.

The image name follows the standard convention, so it can point to any registry and repository.

In the previous example, the image list was configured with three images:

This means that containers that use either the docker.io/localstack/localstackor the docker.io/testcontainers/ryuk image (with any tag), or the docker:cliimage, are allowed to bind-mount the Docker socket when ECI is enabled. Thus, the following works:

Tip

Be restrictive with the images you allow, as described inRecommendations.

In general, it's easier to specify the image using the tag wildcard format, for example <image-name>:*, because then imageList doesn't need to be updated whenever a new version of the image is used. Alternatively, you can use an immutable tag, for example :latest, but it does not always work as well as the wildcard because, for example, Testcontainers uses specific versions of the image, not necessarily the latest one.

When ECI is enabled, Docker Desktop periodically downloads the image digests for the allowed images from the appropriate registry and stores them in memory. Then, when a container is started with a Docker socket bind-mount, Docker Desktop checks if the container's image digest matches one of the allowed digests. If so, the container is allowed to start, otherwise it's blocked.

Due to the digest comparison, it's not possible to bypass the Docker socket mount permissions by re-tagging a disallowed image to the name of an allowed one. In other words, if a user does:

then the tag operation succeeds, but the docker run command fails because the image digest of the disallowed image won't match that of the allowed ones in the repository.

Docker Socket Mount Permissions for derived images

Requires: Docker Desktop4.34.0 and later

As described in the prior section, administrators can configure the list of container images that are allowed to mount the Docker socket via the imageList.

This works for most scenarios, but not always, because it requires knowing upfront the name of the image(s) on which the Docker socket mounts should be allowed. Some container tools such asPaketo buildpacks, build ephemeral local images that require Docker socket bind mounts. Since the name of those ephemeral images is not known upfront, the imageList is not sufficient.

To overcome this, starting with Docker Desktop version 4.34, the Docker Socket mount permissions not only apply to the images listed in the imageList; they also apply to any local images derived (i.e., built from) an image in theimageList.

That is, if a local image called "myLocalImage" is built from "myBaseImage" (i.e., has a Dockerfile with a FROM myBaseImage), then if "myBaseImage" is in the imageList, both "myBaseImage" and "myLocalImage" are allowed to mount the Docker socket.

For example, to enable Paketo buildpacks to work with Docker Desktop and ECI, simply add the following image to the imageList:

When the buildpack runs, it will create an ephemeral image derived frompaketobuildpacks/builder:base and mount the Docker socket to it. ECI will allow this because it will notice that the ephemeral image is derived from an allowed image.

The behavior is disabled by default and must be explicitly enabled by setting"allowDerivedImages": true as shown above. In general it is recommended that you disable this setting unless you know it's required.

A few caveats:

Allowing all containers to mount the Docker socket

In Docker Desktop version 4.36 and later, it's possible to configure the image list to allow any container to mount the Docker socket. You do this by adding"*" to the imageList:

This tells Docker Desktop to allow all containers to mount the Docker socket which increases flexibility but reduces security. It also improves container startup time when using Enhanced Container Isolation.

It is recommended that you use this only in scenarios where explicitly listing allowed container images is not flexible enough.

Command list

In addition to the imageList described in the prior sections, ECI can further restrict the commands that a container can issue via a bind mounted Docker socket. This is done via the Docker socket mount permission commandList, and acts as a complementary security mechanism to the imageList (i.e., like a second line of defense).

For example, say the imageList is configured to allow image docker:cli to mount the Docker socket, and a container is started with it:

By default, this allows the container to issue any command via that Docker socket (e.g., build and push images to the organization's repositories), which is generally not desirable.

To improve security, the commandList can be configured to restrict the commands that the processes inside the container can issue on the bind-mounted Docker socket. The commandList can be configured as a "deny" list (default) or an "allow" list, depending on your preference.

Each command in the list is specified by its name, as reported by docker --help (e.g., "ps", "build", "pull", "push", etc.) In addition, the following command wildcards are allowed to block an entire group of commands:

Command wildcard Description
"container*" Refers to all "docker container ..." commands
"image*" Refers to all "docker image ..." commands
"volume*" Refers to all "docker volume ..." commands
"network*" Refers to all "docker network ..." commands
"build*" Refers to all "docker build ..." commands
"system*" Refers to all "docker system ..." commands

For example, the following configuration blocks the build and push commands on the Docker socket:

Thus, if inside the container, you issue either of those commands on the bind-mounted Docker socket, they will be blocked:

Similarly:

Note that if the commandList had been configured as an "allow" list, then the effect would be the opposite: only the listed commands would have been allowed. Whether to configure the list as an allow or deny list depends on the use case.

Recommendations

Caveats and limitations

Unsupported command Description
compose Docker Compose
dev Dev environments
extension Manages Docker Extensions
feedback Send feedback to Docker
init Creates Docker-related starter files
manifest Manages Docker image manifests
plugin Manages plugins
sbom View Software Bill of Materials (SBOM)
scout Docker Scout
trust Manage trust on Docker images

Note

Docker socket mount permissions do not apply when running "true" Docker-in-Docker (i.e., when running the Docker Engine inside a container). In this case there's no bind-mount of the host's Docker socket into the container, and therefore no risk of the container leveraging the configuration and credentials of the host's Docker Engine to perform malicious activity. Enhanced Container Isolation is capable of running Docker-in-Docker securely, without giving the outer container true root permissions in the Docker Desktop VM.