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 |
|