Skip to content

Commit 75652e8

Browse files
committed
Standardized pod security profiles
1 parent 10d0cc7 commit 75652e8

File tree

3 files changed

+378
-0
lines changed

3 files changed

+378
-0
lines changed

content/en/docs/concepts/policy/pod-security-policy.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ several security mechanisms.
374374

375375
{{< codenew file="policy/restricted-psp.yaml" >}}
376376

377+
See [Pod Security Standards](/docs/concepts/security/pod-security-standards/#policy-instantiation) for more examples.
378+
377379
## Policy Reference
378380

379381
### Privileged
@@ -633,6 +635,8 @@ Refer to the [Sysctl documentation](
633635

634636
{{% capture whatsnext %}}
635637

638+
See [Pod Security Standards](/docs/concepts/security/pod-security-standards/) for policy recommendations.
639+
636640
Refer to [Pod Security Policy Reference](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) for the api details.
637641

638642
{{% /capture %}}
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
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 %}}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
apiVersion: policy/v1beta1
2+
kind: PodSecurityPolicy
3+
metadata:
4+
name: baseline
5+
annotations:
6+
# Optional: Allow the default AppArmor profile, requires setting the default.
7+
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
8+
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
9+
# Optional: Allow the default seccomp profile, requires setting the default.
10+
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default,unconfined'
11+
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'unconfined'
12+
spec:
13+
privileged: false
14+
# The moby default capability set, defined here:
15+
# https://github.com/moby/moby/blob/0a5cec2833f82a6ad797d70acbf9cbbaf8956017/oci/caps/defaults.go#L6-L19
16+
allowedCapabilities:
17+
- 'CHOWN'
18+
- 'DAC_OVERRIDE'
19+
- 'FSETID'
20+
- 'FOWNER'
21+
- 'MKNOD'
22+
- 'NET_RAW'
23+
- 'SETGID'
24+
- 'SETUID'
25+
- 'SETFCAP'
26+
- 'SETPCAP'
27+
- 'NET_BIND_SERVICE'
28+
- 'SYS_CHROOT'
29+
- 'KILL'
30+
- 'AUDIT_WRITE'
31+
# Allow all volume types except hostpath
32+
volumes:
33+
# 'core' volume types
34+
- 'configMap'
35+
- 'emptyDir'
36+
- 'projected'
37+
- 'secret'
38+
- 'downwardAPI'
39+
# Assume that persistentVolumes set up by the cluster admin are safe to use.
40+
- 'persistentVolumeClaim'
41+
# Allow all other non-hostpath volume types.
42+
- 'awsElasticBlockStore'
43+
- 'azureDisk'
44+
- 'azureFile'
45+
- 'cephFS'
46+
- 'cinder'
47+
- 'csi'
48+
- 'fc'
49+
- 'flexVolume'
50+
- 'flocker'
51+
- 'gcePersistentDisk'
52+
- 'gitRepo'
53+
- 'glusterfs'
54+
- 'iscsi'
55+
- 'nfs'
56+
- 'photonPersistentDisk'
57+
- 'portworxVolume'
58+
- 'quobyte'
59+
- 'rbd'
60+
- 'scaleIO'
61+
- 'storageos'
62+
- 'vsphereVolume'
63+
hostNetwork: false
64+
hostIPC: false
65+
hostPID: false
66+
readOnlyRootFilesystem: false
67+
runAsUser:
68+
rule: 'RunAsAny'
69+
seLinux:
70+
rule: 'RunAsAny'
71+
supplementalGroups:
72+
rule: 'RunAsAny'
73+
fsGroup:
74+
rule: 'RunAsAny'

0 commit comments

Comments
 (0)