-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from kcl-lang/add-more-container-validation-mo…
…dels feat: add more container validation models
- Loading branch information
Showing
72 changed files
with
1,101 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[package] | ||
name = "disallow-anonymous" | ||
version = "0.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
"""Disallows associating ClusterRole and Role resources | ||
to the system:anonymous user and system:unauthenticated group. | ||
""" | ||
|
||
schema Params: | ||
allowedRoles?: [str] | ||
|
||
params: Params = option("params") | ||
|
||
# Define the validation function | ||
validate = lambda item { | ||
if item.kind in ["ClusterRoleBinding"]: | ||
if item.roleRef.name not in (params.allowedRoles or []): | ||
if any subject in item.subjects { | ||
subject.name in ["system:unauthenticated", "system:anonymous"] | ||
}: | ||
assert False, "Unauthenticated user reference is not allowed in for ${item.kind}: ${item.metadata.name}" | ||
item | ||
} | ||
# Validate All resource | ||
items = [validate(i) for i in option("items")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: disallow-anonymous | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallows associating ClusterRole and Role resources | ||
to the system:anonymous user and system:unauthenticated group. | ||
spec: | ||
params: | ||
allowedRoles: | ||
- cluster-role-1 | ||
source: ./examples/validation/disallow-anonymous/main.k | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: cluster-role-binding-2 | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: cluster-role-2 | ||
subjects: | ||
- apiGroup: rbac.authorization.k8s.io | ||
kind: Group | ||
name: system:authenticated | ||
- apiGroup: rbac.authorization.k8s.io | ||
kind: Group | ||
name: system:unauthenticated |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: disallow-anonymous | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallows associating ClusterRole and Role resources | ||
to the system:anonymous user and system:unauthenticated group. | ||
spec: | ||
params: | ||
allowedRoles: | ||
- cluster-role-1 | ||
source: ./examples/validation/disallow-anonymous/main.k | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: cluster-role-binding-1 | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: cluster-role-1 | ||
subjects: | ||
- apiGroup: rbac.authorization.k8s.io | ||
kind: Group | ||
name: system:authenticated | ||
- apiGroup: rbac.authorization.k8s.io | ||
kind: Group | ||
name: system:unauthenticated | ||
|
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[package] | ||
name = "disallowed-image-repos" | ||
version = "0.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
"""Disallowed container repositories that begin with a string from the specified list. | ||
""" | ||
|
||
# The list of prefixes a container image is allowed to have. | ||
repos: [str] = option("params").repos or [] | ||
|
||
# Define the validation function | ||
validate = lambda item { | ||
containers = [] | ||
if item.kind == "Pod" and repos: | ||
containers = (item.spec.containers or []) + (item.spec.phemeralContainers or []) + (item.spec.initContainers or []) | ||
elif item.kind == "Deployment": | ||
containers = (item.spec.template.spec.containers or []) + (item.spec.template.spec.phemeralContainers or []) + (item.spec.template.spec.initContainers or []) | ||
images: [str] = [c.image for c in containers] | ||
assert all image in images { | ||
all repo in repos { | ||
not image.startswith(repo) | ||
} | ||
} if images and repos, """Use of image is disallowed for ${item.kind}: ${item.metadata.name}, valid repos ${repos}""" | ||
item | ||
} | ||
# Validate All resource | ||
items = [validate(i) for i in option("items")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: disallowed-image-repos | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallowed container repositories that begin with a string from the specified list. | ||
spec: | ||
params: | ||
repos: | ||
- "k8s.gcr.io/" | ||
source: ./examples/validation/disallowed-image-repos/main.k | ||
--- | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: pod | ||
spec: | ||
containers: | ||
- name: kcl | ||
image: k8s.gcr.io/kcl | ||
args: | ||
- "kcl" | ||
ephemeralContainers: | ||
- name: kcl | ||
image: k8s.gcr.io/kcl |
28 changes: 28 additions & 0 deletions
28
examples/validation/disallowed-image-repos/suite/good.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: disallowed-image-repos | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallowed container repositories that begin with a string from the specified list. | ||
spec: | ||
params: | ||
repos: | ||
- "k8s.gcr.io/" | ||
source: ./examples/validation/disallowed-image-repos/main.k | ||
--- | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: pod | ||
spec: | ||
containers: | ||
- name: kcl | ||
image: kcllang/kcl | ||
args: | ||
- "kcl" | ||
ephemeralContainers: | ||
- name: kcl | ||
image: kcllang/kcl |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[package] | ||
name = "horizontal-pod-auto-scaler" | ||
version = "0.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
"""Disallow the following scenarios when deploying `HorizontalPodAutoscalers` | ||
1. Deployment of HorizontalPodAutoscalers with `.spec.minReplicas` or `.spec.maxReplicas` outside the ranges defined in the constraint | ||
2. Deployment of HorizontalPodAutoscalers where the difference between `.spec.minReplicas` and `.spec.maxReplicas` is less than the configured `minimumReplicaSpread` | ||
3. Deployment of HorizontalPodAutoscalers that do not reference a valid `scaleTargetRef` (e.g. Deployment, ReplicationController, ReplicaSet, StatefulSet). | ||
""" | ||
|
||
schema Params: | ||
minimumReplicaSpread: int = 0 | ||
ranges: [Range] | ||
|
||
check: | ||
minimumReplicaSpread >= 0 | ||
len(ranges) > 0 | ||
|
||
schema Range: | ||
min_replicas: int | ||
max_replicas: int | ||
|
||
check: | ||
0 <= min_replicas < max_replicas | ||
|
||
params: Params = option("params") | ||
|
||
# Define the validation function | ||
validate = lambda item { | ||
containers = [] | ||
if item.kind == "HorizontalPodAutoscaler": | ||
assert item.spec.maxReplicas - item.spec.minReplicas >= params.minimumReplicaSpread, "The {} <{}> minReplicas {} or maxReplicas {} is not allowed. Allowed ranges: {}".format(item.kind, item.metadata.name, item.spec.minReplicas, item.spec.maxReplicas, params.ranges) | ||
assert all r in params.ranges { | ||
item.spec.minReplicas >= r.min_replicas and item.spec.maxReplicas <= r.max_replicas | ||
}, "The {} <{}> minReplicas {} or maxReplicas {} is not allowed. Allowed ranges: {}".format(item.kind, item.metadata.name, item.spec.minReplicas, item.spec.maxReplicas, params.ranges) | ||
item | ||
} | ||
# Validate All resource | ||
items = [validate(i) for i in option("items")] |
40 changes: 40 additions & 0 deletions
40
examples/validation/horizontal-pod-auto-scaler/suite/bad.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: horizontal-pod-auto-scaler | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallow the following scenarios when deploying `HorizontalPodAutoscalers` | ||
1. Deployment of HorizontalPodAutoscalers with `.spec.minReplicas` or `.spec.maxReplicas` outside the ranges defined in the constraint | ||
2. Deployment of HorizontalPodAutoscalers where the difference between `.spec.minReplicas` and `.spec.maxReplicas` is less than the configured `minimumReplicaSpread` | ||
3. Deployment of HorizontalPodAutoscalers that do not reference a valid `scaleTargetRef` (e.g. Deployment, ReplicationController, ReplicaSet, StatefulSet). | ||
spec: | ||
params: | ||
minimumReplicaSpread: 1 | ||
ranges: | ||
- min_replicas: 3 | ||
max_replicas: 6 | ||
source: ./examples/validation/horizontal-pod-auto-scaler/main.k | ||
--- | ||
apiVersion: autoscaling/v2 | ||
kind: HorizontalPodAutoscaler | ||
metadata: | ||
name: nginx-hpa-disallowed-replicas | ||
namespace: default | ||
spec: | ||
minReplicas: 2 | ||
maxReplicas: 7 | ||
metrics: | ||
- resource: | ||
name: cpu | ||
target: | ||
averageUtilization: 900 | ||
type: Utilization | ||
type: Resource | ||
scaleTargetRef: | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
name: nginx-deployment | ||
|
39 changes: 39 additions & 0 deletions
39
examples/validation/horizontal-pod-auto-scaler/suite/good.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: horizontal-pod-auto-scaler | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Disallow the following scenarios when deploying `HorizontalPodAutoscalers` | ||
1. Deployment of HorizontalPodAutoscalers with `.spec.minReplicas` or `.spec.maxReplicas` outside the ranges defined in the constraint | ||
2. Deployment of HorizontalPodAutoscalers where the difference between `.spec.minReplicas` and `.spec.maxReplicas` is less than the configured `minimumReplicaSpread` | ||
3. Deployment of HorizontalPodAutoscalers that do not reference a valid `scaleTargetRef` (e.g. Deployment, ReplicationController, ReplicaSet, StatefulSet). | ||
spec: | ||
params: | ||
minimumReplicaSpread: 1 | ||
ranges: | ||
- min_replicas: 3 | ||
max_replicas: 6 | ||
source: ./examples/validation/horizontal-pod-auto-scaler/main.k | ||
--- | ||
apiVersion: autoscaling/v2 | ||
kind: HorizontalPodAutoscaler | ||
metadata: | ||
name: nginx-hpa-allowed | ||
namespace: default | ||
spec: | ||
minReplicas: 3 | ||
maxReplicas: 6 | ||
metrics: | ||
- resource: | ||
name: cpu | ||
target: | ||
averageUtilization: 900 | ||
type: Utilization | ||
type: Resource | ||
scaleTargetRef: | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
name: nginx-deployment |
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[package] | ||
name = "psp-allow-privilege-escalation" | ||
version = "0.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
"""Controls restricting escalation to root privileges. Corresponds to the | ||
`allowPrivilegeEscalation` field in a PodSecurityPolicy. For more | ||
information, see | ||
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation | ||
""" | ||
import regex | ||
|
||
schema Params: | ||
exemptImages?: [str] | ||
|
||
params: Params = option("params") | ||
|
||
is_exempt = lambda image: str -> bool { | ||
result = False | ||
if params.exemptImages: | ||
result = any exempt_image in params.exemptImages { | ||
(image.startswith(exempt_image.removesuffix("*")) if exempt_image.endswith("*") else exempt_image == image) | ||
} | ||
result | ||
} | ||
|
||
# Define the validation function | ||
validate = lambda item { | ||
cpu = "" | ||
memory = "" | ||
containers = [] | ||
if item.kind == "Pod": | ||
containers = (item.spec.containers or []) + (item.spec.initContainers or []) + (item.spec.ephemeralContainers or []) | ||
elif item.kind == "Deployment": | ||
containers = (item.spec.template.spec.containers or []) + (item.spec.template.spec.initContainers or []) + (item.spec.template.spec.ephemeralContainers or []) | ||
if containers: | ||
containers = [c for c in containers if not is_exempt(c.image)] | ||
container_list_disallow_privilege_escalation = [c.name for c in containers if c.securityContext?.allowPrivilegeEscalation == True] | ||
assert len(container_list_disallow_privilege_escalation) == 0, "Privilege escalation containers ${container_list_disallow_privilege_escalation} are not allowed for ${item.kind} <${item.metadata.name}>" | ||
# Return the resource | ||
item | ||
} | ||
# Validate All resource | ||
items = [validate(i) for i in option("items")] |
27 changes: 27 additions & 0 deletions
27
examples/validation/psp-allow-privilege-escalation/suite/bad.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: psp-allow-privilege-escalation | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Controls restricting escalation to root privileges. Corresponds to the | ||
`allowPrivilegeEscalation` field in a PodSecurityPolicy. For more | ||
information, see | ||
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation | ||
spec: | ||
source: ./examples/validation/psp-allow-privilege-escalation/main.k | ||
--- | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: nginx-privilege-escalation-disallowed | ||
labels: | ||
app: nginx-privilege-escalation | ||
spec: | ||
ephemeralContainers: | ||
- name: nginx | ||
image: nginx | ||
securityContext: | ||
allowPrivilegeEscalation: true |
27 changes: 27 additions & 0 deletions
27
examples/validation/psp-allow-privilege-escalation/suite/good.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
apiVersion: krm.kcl.dev/v1alpha1 | ||
kind: KCLRun | ||
metadata: | ||
name: psp-allow-privilege-escalation | ||
annotations: | ||
krm.kcl.dev/version: 0.0.1 | ||
krm.kcl.dev/type: validation | ||
documentation: >- | ||
Controls restricting escalation to root privileges. Corresponds to the | ||
`allowPrivilegeEscalation` field in a PodSecurityPolicy. For more | ||
information, see | ||
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation | ||
spec: | ||
source: ./examples/validation/psp-allow-privilege-escalation/main.k | ||
--- | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: nginx-privilege-escalation-allowed | ||
labels: | ||
app: nginx-privilege-escalation | ||
spec: | ||
containers: | ||
- name: nginx | ||
image: nginx | ||
securityContext: | ||
allowPrivilegeEscalation: false |
Oops, something went wrong.