no-weakened-confinement
cap_add SYS_ADMIN, SYS_MODULE, SYS_RAWIO or DAC_READ_SEARCH, and security_opt seccomp:unconfined, apparmor:unconfined, label:disable or systempaths=unconfined, weaken Compose container isolation. What each setting removes.
On this page
Docker starts a container with a short list of Linux capabilities, a seccomp filter that blocks dangerous syscalls, an AppArmor or SELinux profile, and masked paths under /proc and /sys. Each of those is a layer between a compromised process and the host kernel. cap_add and security_opt are how a Compose file removes them, and they are often added to get past one error and never taken out. This rule reports:
cap_addentries forSYS_ADMIN,SYS_MODULE,SYS_RAWIOandDAC_READ_SEARCH, in any case and with or without theCAP_prefix.security_optentriesseccomp:unconfined,apparmor:unconfined,label:disableandsystempaths=unconfined, written with either:or=.
SYS_ADMIN covers mounts and a large part of the kernel's interface. SYS_MODULE loads code into the host kernel. SYS_RAWIO reaches raw I/O ports and memory. DAC_READ_SEARCH bypasses file read checks, and with it a container can open host files by handle. cap_add: [ALL] is reported by no-privileged-service as an error.
NET_ADMIN, NET_RAW and SYS_PTRACE are not reported, because VPN clients and monitoring tools need them.
What the rule catches
services:
agent:
image: my-agent:1.2.0
cap_add:
- SYS_ADMIN
security_opt:
- seccomp:unconfinedScanning this file reports:
⚠ WARN [docker-doctor/no-weakened-confinement]
Service 'agent' sets cap_add 'SYS_ADMIN', which lets it mount filesystems and reach most of the kernel.Why it matters
A container shares the host's kernel, so the capabilities, syscall filter and security profile are the only things that limit what a compromised process can ask of it. Removing them widens the kernel surface it can attack and turns an ordinary bug into a host compromise. The runc escapes CVE-2025-31133 and CVE-2025-52565 show how much rides on these defaults. Their advisories say not to run untrusted images, and for containers without user namespaces to avoid root privileges and turn on no new privileges. A service that adds SYS_ADMIN or sets seccomp:unconfined works against that advice.
How to fix it
Remove the capability or the security_opt entry. If the service needs one specific thing, grant that instead, such as a single device in devices.
services:
agent:
image: my-agent:1.2.0
cap_add:
- NET_ADMIN
security_opt:
- no-new-privileges:trueStart from no extra access and add only what the error asks for:
- A device: list it in
devicesinstead of adding a capability. - A mount: use a volume, or a
tmpfs, instead ofSYS_ADMIN. - A blocked syscall: write a seccomp profile that allows that syscall and point
security_optat it withseccomp:./profile.json. The rule does not report a custom profile. - Privilege gain: add
no-new-privileges:truetosecurity_opt.
Some low-level tools, such as profilers and sandboxes that run their own containers, ask for these settings. Set this rule to off in docker-doctor.config.json for a project that exists to run such a tool.
Rule details
- Rule key —
docker-doctor/no-weakened-confinement - Category — Compose
- Default severity —
warning - Applies to — Docker Compose files
Explain this rule from the CLI:
npx @docker-doctor/cli@latest rules explain docker-doctor/no-weakened-confinementChange its severity — or turn it off — in your config file:
// docker-doctor.config.ts
export default {
rules: {
"docker-doctor/no-weakened-confinement": "off",
},
};Severity affects the health score: error findings cost more points than warning, and info costs the least.