Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixing error in CEL code for privileged container policy #600

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: 1.1.2
name: k8spspprivilegedcontainer
displayName: Privileged Container
createdAt: "2024-09-19T20:41:16Z"
description: Controls the ability of any container to enable privileged mode. Corresponds to the `privileged` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged
digest: c59b8fdc5827901a5d35fb33825275427b6cf27e38d5f2d975ac52fcc022deff
license: Apache-2.0
homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/privileged-containers
keywords:
- gatekeeper
- open-policy-agent
- policies
readme: |-
# Privileged Container
Controls the ability of any container to enable privileged mode. Corresponds to the `privileged` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged
install: |-
### Usage
```shell
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/privileged-containers/1.1.2/template.yaml
```
provider:
name: Gatekeeper Library
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resources:
- template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system"]
parameters:
exemptImages:
- "safeimages.com/*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged-disallowed
labels:
app: nginx-privileged
spec:
ephemeralContainers:
- name: nginx
image: nginx
securityContext:
privileged: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged-allowed
labels:
app: nginx-privileged
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged-allowed-exempt
labels:
app: nginx-privileged
spec:
containers:
- name: nginx
image: safeimages.com/nginx
securityContext:
privileged: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged-disallowed
labels:
app: nginx-privileged
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
initContainers:
- name: nginx-init
image: nginx
securityContext:
privileged: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
kind: AdmissionReview
apiVersion: admission.k8s.io/v1beta1
request:
operation: "UPDATE"
object:
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged-disallowed
labels:
app: nginx-privileged
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
kind: Suite
apiVersion: test.gatekeeper.sh/v1alpha1
metadata:
name: privileged-containers
tests:
- name: privileged-containers-disallowed
template: template.yaml
constraint: samples/psp-privileged-container/constraint.yaml
cases:
- name: example-disallowed
object: samples/psp-privileged-container/example_disallowed.yaml
assertions:
- violations: yes
- name: example-allowed
object: samples/psp-privileged-container/example_allowed.yaml
assertions:
- violations: no
- name: disallowed-ephemeral
object: samples/psp-privileged-container/disallowed_ephemeral.yaml
assertions:
- violations: yes
- name: update
object: samples/psp-privileged-container/update.yaml
assertions:
- violations: no
- name: exempted-image
object: samples/psp-privileged-container/example_allowed_exempt.yaml
assertions:
- violations: no
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
annotations:
metadata.gatekeeper.sh/title: "Privileged Container"
metadata.gatekeeper.sh/version: 1.1.2
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
information, see
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
validation:
openAPIV3Schema:
type: object
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
information, see
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
code:
- engine: K8sNativeValidation
source:
variables:
- name: containers
expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []'
- name: initContainers
expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []'
- name: ephemeralContainers
expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []'
- name: exemptImagePrefixes
expression: |
!has(variables.params.exemptImages) ? [] :
variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", ""))
- name: exemptImageExplicit
expression: |
!has(variables.params.exemptImages) ? [] :
variables.params.exemptImages.filter(image, !image.endsWith("*"))
- name: exemptImages
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
container.image in variables.exemptImageExplicit ||
variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))
).map(container, container.image)
- name: badContainers
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
!(container.image in variables.exemptImages) &&
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext.privileged: true")
- name: isUpdate
expression: has(request.operation) && request.operation == "UPDATE"
validations:
- expression: variables.isUpdate || size(variables.badContainers) == 0
messageExpression: 'variables.badContainers.join(", ")'
- engine: Rego
source:
rego: |
package k8spspprivileged

import data.lib.exclude_update.is_update
import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
# spec.containers.privileged field is immutable.
not is_update(input.review)

c := input_containers[_]
not is_exempt(c)
c.securityContext.privileged
msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
}

input_containers[c] {
c := input.review.object.spec.containers[_]
}

input_containers[c] {
c := input.review.object.spec.initContainers[_]
}

input_containers[c] {
c := input.review.object.spec.ephemeralContainers[_]
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}
- |
package lib.exempt_container

is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}

_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}

_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ spec:
image: nginx
securityContext:
privileged: true
initContainers:
- name: nginx-init
image: nginx
securityContext:
privileged: true
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspprivilegedcontainer
annotations:
metadata.gatekeeper.sh/title: "Privileged Container"
metadata.gatekeeper.sh/version: 1.1.1
metadata.gatekeeper.sh/version: 1.1.2
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
Expand Down Expand Up @@ -64,13 +64,13 @@ spec:
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
!(container.image in variables.exemptImages) &&
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged == true)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext: " + container.securityContext)
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext.privileged: true")
- name: isUpdate
expression: has(request.operation) && request.operation == "UPDATE"
validations:
- expression: variables.isUpdate || size(variables.badContainers) == 0
messageExpression: 'variables.badContainers.join("\n")'
messageExpression: 'variables.badContainers.join(", ")'
- engine: Rego
source:
rego: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspprivilegedcontainer
annotations:
metadata.gatekeeper.sh/title: "Privileged Container"
metadata.gatekeeper.sh/version: 1.1.1
metadata.gatekeeper.sh/version: 1.1.2
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
Expand Down
6 changes: 3 additions & 3 deletions src/pod-security-policy/privileged-containers/src.cel
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ variables:
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
!(container.image in variables.exemptImages) &&
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged == true)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext: " + container.securityContext)
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext.privileged: true")
- name: isUpdate
expression: has(request.operation) && request.operation == "UPDATE"
validations:
- expression: variables.isUpdate || size(variables.badContainers) == 0
messageExpression: 'variables.badContainers.join("\n")'
messageExpression: 'variables.badContainers.join(", ")'
13 changes: 9 additions & 4 deletions website/docs/validation/privileged-containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ metadata:
name: k8spspprivilegedcontainer
annotations:
metadata.gatekeeper.sh/title: "Privileged Container"
metadata.gatekeeper.sh/version: 1.1.1
metadata.gatekeeper.sh/version: 1.1.2
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
Expand Down Expand Up @@ -76,13 +76,13 @@ spec:
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
!(container.image in variables.exemptImages) &&
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged == true)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext: " + container.securityContext)
(has(container.securityContext) && has(container.securityContext.privileged) && container.securityContext.privileged)
).map(container, "Privileged container is not allowed: " + container.name +", securityContext.privileged: true")
- name: isUpdate
expression: has(request.operation) && request.operation == "UPDATE"
validations:
- expression: variables.isUpdate || size(variables.badContainers) == 0
messageExpression: 'variables.badContainers.join("\n")'
messageExpression: 'variables.badContainers.join(", ")'
- engine: Rego
source:
rego: |
Expand Down Expand Up @@ -194,6 +194,11 @@ spec:
image: nginx
securityContext:
privileged: true
initContainers:
- name: nginx-init
image: nginx
securityContext:
privileged: true

```

Expand Down
Loading