October 20, 2022·6 min read·engineeringdockersecuritynamespacesdesktop

Enhanced Container Isolation separates container root from the Desktop VM

Docker Desktop 4.13 combines enforced settings with a Sysbox-based runtime. User namespaces reduce container privileges in the VM, with explicit launch limitations for WSL and Kubernetes.

An administrator can lock a development setting in the desktop interface while leaving another route to the environment that implements it. A sufficiently privileged container inside the Desktop VM can threaten that distinction. Docker Desktop 4.13 introduces Settings Management and Enhanced Container Isolation together because configuring a policy and protecting its execution environment are related problems.

The 4.13.0 release notes date the release to October 19. Docker's October 20 announcement groups the two additions under Hardened Docker Desktop for Business customers. Settings Management lets administrators set and lock configuration. Enhanced Container Isolation strengthens the separation between user containers and the Linux VM that runs them.

I value explicit build definitions and small application images. Those choices make an artifact easier to understand, but they do not determine what privileges its runtime assigns. The new isolation model concerns that separate part of running a container on a developer's machine.

Root inside the container gets a different VM identity

Docker's implementation documentation at launch identifies a customized Sysbox runtime as the mechanism. Sysbox derives from the OCI runc runtime. With isolation enabled, Desktop automatically launches user containers created through docker run and docker create with Sysbox.

The Linux user namespace maps a container's root user to an unprivileged identity in the VM. A process can therefore appear to be root within its container without receiving the same identity in the surrounding Linux environment. Desktop assigns exclusive mappings to individual containers automatically.

The launch guide gives a direct way to inspect the mapping.

docker run --rm alpine cat /proc/self/uid_map

Its example maps container user zero to VM user 100000 over a range of 65536 IDs. The particular mapping varies between containers, so that example is an illustration of the relationship. It is not a fixed user ID every deployment should expect.

The difference matters when considering a process that crosses a container boundary. Its container identity no longer implies root privileges in the Desktop VM. This adds another constraint to the process's authority. It does not make the shared Linux kernel irrelevant, since the container still executes through it.

Sysbox adds controls beyond identity mapping

User namespaces are part of the implementation, but Docker describes other controls as well. Sysbox restricts access to sensitive VM directories and examines sensitive system calls. It also emulates portions of /proc and /sys, and maps filesystem user and group IDs between the namespace and VM.

Those mechanisms complement Docker's existing isolation controls. The documentation names capabilities, seccomp and AppArmor among the mechanisms already in use. Enhanced Container Isolation adds constraints around the container's relationship with the VM. It does not replace every existing container security mechanism with a single new switch.

The launch guide also says containers cannot share the VM's namespaces through options such as --network=host and --pid=host. That is a functional boundary with implications for development tools that expect to inspect the surrounding system. A program designed around host namespace access has a different requirement from an application whose work remains within its own environment.

Privileged containers retain privileges inside their own user namespace. They do not receive the corresponding privileges in the Desktop VM. The distinction is necessary when interpreting the word privileged under the new model. An option that previously exposed more of the surrounding VM now operates within the additional namespace boundary.

The engine itself remains outside that user namespace

Docker explicitly distinguishes this model from Rootless Docker. Rootless Docker runs the engine and its containers without root privileges on a native Linux host. Enhanced Container Isolation places the user containers in namespaces while leaving the Desktop engine outside those namespaces.

This creates a boundary between user containers and the engine that created them. Desktop already runs that engine inside a VM, so the release strengthens separation within the guest as well as relying on the boundary between guest and host. Both boundaries have a specific role in the architecture.

The documentation also distinguishes the new implementation from Engine's userns-remap mode. Both use Linux user namespaces, but Enhanced Container Isolation assigns exclusive mappings per container and combines them with the additional runtime controls. Describing the release as simply enabling userns-remap would omit the mechanism Docker actually shipped.

I prefer this explanation to a broad claim that container root is harmless. The useful fact is where an identity has authority and which operations the runtime restricts. That gives an engineer something concrete to compare with a tool's filesystem and namespace requirements.

Settings Management defines what is enforced

The contemporary settings guide describes admin-settings.json. Each configured setting includes a locked field. When true, the user cannot edit the setting through Desktop or its CLI. When false, it behaves as a default for new installations and respects previously saved choices on existing ones.

That distinction changes the meaning of distributing a configuration file. A default supplies an initial value. A locked setting imposes an administrator's choice. An organization expecting a uniform policy needs to express the latter when that is its actual requirement.

Enabling isolation uses the following configuration from the launch guide.

{
  "configurationFileVersion": 2,
  "enhancedContainerIsolation": {
    "value": true,
    "locked": true
  }
}

The version field identifies the configuration format. Setting the value enables the capability, and the lock prevents the user from changing it through the supported interfaces. The file alone is not the whole setup. Docker also requires enforced sign-in through registry.json because the feature depends on an authenticated Business organization.

Runtime inspection identifies the selected implementation

The launch documentation gives docker inspect as another way to identify the isolation path. Inspecting the container's HostConfig.Runtime reports sysbox-runc under Enhanced Container Isolation, compared with runc without it. That identifies the runtime attached to the container, which is more direct evidence than assuming a distributed settings file has already taken effect.

The implementation guide also says the CLI's --runtime flag is ignored when isolation is enabled. Docker retains runc as its default runtime name while implicitly launching user containers through Sysbox. An engineer reading the engine default alone can therefore miss the enforced selection. The container's recorded runtime and its user mapping describe the resulting execution arrangement more precisely.

Protected file locations and process lifecycle matter

Docker places administrative settings in protected system locations. The guide names /Library/Application Support/com.docker.docker/admin-settings.json on Mac, C:\ProgramData\DockerDesktop\admin-settings.json on Windows and /usr/share/docker-desktop/admin-settings.json on Linux. Settings Management is designed for organizations that do not give developers root access to their machines.

That assumption is part of the enforcement model. Placing a file outside the user's normal settings directory makes sense when the user lacks authority to replace it. A deployment procedure should identify that assumption alongside the JSON it distributes. Otherwise an example configuration can imply stronger enforcement than its host permissions provide.

Applying changed settings also requires a full application relaunch. Existing installations must quit through the Docker menu and launch again. Docker says selecting Restart is insufficient because it restarts only some components. This is an observable operational requirement, not merely wording in an installation procedure.

Desktop does not automatically force developers to relaunch when administrators change the file. The configuration can therefore exist on disk before the running application has applied it. A statement that a setting was distributed and a statement that the current process enforces it describe different stages of deployment.

The launch has specific workload exclusions

The isolation guide states that the feature is incompatible with WSL and does not protect Kubernetes pods. These limitations prevent a general claim that enabling it secures every workload available through Desktop. A Windows installation using WSL and a local Kubernetes workload require separate consideration under this release's documented boundaries.

The same guide prevents console access to the Desktop VM and restricts changes to its configuration files. Those controls fit the purpose of protecting the environment that implements locked settings. They also affect tools whose normal operation assumes direct access to that environment.

My interest in this release is the explicit connection between configuration authority and runtime authority. Administrators gain a way to lock settings, while the user namespace and Sysbox controls constrain containers that might otherwise modify the VM beneath those settings. The documented WSL and Kubernetes exclusions make clear which execution paths the initial implementation covers.