<p>The second example policy from the <a href="https://kubernetes.io/docs/concepts/policy/pod-security-policy/#example-policies" rel="noreferrer">PodSecurityPolicy documentation</a> consists of the following PodSecurityPolicy snippet</p>

<pre><code>...
spec:
  privileged: false
  # Required to prevent escalations to root.
  allowPrivilegeEscalation: false
  # This is redundant with non-root + disallow privilege escalation,
  # but we can provide it for defense in depth.
  requiredDropCapabilities:
    - ALL
...
</code></pre>

<p>Why is dropping all capabilities redundant for non-root + disallow privilege escalation? You can have a container process without privilege escalation that is non-root but has effective capabilities right?</p>

<p>It seems like this is not possible with Docker:</p>

<pre><code>$ docker run --cap-add SYS_ADMIN --user 1000 ubuntu grep Cap /proc/self/status
CapInh: 00000000a82425fb
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 00000000a82425fb
CapAmb: 0000000000000000
</code></pre>

<p>All effective capabilities have been dropped even when trying to explicitly add them. But other container runtimes could implement it, so is this comment just Docker specific?</p>

dippynark
<blockquote>
  <p>Why is dropping all capabilities redundant for non-root + disallow privilege escalation?</p>
</blockquote>

<p>Because you need privilege escalation to be able to use 'new' capabilities, an effectively <code>allowPrivilegeEscalation: false</code> is disabling <em>setuid</em> in the <a href="https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt" rel="noreferrer">execve</a> system call that prevents the use of any new capabilities.<br> 
Also as shown in the docs: <em>"Once the bit is set, it is inherited across fork, clone, and execve and cannot be unset"</em>. More info <a href="https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation" rel="noreferrer">here</a>.  </p>

<p>This in combination with <code>privileged: false</code> renders <code>requiredDropCapabilities: [ALL]</code> redundant.</p>

<p>The equivalent Docker options here are:</p>

<ul>
<li><code>--user=whatever</code> => <code>privileged: false</code></li>
<li><code>--security-opt=no-new-privileges</code> => <code>allowPrivilegeEscalation: false</code></li>
<li><code>--cap-drop=all</code> => <code>requiredDropCapabilities: [ALL]</code></li>
</ul>

<blockquote>
  <p>It seems like this is not possible with Docker</p>
</blockquote>

<p>That's what looks like Docker is doing, the moment you specify a non-privileged user all of the effective capabilities are dropped (<code>CapEff: 0000000000000000</code>), even if you specify <code>--cap-add SYS_ADMIN</code></p>

<p>This combined with the  <code>--security-opt=no-new-privileges</code> as an option renders <code>--cap-drop=all</code> redundant.</p>

<p>Note that it seems like the default capability mask for docker includes <code>SYS_ADMIN</code></p>

<pre><code>$ docker run --rm ubuntu grep Cap /proc/self/status
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
$ capsh --decode=00000000a82425fb
0x00000000a82425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_admin,cap_mknod,cap_audit_write,cap_setfcap
</code></pre>

<p>Which would make sense why the <code>00000000a82425fb</code> is the same without specifying any <code>--cap-add</code> option.</p>

<blockquote>
  <p>But other container runtimes could implement it, so is this comment just Docker specific?</p>
</blockquote>

<p>I suppose, so you could have a case where <code>privileged: false</code> and <code>allowPrivilegeEscalation: false</code> not effectively disabling capabilities and that could be dropped with <code>requiredDropCapabilities:</code> (Although, I don't see why another runtime would want to change the Docker behavior).</p>
