Skip to content

IESC001: sandbox_privileges

Compose services do not grant additional sandbox privileges or host access.

Category: security · Applies to: eval, helper · Allowlist: [tool.inspect-evals-lint.allowlists.sandbox_privileges]

What it does

Reads parsed YAML from every compose*.y*ml and docker-compose*.y*ml under the package, including nested files and overrides. exclude does not apply: Compose files configure the sandbox from the host even when they sit beside challenge code that is excluded. Reports one error per service, field and value for the settings described below.

GPU reservations under deploy.resources.reservations.devices, ordinary named or anonymous volumes, and namespaces shared by service: reference are accepted. YAML anchors are resolved; commented-out settings are ignored. A value tagged !override or !reset is checked as written.

Each finding points at the line of the setting, or of the list item for list settings such as volumes and cap_add. A setting merged from a YAML anchor points at the anchor, so a suppression comment there covers every service that merges it.

Why is this bad?

These settings can give model-controlled processes access to host data, devices, namespaces, or the container engine, or remove runtime restrictions. Some evaluations need them. Each exception needs review and an allowlist entry; a finding does not establish that a setting is exploitable.

The effects depend on the host platform, daemon configuration, and remaining permissions. In particular, sharing a namespace does not automatically authorize every operation on the resources it exposes.

Privileges and device access

  • privileged: true grants all Linux capabilities, exposes host devices, and relaxes security profiles. This can allow sandbox processes to alter host resources and take control of the host. Docker runtime privileges.
  • Any nonempty cap_add requests additional Linux capabilities. Each capability authorizes particular operations: for example, SYS_ADMIN includes mounting filesystems, while SYS_PTRACE permits process inspection subject to other restrictions. The implications depend on the capabilities requested and the namespaces in which they apply. Linux capabilities.
  • Any nonempty devices exposes selected devices and their drivers to the container. For example, access to a disk device can expose data beyond the container's mounted directories. The effect depends on the device and its allowed operations. Docker device access.
  • Any nonempty device_cgroup_rules adds device permissions by type and major/minor number. Rules can allow reading, writing, and creating device nodes; wildcards can cover whole classes of devices. These permissions can apply when a device node becomes available later. Linux device access rules.

Disabled security restrictions

The following values in security_opt are reported with either : or = as the separator. Each disables a different restriction.

  • seccomp=unconfined removes the container's system-call filter. Code can attempt kernel operations that the default profile would reject, subject to remaining permission checks. Docker seccomp profiles.
  • apparmor=unconfined removes AppArmor profile enforcement where AppArmor is enabled. File access, mounts, and other operations lose the additional restrictions imposed by that profile. Docker AppArmor profiles.
  • label=disable disables SELinux labeling for the container. On an SELinux-enabled host, this removes label-based confinement that helps separate container processes and resources. label=type:spc_t (the super-privileged container type) and label=type:unconfined_t run the container in an SELinux domain without that confinement, with the same effect. Docker security options.
  • systempaths=unconfined removes the runtime's masking and read-only protection of system paths. Kernel information and controls at those paths become accessible subject to remaining permissions. Docker system-path security option.

Shared namespaces

Setting Implication
network_mode: host Shares host networking. Processes can reach services on host loopback and listen on host ports without a port mapping. Docker host networking.
pid: host Makes host processes visible. Signaling or inspecting them then depends on credentials, capabilities, and other controls. Linux PID namespaces.
ipc: host Shares host IPC resources, including System V shared memory, semaphores, and message queues. Processes may read data or interfere with applications when IPC permissions allow it. Linux IPC namespaces.
userns_mode: host Disables per-container user-namespace remapping where the Docker daemon enables it. Container user IDs lose that remapping's separation from host IDs. Docker user-namespace remapping.
uts: host Shares the host's hostname and NIS domain name. A process with the required capability can change these identifiers for other processes in that namespace. Linux UTS namespaces.
cgroup: host Exposes the host view of cgroup paths and hierarchy. This reveals information outside the container's private view; it does not itself remove resource limits or grant write access. Linux cgroup namespaces.
network_mode: container:... Joins another container's networking, including its loopback services and listening ports. Docker container networking mode.
pid: container:... Shares another container's process namespace, allowing process visibility and operations subject to permissions. Docker PID settings.
ipc: container:... Shares another container's IPC resources, allowing data access or interference subject to permissions. Docker IPC settings.

