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

chore: adding CEL for psp-host-namespaces #603

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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.0
name: k8spsphostnamespace
displayName: Host Namespace
createdAt: "2024-06-04T20:21:50Z"
description: Disallows sharing of host PID and IPC namespaces by pod containers. Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
digest: 5e4f8501fb48a18710d435ac83273b74420023033265ca8f5eb385aec4c345f7
license: Apache-2.0
homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/host-namespaces
keywords:
- gatekeeper
- open-policy-agent
- policies
readme: |-
# Host Namespace
Disallows sharing of host PID and IPC namespaces by pod containers. Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
install: |-
### Usage
```shell
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/host-namespaces/1.1.0/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,9 @@
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPHostNamespace
metadata:
name: psp-host-namespace
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-namespace-allowed
labels:
app: nginx-host-namespace
spec:
hostPID: false
hostIPC: false
containers:
- name: nginx
image: nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-namespace-disallowed
labels:
app: nginx-host-namespace
spec:
hostPID: true
hostIPC: true
containers:
- name: nginx
image: nginx
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-host-namespace-disallowed
labels:
app: nginx-host-namespace
spec:
hostPID: true
hostIPC: true
containers:
- name: nginx
image: nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
kind: Suite
apiVersion: test.gatekeeper.sh/v1alpha1
metadata:
name: host-namespaces
tests:
- name: host-namespace
template: template.yaml
constraint: samples/psp-host-namespace/constraint.yaml
cases:
- name: example-allowed
object: samples/psp-host-namespace/example_allowed.yaml
assertions:
- violations: no
- name: example-disallowed
object: samples/psp-host-namespace/example_disallowed.yaml
assertions:
- violations: yes
- name: update
object: samples/psp-host-namespace/update.yaml
assertions:
- violations: no
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spsphostnamespace
annotations:
metadata.gatekeeper.sh/title: "Host Namespace"
metadata.gatekeeper.sh/version: 1.1.0
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
For more information, see
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
spec:
crd:
spec:
names:
kind: K8sPSPHostNamespace
validation:
# Schema for the `parameters` field
openAPIV3Schema:
type: object
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
For more information, see
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
targets:
- target: admission.k8s.gatekeeper.sh
code:
- engine: K8sNativeValidation
source:
variables:
- name: sharingNamespace
expression: |
has(variables.anyObject.spec.hostPID) || has(variables.anyObject.spec.hostIPC) ? variables.anyObject.spec.hostPID || variables.anyObject.spec.hostIPC : false
validations:
- expression: '(has(request.operation) && request.operation == "UPDATE") || !variables.sharingNamespace'
messageExpression: '"Sharing the host namespace is not allowed: " + variables.anyObject.metadata.namespace'
- engine: Rego
source:
rego: |
package k8spsphostnamespace

import data.lib.exclude_update.is_update

violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update(input.review)

input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}

input_share_hostnamespace(o) {
o.spec.hostPID
}
input_share_hostnamespace(o) {
o.spec.hostIPC
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}
56 changes: 34 additions & 22 deletions library/pod-security-policy/host-namespaces/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spsphostnamespace
annotations:
metadata.gatekeeper.sh/title: "Host Namespace"
metadata.gatekeeper.sh/version: 1.0.1
metadata.gatekeeper.sh/version: 1.1.0
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
Expand All @@ -26,29 +26,41 @@ spec:
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spsphostnamespace
code:
- engine: K8sNativeValidation
source:
variables:
- name: sharingNamespace
expression: |
has(variables.anyObject.spec.hostPID) || has(variables.anyObject.spec.hostIPC) ? variables.anyObject.spec.hostPID || variables.anyObject.spec.hostIPC : false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is vulnerable to failing on nil.

Suggest splitting this in to two variables:

  • get hostIPC if exists, false otherwise
  • same for hostPID
  • test the downstream variables

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the code. PTAL @maxsmythe

validations:
- expression: '(has(request.operation) && request.operation == "UPDATE") || !variables.sharingNamespace'
messageExpression: '"Sharing the host namespace is not allowed: " + variables.anyObject.metadata.namespace'
- engine: Rego
source:
rego: |
package k8spsphostnamespace

import data.lib.exclude_update.is_update
import data.lib.exclude_update.is_update

violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update(input.review)
violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update(input.review)

input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}
input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}

input_share_hostnamespace(o) {
o.spec.hostPID
}
input_share_hostnamespace(o) {
o.spec.hostIPC
}
libs:
- |
package lib.exclude_update
input_share_hostnamespace(o) {
o.spec.hostPID
}
input_share_hostnamespace(o) {
o.spec.hostIPC
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}
is_update(review) {
review.operation == "UPDATE"
}
18 changes: 12 additions & 6 deletions src/pod-security-policy/host-namespaces/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spsphostnamespace
annotations:
metadata.gatekeeper.sh/title: "Host Namespace"
metadata.gatekeeper.sh/version: 1.0.1
metadata.gatekeeper.sh/version: 1.1.0
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
Expand All @@ -26,8 +26,14 @@ spec:
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
{{ file.Read "src/pod-security-policy/host-namespaces/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }}
libs:
- |
{{ file.Read "src/pod-security-policy/host-namespaces/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }}
code:
- engine: K8sNativeValidation
source:
{{ file.Read "src/pod-security-policy/host-namespaces/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }}
- engine: Rego
source:
rego: |
{{ file.Read "src/pod-security-policy/host-namespaces/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }}
libs:
- |
{{ file.Read "src/pod-security-policy/host-namespaces/lib_exclude_update.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }}
7 changes: 7 additions & 0 deletions src/pod-security-policy/host-namespaces/src.cel
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variables:
- name: sharingNamespace
expression: |
has(variables.anyObject.spec.hostPID) || has(variables.anyObject.spec.hostIPC) ? variables.anyObject.spec.hostPID || variables.anyObject.spec.hostIPC : false
validations:
- expression: '(has(request.operation) && request.operation == "UPDATE") || !variables.sharingNamespace'
messageExpression: '"Sharing the host namespace is not allowed: " + variables.anyObject.metadata.namespace'
66 changes: 39 additions & 27 deletions website/docs/validation/host-namespaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ metadata:
name: k8spsphostnamespace
annotations:
metadata.gatekeeper.sh/title: "Host Namespace"
metadata.gatekeeper.sh/version: 1.0.1
metadata.gatekeeper.sh/version: 1.1.0
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
Expand All @@ -38,32 +38,44 @@ spec:
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spsphostnamespace

import data.lib.exclude_update.is_update

violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update(input.review)

input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}

input_share_hostnamespace(o) {
o.spec.hostPID
}
input_share_hostnamespace(o) {
o.spec.hostIPC
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}
code:
- engine: K8sNativeValidation
source:
variables:
- name: sharingNamespace
expression: |
has(variables.anyObject.spec.hostPID) || has(variables.anyObject.spec.hostIPC) ? variables.anyObject.spec.hostPID || variables.anyObject.spec.hostIPC : false
validations:
- expression: '(has(request.operation) && request.operation == "UPDATE") || !variables.sharingNamespace'
messageExpression: '"Sharing the host namespace is not allowed: " + variables.anyObject.metadata.namespace'
- engine: Rego
source:
rego: |
package k8spsphostnamespace

import data.lib.exclude_update.is_update

violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update(input.review)

input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}

input_share_hostnamespace(o) {
o.spec.hostPID
}
input_share_hostnamespace(o) {
o.spec.hostIPC
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}

```

Expand Down
Loading