After diving around the moby source code, I finally located TweakCapabilities(): it takes the two sets of capabilities to add and to drop, enforcing the following scheme below; thus works in docker-compose.yaml where YAML doesn't define an order for the cap_add
and cap_drop
keys. The first matching item below will terminate the list.
- container is
privileged: true
: ignore cap_add
and cap_drop
completely, return all available capabilities instead.
- both
cap_add
and cap_drop
are empty: return the default Docker set of capabilities.
cap_add
contains ALL
: return all capabilities minus the capabilities listed in cap_drop
(ignores ALL
in the latter).
cap_drop
contains ALL
: return the capabilities from cap_add
only, ignoring any Docker default capabilities.
- default: first drop all capabilites from the default set listed in
cap_drop
, then add the capabilities in cap_add
, and finally return the result.
If I'm not mistaken this can be also represented in a more accessible manner as follows...
privileged: true |
ALL capabilities: ignores cap_add and cap_drop (boss mode) |
|
no cap_add |
cap_add: ['CAP_A'] |
cap_add: ['ALL'] |
no cap_drop |
default capabilities |
default + CAP_A |
ALL capabilities |
cap_drop: ['CAP_Z'] |
default -CAP_Z |
default -CAP_Z +CAP_A |
ALL -CAP_Z |
cap_drop: ['ALL'] |
NO capabilities |
CAP_A |
ALL capabilities |
In the end, there's only the following two "deterministic" combinations that always include cap_drop: ALL
and that follow the line of least privilege:
|
no cap_add |
cap_add: ['CAP_A'] |
|
|
|
|
|
|
|
|
|
cap_drop: ['ALL'] |
NO capabilities |
CAP_A |
|