You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: content/en/docs/Writing policies/exceptions.md
+246-2
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ weight: 80
6
6
---
7
7
8
8
{{% alert title="Warning" color="warning" %}}
9
-
Policy exceptions are a **beta** feature and requires setting certain container flags to enable. It is not ready for production usage and there may be breaking changes. Normal semantic versioning and compatibility rules will not apply.
9
+
Policy exceptions are a **beta** feature. Normal semantic versioning and compatibility rules will not apply.
10
10
{{% /alert %}}
11
11
12
12
Although Kyverno policies contain multiple methods to provide fine-grained control as to which resources they act upon in the form of [`match`/`exclude` blocks](/docs/writing-policies/match-exclude/#match-statements), [preconditions](/docs/writing-policies/preconditions/) at multiple hierarchies, [anchors](/docs/writing-policies/validate/#anchors), and more, all these mechanisms have in common that the resources which they are intended to exclude must occur in the same rule definition. This may be limiting in situations where policies may not be directly editable, or doing so imposes an operational burden.
@@ -15,7 +15,7 @@ For example, in organizations where multiple teams must interact with the same c
15
15
16
16
Imagine a validate policy exists in `Enforce` mode which mandates all Pods must not mount host namespaces. A separate team has a legitimate need to run a specific tool in this cluster for a limited time which violates this policy. Normally, the policy would block such a "bad" Pod if the policy was not previously altered in such a way to allow said Pod to run. Rather than making adjustments to the policy, an exception may be granted. Both of these examples are use cases for a **PolicyException** resource described below.
17
17
18
-
A `PolicyException` is a Namespaced Custom Resource which allows a resource(s) to be allowed past a given policy and rule combination. It can be used to exempt any resource from any Kyverno rule type although it is primarily intended for use with validate rules. A PolicyException encapsulates the familiar `match`/`exclude` statements used in `Policy` and `ClusterPolicy` resources but adds an `exceptions{}` object to select the policy and rule name(s) used to form the exception. The logical flow of how a PolicyException works in tandem with a validate policy is depicted below.
18
+
A `PolicyException` is a Namespaced Custom Resource which allows a resource(s) to be allowed past a given policy and rule combination. It can be used to exempt any resource from any Kyverno rule type although it is primarily intended for use with validate rules. A PolicyException encapsulates the familiar `match`/`exclude` statements used in `Policy` and `ClusterPolicy` resources but adds an `exceptions{}` object to select the policy and rule name(s) used to form the exception. A `conditions{}` block (optional) uses common expressions similar to those found in [preconditions](/docs/writing-policies/preconditions/) and [deny rules](/docs/writing-policies/validate/#deny-rules) to query the contents of the selected resources in order to refine the selection process. The logical flow of how a PolicyException works in tandem with a validate policy is depicted below.
A Deployment matching the characteristics defined in the PolicyException, shown below, will be allowed creation even though it technically violates the rule's definition.
@@ -166,3 +171,242 @@ spec:
166
171
- resources:
167
172
names: "?*"
168
173
```
174
+
175
+
## Pod Security Exemptions
176
+
177
+
Kyverno policies can be used to apply Pod Security Standards profiles and controls via the [validate.podSecurity](/docs/writing-policies/validate/#pod-security) subrule. However, there are cases where certain Pods need to be exempted from these policies. For example, a Pod may need to run as `root` or require privileged access. In such cases, a PolicyException can be used to define an exemption for the Pod through the `podSecurity{}` block. It can be used to define controls that are exempted from the policy.
178
+
179
+
Given the following policy that enforces the latest version of the Pod Security Standards restricted profile in a single rule across the entire cluster.
180
+
181
+
```yaml
182
+
apiVersion: kyverno.io/v1
183
+
kind: ClusterPolicy
184
+
metadata:
185
+
name: psa
186
+
spec:
187
+
background: true
188
+
validationFailureAction: Enforce
189
+
rules:
190
+
- name: restricted
191
+
match:
192
+
any:
193
+
- resources:
194
+
kinds:
195
+
- Pod
196
+
validate:
197
+
podSecurity:
198
+
level: restricted
199
+
version: latest
200
+
```
201
+
202
+
In this use case, all Pods in the `delta` Namespace need to run as a root. A PolicyException can be used to exempt all Pods whose Namespace is `delta` from the policy by excluding the `runAsNonRoot` control.
203
+
204
+
```yaml
205
+
apiVersion: kyverno.io/v2beta1
206
+
kind: PolicyException
207
+
metadata:
208
+
name: pod-security-exception
209
+
namespace: policy-exception-ns
210
+
spec:
211
+
exceptions:
212
+
- policyName: psa
213
+
ruleNames:
214
+
- restricted
215
+
match:
216
+
any:
217
+
- resources:
218
+
namespaces:
219
+
- delta
220
+
podSecurity:
221
+
- controlName: "Running as Non-root"
222
+
```
223
+
224
+
The following Pod satisfies all controls in the restricted profile except the `Running as Non-root` control but it matches the exception. Hence, it will be successfully created.
225
+
226
+
```yaml
227
+
apiVersion: v1
228
+
kind: Pod
229
+
metadata:
230
+
name: nginx-pod
231
+
namespace: delta
232
+
spec:
233
+
containers:
234
+
- name: nginx
235
+
image: nginx
236
+
args:
237
+
- sleep
238
+
- 1d
239
+
securityContext:
240
+
seccompProfile:
241
+
type: RuntimeDefault
242
+
runAsNonRoot: false
243
+
allowPrivilegeEscalation: false
244
+
capabilities:
245
+
drop:
246
+
- ALL
247
+
```
248
+
249
+
PolicyExceptions `podSecurity{}` block has the same functionality as the [validate.podSecurity.exclude](/docs/writing-policies/validate/#exemptions) block in the policy itself. They can be used to exempt controls that can only be defined in the container level fields.
250
+
251
+
For example, the following PolicyException exempts the containers running either the `nginx` or `redis` image from following the Capabilities control.
252
+
253
+
```yaml
254
+
apiVersion: kyverno.io/v2beta1
255
+
kind: PolicyException
256
+
metadata:
257
+
name: pod-security-exception
258
+
namespace: policy-exception-ns
259
+
spec:
260
+
exceptions:
261
+
- policyName: psa
262
+
ruleNames:
263
+
- restricted
264
+
match:
265
+
any:
266
+
- resources:
267
+
namespaces:
268
+
- delta
269
+
podSecurity:
270
+
- controlName: Capabilities
271
+
images:
272
+
- nginx*
273
+
- redis*
274
+
```
275
+
276
+
There might be a case where it is required to have specific values for the controls in the PodSecurity profile. In such cases, the `podSecurity.restrictedField` field can be used to define these values for the controls that are exempted from the policy.
277
+
278
+
For example, service meshes like Istio and Linkerd employ an `initContainer` that requires some privileges which are very often problematic in security-conscious clusters. Minimally, these initContainers must add two [Linux capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) which allow them to make modifications to the networking stack: `NET_ADMIN`and `NET_RAW`. These initContainers may go even further by running as a root user, something which is a big no-no in the world of containers.
279
+
280
+
In this case, the `podSecurity.restrictedField` can be used to enforce the entire baseline profile of the Pod Security Standards but only exclude Istio’s and Linkerd’s images from specifically the initContainers list.
281
+
282
+
The following PolicyException grants an exemption to the `initContainers` that use istio or linkerd images, allowing them to bypass the `Capabilities` control. This is achieved by permitting the values of `NET_ADMIN` and `NET_RAW` in the `securityContext.capabilities.add` field.
The following Pod meets all requirements outlined in the baseline profile, except the `Capabilities` control in the `initContainer`. However, it matches the exception that permits the configuration of `spec.initContainers[*].securityContext.capabilities.add` to include `NET_ADMIN` and `NET_RAW`. Hence, it will be successfully created.
312
+
313
+
```yaml
314
+
apiVersion: v1
315
+
kind: Pod
316
+
metadata:
317
+
name: istio-pod
318
+
spec:
319
+
initContainers:
320
+
- name: istio-init
321
+
image: docker.io/istio/proxyv2:1.20.2
322
+
args:
323
+
- istio-iptables
324
+
- -p
325
+
- "15001"
326
+
- -z
327
+
- "15006"
328
+
- -u
329
+
- "1337"
330
+
- -m
331
+
- REDIRECT
332
+
- -i
333
+
- '*'
334
+
- -x
335
+
- ""
336
+
- -b
337
+
- '*'
338
+
- -d
339
+
- 15090,15021,15020
340
+
- --log_output_level=default:info
341
+
securityContext:
342
+
allowPrivilegeEscalation: false
343
+
capabilities:
344
+
add:
345
+
- NET_ADMIN
346
+
- NET_RAW
347
+
drop:
348
+
- ALL
349
+
privileged: false
350
+
readOnlyRootFilesystem: false
351
+
runAsGroup: 0
352
+
runAsNonRoot: false
353
+
runAsUser: 0
354
+
containers:
355
+
- name: busybox
356
+
image: busybox:1.35
357
+
args:
358
+
- sleep
359
+
- infinity
360
+
```
361
+
362
+
The following Pod meets all requirements outlined in the baseline profile, except the `Capabilities` control in the `initContainer` and it matches the exception but it sets the `spec.initContainers[*].securityContext.capabilities.add` to `SYS_ADMIN` which isn't an allowed value. Hence, it will be rejected.
0 commit comments