container: references depend on containers outside the declared Compose service relationships. The rule cannot establish their configuration. References using service: remain within those declared relationships and are outside this check.

Host files and engine access

  • Host bind mounts in either short or long volumes syntax expose a host path. Writable mounts can let sandbox code change host files; read-only mounts still expose their contents, potentially including credentials or evaluation answers. Relative paths and Windows host paths are checked too, as is a short-syntax source with a path separator outside its interpolations, such as ${HOME}/.ssh: a volume name cannot contain one. Docker bind mounts.
  • Named volumes whose local driver_opts.o contains bind or rbind also expose the host path in driver_opts.device. Review them as host bind mounts even though the service refers to a volume name. Compose local-driver bind example. The rbind option also includes existing mounts below the source path, potentially exposing additional filesystems. Linux recursive bind mounts.
  • Windows named pipe mounts (type: npipe) expose a host communication endpoint. The implications depend on the service listening on that pipe and the caller's permissions. Compose mount types.
  • Container engine sockets receive an additional callout when the source or target names a Docker, Podman, containerd, CRI-O or BuildKit socket (docker.sock, docker_engine, podman.sock, containerd.sock, crio.sock, cri-dockerd.sock, buildkitd.sock), or the source is a directory holding /var/run/docker.sock, such as /var/run. Access to an engine API can allow creation of containers with host mounts or elevated privileges. Docker daemon access. A read-only socket mount does not restrict which API operations a connected client can request. Review must therefore account for Docker's API authorization policy, which allows all operations by default.
  • secrets and configs whose top-level definition has a file or environment source copy a host file or environment variable into the container, at /run/secrets/<name> for a secret. Review them as you would a read-only bind mount of that file. content and external sources are accepted. Keys name the file, or env:<variable>. Compose secrets, Compose configs.
  • use_api_socket: true provides the engine socket and the user's credentials. In addition to engine access, this can permit registry operations using those credentials. Compose API socket access.
  • volumes_from: [container:...] imports another container's mounts, potentially exposing files or sockets whose sources are not declared in this Compose file. A read-only import still exposes readable data. Compose imported volumes.

Privileged lifecycle commands

The rule also reports privileged: true within each lifecycle hook:

  • pre_start runs an initialization step with extra privileges in a temporary container before the service starts. Compose pre-start hooks.
  • post_start runs a command with extra privileges in the running service container after startup. Compose post-start hooks.
  • pre_stop runs a command with extra privileges before the service container stops. Compose pre-stop hooks.

These hooks need review even when the service itself has no privileged setting. Check what the command does and whether sandbox code can modify any scripts or inputs it will use with those privileges.

Example

services:
  default:
    image: example/sandbox:1.0
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Remove the settings when they are unnecessary. If required, document the reason next to default:privileged and default:volumes:/var/run/docker.sock entries in allowlists.sandbox_privileges.

This is a static check of declared Compose settings. It does not run Docker, read environment files, inspect images, combine overrides, follow include or extends files, or inspect Kubernetes settings. Interpolated privilege, namespace, capability, device, security-option, and mount values that cannot be checked produce warnings because Compose interpolation can change the effective settings at runtime. A pass means no listed settings were found in the files checked.

Service environment and env_file values are not checked, though they can also carry host values into the container. Published ports, external networks, and host-gateway mappings need a network-exposure policy. Missing hardening settings such as read_only or no-new-privileges are outside this rule's checks.

Options

  • allowlists.sandbox_privileges: { package = ["service:field:value"] } entries report warnings while present. Each finding names its key in the hint. The value is the capability, device, rule, namespace mode, security option, host path, secret or config source, or container, so allowing default:cap_add:SYS_PTRACE does not allow ALL, and allowing one host path does not allow another. Settings without a value use service:field, such as default:privileged and default:post_start.privileged. A key applies to that service across the package's Compose files. Removed settings leave stale entries for the runner to report.

See also

Suppress on a line with # inspect-evals-lint: ignore[IESC001] or ignore[sandbox_privileges]; select or ignore it in configuration by either, or by the prefix IESC.