Skip to content

Commit b8fd224

Browse files
authored
Merge pull request #315 from devtron-labs/k8s-shield
fix: add policies
2 parents 8a4ee26 + 56caff4 commit b8fd224

12 files changed

+256
-166
lines changed

charts/k8s-shield/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
apiVersion: v2
2-
appVersion: 1.0.0
2+
appVersion: 1.1.0
33
description: A Helm chart for Kubernetes admission policies
44
keywords:
55
- Devtron

charts/k8s-shield/Readme.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ The following sections describe the policies that are defined in the values.yaml
1919
9. Readiness and Liveness Policy
2020
10. Pod Security Policy
2121
11. Container Security Policy
22-
12. Extra Validating Policy
22+
12. Deny Namespace Creation
23+
13. Deny CRDs Deletion
24+
14. Extra Validating Policy
2325

2426
## Exclude Label
2527

@@ -67,6 +69,13 @@ The ```limitResourcePolicy``` enforces a maximum CPU and memory limit for the sp
6769

6870
The ```containerSecurityPolicy``` defines additional security policies that apply to containers within pods. It ensures that containers adhere to security best practices, including non-root execution and restrictions on filesystem access and privilege escalation.
6971

72+
## Deny Namespace Creation
73+
74+
The ```Deny Namespace Creation```policy completely denies the creation of new namespaces. This is useful in highly controlled environments where namespace provisioning is managed externally.
75+
76+
## Deny CRDs Deletion
77+
The ```Deny CRDs Deletion``` policy blocks deletion of CustomResourceDefinitions (CRDs), which can be critical to the operation of custom applications and controllers.
78+
7079
## Extra Validating Policy
7180

7281
The ```extraValidatingPolicy``` section allows you to define additional custom validation policies beyond the default set. These policies can be used to enforce specific rules for your Kubernetes resources.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{{- if and $.Values.defaultPolicies.create (or $.Values.defaultPolicies.policies.namespaceCreationPolicy $.Values.defaultPolicies.policies.namespaceDeletionPolicy) }}
2+
apiVersion: admissionregistration.k8s.io/v1
3+
kind: ValidatingAdmissionPolicy
4+
metadata:
5+
name: {{ include "k8s-shield.fullname" . }}-namespace-policy
6+
spec:
7+
failurePolicy: Fail
8+
matchConstraints:
9+
matchPolicy: Equivalent
10+
namespaceSelector: {}
11+
objectSelector: {}
12+
resourceRules:
13+
{{- if $.Values.defaultPolicies.policies.namespaceCreationPolicy }}
14+
- apiGroups:
15+
- ""
16+
apiVersions:
17+
- v1
18+
operations:
19+
- CREATE
20+
resources:
21+
- namespaces
22+
scope: "*"
23+
{{- end }}
24+
{{- if $.Values.defaultPolicies.policies.namespaceDeletionPolicy }}
25+
- apiGroups:
26+
- ""
27+
apiVersions:
28+
- v1
29+
operations:
30+
- DELETE
31+
resources:
32+
- namespaces
33+
{{- if $.Values.policyDefinitions.namespacePolicy.namespaces }}
34+
resourceNames:
35+
{{- range $.Values.policyDefinitions.namespacePolicy.namespaces }}
36+
- {{ . | quote }}
37+
{{- end }}
38+
{{- end }}
39+
scope: "*"
40+
{{- end }}
41+
validations:
42+
- expression: "false"
43+
message: "Namespace creation or deletion is not allowed."
44+
---
45+
apiVersion: admissionregistration.k8s.io/v1
46+
kind: ValidatingAdmissionPolicyBinding
47+
metadata:
48+
name: {{ include "k8s-shield.fullname" . }}-namespace-policy
49+
spec:
50+
matchResources:
51+
matchPolicy: Equivalent
52+
namespaceSelector: {}
53+
objectSelector: {}
54+
policyName: {{ include "k8s-shield.fullname" . }}-namespace-policy
55+
validationActions:
56+
{{- range .Values.policyDefinitions.namespacePolicy.validationActions }}
57+
- {{ . }}
58+
{{- end }}
59+
{{- end }}

charts/k8s-shield/templates/restrict-admin-cluster-role-creation-policy.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ spec:
3636
rule.resources.exists(r, r == '*') &&
3737
rule.verbs.exists(v, v == '*')) &&
3838
!(rule.nonResourceURLs.exists(u, u == '*') &&
39-
rule.verbs.exists(v, v == '*'))"
39+
rule.verbs.exists(v, v == '*'))
40+
)"
41+
4042
message: "Creation of ClusterRole with admin access is denied"
4143
{{- end }}
4244

