|
| 1 | +--- |
| 2 | +reviewers: |
| 3 | +- tallclair |
| 4 | +title: Pod Security Standards |
| 5 | +content_template: templates/concept |
| 6 | +weight: 10 |
| 7 | +--- |
| 8 | + |
| 9 | +{{% capture overview %}} |
| 10 | + |
| 11 | +Security settings for Pods are typically applied by using [security |
| 12 | +contexts](/docs/tasks/configure-pod-container/security-context/). Security Contexts allow for the |
| 13 | +definition of privilege and access controls on a per-Pod basis. |
| 14 | + |
| 15 | +The enforcement and policy-based definition of cluster requirements of security contexts has |
| 16 | +previously been achieved using [Pod Security Policy](/docs/concepts/policy/pod-security-policy/). A |
| 17 | +_Pod Security Policy_ is a cluster-level resource that controls security sensitive aspects of the |
| 18 | +Pod specification. |
| 19 | + |
| 20 | +However, numerous means of policy enforcement have arisen that augment or replace the use of |
| 21 | +PodSecurityPolicy. The intent of this page is to detail recommended Pod security profiles, decoupled |
| 22 | +from any specific instantiation. |
| 23 | + |
| 24 | +{{% /capture %}} |
| 25 | + |
| 26 | +{{% capture body %}} |
| 27 | + |
| 28 | +## Policy Types |
| 29 | + |
| 30 | +There is an immediate need for base policy definitions to broadly cover the security spectrum. These |
| 31 | +should range from highly restricted to highly flexible: |
| 32 | + |
| 33 | +- **_Privileged_** - Unrestricted policy, providing the widest possible level of permissions. This |
| 34 | + policy allows for known privilege escalations. |
| 35 | +- **_Baseline/Default_** - Minimally restrictive policy while preventing known privilege |
| 36 | + escalations. Allows the default (minimally specified) Pod configuration. |
| 37 | +- **_Restricted_** - Heavily restricted policy, following current Pod hardening best practices. |
| 38 | + |
| 39 | +## Policies |
| 40 | + |
| 41 | +### Privileged |
| 42 | + |
| 43 | +The Privileged policy is purposely-open, and entirely unrestricted. This type of policy is typically |
| 44 | +aimed at system- and infrastructure-level workloads managed by privileged, trusted users. |
| 45 | + |
| 46 | +The privileged policy is defined by an absence of restrictions. For blacklist-oriented enforcement |
| 47 | +mechanisms (such as gatekeeper), the privileged profile may be an absence of applied constraints |
| 48 | +rather than an instantiated policy. In contrast, for a whitelist oriented mechanism (such as Pod |
| 49 | +Security Policy) the privileged policy should enable all controls (disable all restrictions). |
| 50 | + |
| 51 | +### Baseline/Default |
| 52 | + |
| 53 | +The Baseline/Default policy is aimed at ease of adoption for common containerized workloads while |
| 54 | +preventing known privilege escalations. This policy is targeted at application operators and |
| 55 | +developers of non-critical applications. The following listed controls should be |
| 56 | +enforced/disallowed: |
| 57 | + |
| 58 | +<table> |
| 59 | + <caption style="display:none">Baseline policy specification</caption> |
| 60 | + <tbody> |
| 61 | + <tr> |
| 62 | + <td><strong>Control</strong></td> |
| 63 | + <td><strong>Policy</strong></td> |
| 64 | + </tr> |
| 65 | + <tr> |
| 66 | + <td>Host Namespaces</td> |
| 67 | + <td> |
| 68 | + Sharing the host namespaces must be disallowed.<br> |
| 69 | + <br><b>Restricted Fields:</b><br> |
| 70 | + spec.hostNetwork<br> |
| 71 | + spec.hostPID<br> |
| 72 | + spec.hostIPC<br> |
| 73 | + <br><b>Allowed Values:</b> false<br> |
| 74 | + </td> |
| 75 | + </tr> |
| 76 | + <tr> |
| 77 | + <td>Privileged Containers</td> |
| 78 | + <td> |
| 79 | + Privileged Pods disable most security mechanisms and must be disallowed.<br> |
| 80 | + <br><b>Restricted Fields:</b><br> |
| 81 | + spec.containers[*].securityContext.privileged<br> |
| 82 | + spec.initContainers[*].securityContext.privileged<br> |
| 83 | + <br><b>Allowed Values:</b> false, undefined/nil<br> |
| 84 | + </td> |
| 85 | + </tr> |
| 86 | + <tr> |
| 87 | + <td>Capabilities</td> |
| 88 | + <td> |
| 89 | + Adding additional capabilities beyond the <a href="https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities">default set</a> must be disallowed.<br> |
| 90 | + <br><b>Restricted Fields:</b><br> |
| 91 | + spec.containers[*].securityContext.capabilities.add<br> |
| 92 | + spec.initContainers[*].securityContext.capabilities.add<br> |
| 93 | + <br><b>Allowed Values:</b> empty (optionally whitelisted defaults)<br> |
| 94 | + </td> |
| 95 | + </tr> |
| 96 | + <tr> |
| 97 | + <td>HostPath Volumes</td> |
| 98 | + <td> |
| 99 | + HostPath volumes must be forbidden.<br> |
| 100 | + <br><b>Restricted Fields:</b><br> |
| 101 | + spec.volumes[*].hostPath<br> |
| 102 | + <br><b>Allowed Values:</b> undefined/nil<br> |
| 103 | + </td> |
| 104 | + </tr> |
| 105 | + <tr> |
| 106 | + <td>Host Ports</td> |
| 107 | + <td> |
| 108 | + HostPorts should be disallowed, or at minimum restricted to a whitelist.<br> |
| 109 | + <br><b>Restricted Fields:</b><br> |
| 110 | + spec.containers[*].ports[*].hostPort<br> |
| 111 | + spec.initContainers[*].ports[*].hostPort<br> |
| 112 | + <br><b>Allowed Values:</b> 0, undefined, (whitelisted)<br> |
| 113 | + </td> |
| 114 | + </tr> |
| 115 | + <tr> |
| 116 | + <td>AppArmor <em>(optional)</em></td> |
| 117 | + <td> |
| 118 | + On supported hosts, the `runtime/default` AppArmor profile is applied by default. The default policy should prevent overriding or disabling the policy, or restrict overrides to a whitelisted set of profiles.<br> |
| 119 | + <br><b>Restricted Fields:</b><br> |
| 120 | + metadata.annotations['container.apparmor.security.beta.kubernetes.io/*']<br> |
| 121 | + <br><b>Allowed Values:</b> runtime/default, undefined<br> |
| 122 | + </td> |
| 123 | + </tr> |
| 124 | + <tr> |
| 125 | + <td>SELinux <em>(optional)</em></td> |
| 126 | + <td> |
| 127 | + Setting custom SELinux options should be disallowed.<br> |
| 128 | + <br><b>Restricted Fields:</b><br> |
| 129 | + spec.securityContext.seLinuxOptions<br> |
| 130 | + spec.containers[*].securityContext.seLinuxOptions<br> |
| 131 | + spec.initContainers[*].securityContext.seLinuxOptions<br> |
| 132 | + <br><b>Allowed Values:</b> undefined/nil<br> |
| 133 | + </td> |
| 134 | + </tr> |
| 135 | + </tbody> |
| 136 | +</table> |
| 137 | + |
| 138 | +### Restricted |
| 139 | + |
| 140 | +The Restricted policy is aimed at enforcing current Pod hardening best practices, at the expense of |
| 141 | +some compatibility. It is targeted at operators and developers of security-critical applications, as |
| 142 | +well as lower-trust users.The following listed controls should be enforced/disallowed: |
| 143 | + |
| 144 | + |
| 145 | +<table> |
| 146 | + <caption style="display:none">Restricted policy specification</caption> |
| 147 | + <tbody> |
| 148 | + <tr> |
| 149 | + <td><strong>Control</strong></td> |
| 150 | + <td><strong>Policy</strong></td> |
| 151 | + </tr> |
| 152 | + <tr> |
| 153 | + <td colspan="2"><em>Everything from the default profile.</em></td> |
| 154 | + </tr> |
| 155 | + <tr> |
| 156 | + <td>Volume Types</td> |
| 157 | + <td> |
| 158 | + In addition to restricting HostPath volumes, the restricted profile limits usage of non-core volume types to those defined through PersistentVolumes.<br> |
| 159 | + <br><b>Restricted Fields:</b><br> |
| 160 | + spec.volumes[*].hostPath<br> |
| 161 | + spec.volumes[*].gcePersistentDisk<br> |
| 162 | + spec.volumes[*].awsElasticBlockStore<br> |
| 163 | + spec.volumes[*].gitRepo<br> |
| 164 | + spec.volumes[*].nfs<br> |
| 165 | + spec.volumes[*].iscsi<br> |
| 166 | + spec.volumes[*].glusterfs<br> |
| 167 | + spec.volumes[*].rbd<br> |
| 168 | + spec.volumes[*].flexVolume<br> |
| 169 | + spec.volumes[*].cinder<br> |
| 170 | + spec.volumes[*].cephFS<br> |
| 171 | + spec.volumes[*].flocker<br> |
| 172 | + spec.volumes[*].fc<br> |
| 173 | + spec.volumes[*].azureFile<br> |
| 174 | + spec.volumes[*].vsphereVolume<br> |
| 175 | + spec.volumes[*].quobyte<br> |
| 176 | + spec.volumes[*].azureDisk<br> |
| 177 | + spec.volumes[*].portworxVolume<br> |
| 178 | + spec.volumes[*].scaleIO<br> |
| 179 | + spec.volumes[*].storageos<br> |
| 180 | + spec.volumes[*].csi<br> |
| 181 | + <br><b>Allowed Values:</b> undefined/nil<br> |
| 182 | + </td> |
| 183 | + </tr> |
| 184 | + <tr> |
| 185 | + <td>Privilege Escalation</td> |
| 186 | + <td> |
| 187 | + Privilege escalation to root should not be allowed.<br> |
| 188 | + <br><b>Restricted Fields:</b><br> |
| 189 | + spec.containers[*].securityContext.privileged<br> |
| 190 | + spec.initContainers[*].securityContext.privileged<br> |
| 191 | + <br><b>Allowed Values:</b> false, undefined/nil<br> |
| 192 | + </td> |
| 193 | + </tr> |
| 194 | + <tr> |
| 195 | + <td>Running as Non-root</td> |
| 196 | + <td> |
| 197 | + Containers must be required to run as non-root users.<br> |
| 198 | + <br><b>Restricted Fields:</b><br> |
| 199 | + spec.securityContext.runAsNonRoot<br> |
| 200 | + spec.containers[*].securityContext.runAsNonRoot<br> |
| 201 | + spec.initContainers[*].securityContext.runAsNonRoot<br> |
| 202 | + <br><b>Allowed Values:</b> true<br> |
| 203 | + </td> |
| 204 | + </tr> |
| 205 | + <tr> |
| 206 | + <td>Non-root groups <em>(optional)</em></td> |
| 207 | + <td> |
| 208 | + Containers should be forbidden from running with a root primary or supplementary GID.<br> |
| 209 | + <br><b>Restricted Fields:</b><br> |
| 210 | + spec.securityContext.runAsGroup<br> |
| 211 | + spec.securityContext.supplementalGroups[*]<br> |
| 212 | + spec.securityContext.fsGroup<br> |
| 213 | + spec.containers[*].securityContext.runAsGroup<br> |
| 214 | + spec.containers[*].securityContext.supplementalGroups[*]<br> |
| 215 | + spec.containers[*].securityContext.fsGroup<br> |
| 216 | + spec.initContainers[*].securityContext.runAsGroup<br> |
| 217 | + spec.initContainers[*].securityContext.supplementalGroups[*]<br> |
| 218 | + spec.initContainers[*].securityContext.fsGroup<br> |
| 219 | + <br><b>Allowed Values:</b><br> |
| 220 | + non-zero<br> |
| 221 | + undefined / nil (except for `*.runAsGroup`)<br> |
| 222 | + </td> |
| 223 | + </tr> |
| 224 | + <tr> |
| 225 | + <td>Seccomp</td> |
| 226 | + <td> |
| 227 | + The runtime/default seccomp profile must be required, or allow additional whitelisted values.<br> |
| 228 | + <br><b>Restricted Fields:</b><br> |
| 229 | + metadata.annotations['seccomp.security.alpha.kubernetes.io/pod']<br> |
| 230 | + metadata.annotations['container.seccomp.security.alpha.kubernetes.io/*']<br> |
| 231 | + <br><b>Allowed Values:</b><br> |
| 232 | + runtime/default<br> |
| 233 | + undefined (container annotation)<br> |
| 234 | + </td> |
| 235 | + </tr> |
| 236 | + </tbody> |
| 237 | +</table> |
| 238 | + |
| 239 | +## Policy Instantiation |
| 240 | + |
| 241 | +Decoupling policy definition from policy instantiation allows for a common understanding and |
| 242 | +consistent language of policies across clusters, independent of the underlying enforcement |
| 243 | +mechanism. |
| 244 | + |
| 245 | +As mechanisms mature, they will be defined below on a per-policy basis. The methods of enforcement |
| 246 | +of individual policies are not defined here. |
| 247 | + |
| 248 | +[**PodSecurityPolicy**](/docs/concepts/policy/pod-security-policy/) |
| 249 | + |
| 250 | +- [Privileged](https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/policy/privileged-psp.yaml) |
| 251 | +- [Baseline](https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/policy/baseline-psp.yaml) |
| 252 | +- [Restricted](https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/policy/restricted-psp.yaml) |
| 253 | + |
| 254 | +## FAQ |
| 255 | + |
| 256 | +### Why isn't there a profile between privileged and default? |
| 257 | + |
| 258 | +The three profiles defined here have a clear linear progression from most secure (restricted) to least |
| 259 | +secure (privileged), and cover a broad set of workloads. Privileges required above the baseline |
| 260 | +policy are typically very application specific, so we do not offer a standard profile in this |
| 261 | +niche. This is not to say that the privileged profile should always be used in this case, but that |
| 262 | +policies in this space need to be defined on a case-by-case basis. |
| 263 | + |
| 264 | +SIG Auth may reconsider this position in the future, should a clear need for other profiles arise. |
| 265 | + |
| 266 | +### What's the difference between a security policy and a security context? |
| 267 | + |
| 268 | +[Security Contexts](/docs/tasks/configure-pod-container/security-context/) configure Pods and |
| 269 | +Containers at runtime. Security contexts are defined as part of the Pod and container specifications |
| 270 | +in the Pod manifest, and represent parameters to the container runtime. |
| 271 | + |
| 272 | +Security policies are control plane mechanisms to enforce specific settings in the Security Context, |
| 273 | +as well as other parameters outside the Security Contex. As of February 2020, the current native |
| 274 | +solution for enforcing these security policies is [Pod Security |
| 275 | +Policy](/docs/concepts/policy/pod-security-policy/) - a mechanism for centrally enforcing security |
| 276 | +policy on Pods across a cluster. Other alternatives for enforcing security policy are being |
| 277 | +developed in the Kubernetes ecosystem, such as [OPA |
| 278 | +Gatekeeper](https://github.com/open-policy-agent/gatekeeper). |
| 279 | + |
| 280 | +### What profiles should I apply to my Windows Pods? |
| 281 | + |
| 282 | +Windows in Kubernetes has some limitations and differentiators from standard Linux-based |
| 283 | +workloads. Specifically, the Pod SecurityContext fields [have no effect on |
| 284 | +Windows](/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#v1-podsecuritycontext). As |
| 285 | +such, no standardized Pod Security profiles currently exists. |
| 286 | + |
| 287 | +### What about sandboxed Pods? |
| 288 | + |
| 289 | +There is not currently an API standard that controls whether a Pod is considered sandboxed or |
| 290 | +not. Sandbox Pods may be identified by the use of a sandboxed runtime (such as gVisor or Kata |
| 291 | +Containers), but there is no standard definition of what a sandboxed runtime is. |
| 292 | + |
| 293 | +The protections necessary for sandboxed workloads can differ from others. For example, the need to |
| 294 | +restrict privileged permissions is lessened when the workload is isolated from the underlying |
| 295 | +kernel. This allows for workloads requiring heightened permissions to still be isolated. |
| 296 | + |
| 297 | +Additionally, the protection of sandboxed workloads is highly dependent on the method of |
| 298 | +sandboxing. As such, no single ‘recommended’ policy is recommended for all sandboxed workloads. |
| 299 | + |
| 300 | +{{% /capture %}} |
0 commit comments