charts/k8s-shield/templates/restrict-application-deletion-policy.yaml

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,29 @@ metadata:
55
name: {{ include "k8s-shield.fullname" . }}-prevent-app-deletion
66
spec:
77
failurePolicy: Fail
8-
{{- if and .Values.policyDefinitions.appDeletionPolicy.namespaces }}
98
matchConstraints:
109
matchPolicy: Equivalent
10+
{{- if .Values.policyDefinitions.appDeletionPolicy.namespaces }}
1111
namespaceSelector:
1212
matchExpressions:
1313
- key: kubernetes.io/metadata.name
1414
operator: In
1515
values:
16-
{{- range .Values.policyDefinitions.appDeletionPolicy.namespaces }}
17-
- {{ . | quote }}
18-
{{- end }}
19-
{{- else }}
20-
matchConstraints: {}
21-
{{- end }}
16+
{{- range .Values.policyDefinitions.appDeletionPolicy.namespaces }}
17+
- {{ . | quote }}
18+
{{- end }}
19+
{{- end }}
20+
resourceRules:
21+
- apiGroups:
22+
- argoproj.io
23+
apiVersions:
24+
- v1alpha1
25+
operations:
26+
- DELETE
27+
resources:
28+
- applications
29+
scope: Namespaced
2230
objectSelector: {}
23-
resourceRules:
24-
- apiGroups:
25-
- argoproj.io
26-
apiVersions:
27-
- v1alpha1
28-
operations:
29-
- DELETE
30-
resources:
31-
- applications
32-
scope: Namespaced
3331
validations:
3432
- expression: "false"
3533
message: Deletion of application is not allowed.
@@ -39,13 +37,13 @@ kind: ValidatingAdmissionPolicyBinding
3937
metadata:
4038
name: {{ include "k8s-shield.fullname" . }}-prevent-app-deletion
4139
spec:
40+
policyName: {{ include "k8s-shield.fullname" . }}-prevent-app-deletion
4241
matchResources:
4342
matchPolicy: Equivalent
4443
namespaceSelector: {}
4544
objectSelector: {}
46-
policyName: {{ include "k8s-shield.fullname" . }}-prevent-app-deletion
4745
validationActions:
48-
{{- range .Values.policyDefinitions.appDeletionPolicy.validationActions }}
49-
- {{ . }}
50-
{{- end }}
46+
{{- range .Values.policyDefinitions.appDeletionPolicy.validationActions }}
47+
- {{ . }}
48+
{{- end }}
5149
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
{{- if and $.Values.defaultPolicies.create $.Values.defaultPolicies.policies.namespaceDeletionPolicy }}
1+
{{- if and $.Values.defaultPolicies.create $.Values.defaultPolicies.policies.denyCRDDeletion }}
22
apiVersion: admissionregistration.k8s.io/v1
33
kind: ValidatingAdmissionPolicy
44
metadata:
5-
name: {{ include "k8s-shield.fullname" . }}-restrict-namespace-deletion
5+
name: {{ include "k8s-shield.fullname" . }}-deny-crd-deletion
66
spec:
77
failurePolicy: Fail
88
matchConstraints:
@@ -11,34 +11,31 @@ spec:
1111
objectSelector: {}
1212
resourceRules:
1313
- apiGroups:
14-
- ""
14+
- apiextensions.k8s.io
1515
apiVersions:
1616
- v1
1717
operations:
1818
- DELETE
19-
resourceNames:
20-
{{- range $.Values.policyDefinitions.namespaceDeletionPolicy.namespaces }}
21-
- {{ . }}
22-
{{- end }}
2319
resources:
24-
- namespaces
20+
- customresourcedefinitions
2521
scope: "*"
2622
validations:
2723
- expression: "false"
28-
message: Deletion of namespace is not allowed.
24+
message: "Deletion of CRDs is not allowed for any user."
25+
reason: Invalid
2926
---
3027
apiVersion: admissionregistration.k8s.io/v1
3128
kind: ValidatingAdmissionPolicyBinding
3229
metadata:
33-
name: {{ include "k8s-shield.fullname" . }}-restrict-namespace-deletion
30+
name: {{ include "k8s-shield.fullname" . }}-deny-crd-deletion
3431
spec:
32+
policyName: {{ include "k8s-shield.fullname" . }}-deny-crd-deletion
3533
matchResources:
3634
matchPolicy: Equivalent
3735
namespaceSelector: {}
3836
objectSelector: {}
39-
policyName: {{ include "k8s-shield.fullname" . }}-restrict-namespace-deletion
4037
validationActions:
41-
{{- range .Values.policyDefinitions.namespaceDeletionPolicy.validationActions }}
42-
- {{ . }}
43-
{{- end }}
44-
{{- end }}
38+
{{- range $.Values.policyDefinitions.denyCRDDeletion.validationActions }}
39+
- {{ . }}
40+
{{- end }}
41+
{{- end }}

charts/k8s-shield/templates/restrict-limit-resource-policy.yaml

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,37 @@ metadata:
77
name: {{ include "k8s-shield.fullname" . }}-restrict-resource-limits
88
spec:
99
failurePolicy: Fail
10-
{{- if and .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.namespaces }}
1110
matchConstraints:
1211
matchPolicy: Equivalent
12+
{{- if .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.namespaces }}
1313
namespaceSelector:
1414
matchExpressions:
1515
- key: kubernetes.io/metadata.name
1616
operator: In
1717
values:
18-
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.namespaces }}
18+
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.namespaces }}
19+
- {{ . | quote }}
20+
{{- end }}
21+
{{- end }}
22+
resourceRules:
23+
- apiGroups:
24+
{{- range $.Values.policyDefinitions.resourcePolicies.limitResourcePolicy.apiGroups }}
1925
- {{ . | quote }}
2026
{{- end }}
21-
{{- else }}
22-
matchConstraints: {}
23-
{{- end }}
27+
apiVersions:
28+
- v1
29+
operations:
30+
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.operations }}
31+
- {{ . | quote }}
32+
{{- end }}
33+
resources:
34+
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.resources }}
35+
- {{ . | quote }}
36+
{{- end }}
37+
scope: Namespaced
2438
objectSelector: {}
25-
resourceRules:
26-
- apiGroups:
27-
{{- range $.Values.policyDefinitions.resourcePolicies.limitResourcePolicy.apiGroups }}
28-
- {{ . | quote }}
29-
{{- end }}
30-
apiVersions:
31-
- v1
32-
operations:
33-
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.operations }}
34-
- {{ . | quote }}
35-
{{- end }}
36-
resources:
37-
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.resources }}
38-
- {{ . | quote }}
39-
{{- end }}
40-
scope: Namespaced
4139
validations:
42-
{{- if and .Values.excludeLabel.key .Values.excludeLabel.value }}
40+
{{- if and .Values.excludeLabel.key .Values.excludeLabel.value }}
4341
- expression: |-
4442
(has(object.metadata.labels) && object.metadata.labels['{{ .Values.excludeLabel.key }}'] == '{{ .Values.excludeLabel.value }}')
4543
|| (
@@ -62,7 +60,7 @@ spec:
6260
)
6361
)
6462
message: "Resource limits exceed the maximum allowed: CPU <= {{ $maxCPU }} and memory <= {{ $maxMemory }}, set label {{ .Values.excludeLabel.key }}: {{ .Values.excludeLabel.value }} to allow"
65-
{{- else }}
63+
{{- else }}
6664
- expression: |-
6765
has(object.spec.template) ?
6866
(
@@ -82,7 +80,7 @@ spec:
8280
)
8381
)
8482
message: "Resource limits exceed the maximum allowed: CPU <= {{ $maxCPU }} and memory <= {{ $maxMemory }}."
85-
{{- end }}
83+
{{- end }}
8684
---
8785
apiVersion: admissionregistration.k8s.io/v1
8886
kind: ValidatingAdmissionPolicyBinding
@@ -91,7 +89,7 @@ metadata:
9189
spec:
9290
policyName: {{ include "k8s-shield.fullname" . }}-restrict-resource-limits
9391
validationActions:
94-
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.validationActions }}
95-
- {{ . }}
96-
{{- end }}
92+
{{- range .Values.policyDefinitions.resourcePolicies.limitResourcePolicy.validationActions }}
93+
- {{ . }}
94+
{{- end }}
9795
{{- end }}

charts/k8s-shield/templates/restrict-loadbalance-creation-policy.yaml

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ metadata:
55
name: {{ include "k8s-shield.fullname" . }}-restrict-loadbalancer-creation
66
spec:
77
failurePolicy: Fail
8-
{{- if and .Values.policyDefinitions.loadBalancerCreationPolicy.namespaces }}
98
matchConstraints:
109
matchPolicy: Equivalent
10+
{{- if .Values.policyDefinitions.loadBalancerCreationPolicy.namespaces }}
1111
namespaceSelector:
1212
matchExpressions:
1313
- key: kubernetes.io/metadata.name
@@ -16,20 +16,18 @@ spec:
1616
{{- range .Values.policyDefinitions.loadBalancerCreationPolicy.namespaces }}
1717
- {{ . | quote }}
1818
{{- end }}
19-
{{- else }}
20-
matchConstraints: {}
21-
{{- end }}
19+
{{- end }}
20+
resourceRules:
21+
- apiGroups:
22+
- ""
23+
apiVersions:
24+
- v1
25+
operations:
26+
- CREATE
27+
resources:
28+
- services
29+
scope: Namespaced
2230
objectSelector: {}
23-
resourceRules:
24-
- apiGroups:
25-
- ""
26-
apiVersions:
27-
- v1
28-
operations:
29-
- CREATE
30-
resources:
31-
- services
32-
scope: Namespaced
3331
validations:
3432
{{- if and .Values.excludeLabel.key .Values.excludeLabel.value }}
3533
- expression: "object.spec.type == 'LoadBalancer' && has(object.metadata.labels) && object.metadata.labels['{{ .Values.excludeLabel.key }}'] == '{{ .Values.excludeLabel.value }}'"
@@ -53,4 +51,4 @@ spec:
5351
{{- range .Values.policyDefinitions.loadBalancerCreationPolicy.validationActions }}
5452
- {{ . }}
5553
{{- end }}
56-
{{- end }}
54+
{{- end }}

0 commit comments

Comments
 (0)