Skip to content

Commit 4adf8ef

Browse files
nikpivkinsimar7
andauthored
feat: combine multiple image registry checks into one (#391)
Signed-off-by: Nikita Pivkin <nikita.pivkin@smartforce.io> Co-authored-by: simar7 <1254783+simar7@users.noreply.github.com>
1 parent db98cb9 commit 4adf8ef

7 files changed

+181
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
Ensure that all containers use images only from trusted registry domains.
3+
4+
### Impact
5+
<!-- Add Impact here -->
6+
7+
<!-- DO NOT CHANGE -->
8+
{{ remediationActions }}
9+
10+
### Links
11+
- https://cloud.google.com/container-registry/docs/overview#registries
12+
13+
- https://docs.aws.amazon.com/general/latest/gr/ecr.html
14+
15+

checks/kubernetes/uses_untrusted_azure_registry.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# severity: MEDIUM
1111
# short_code: use-azure-image-prefix
1212
# recommended_action: "Use images from trusted Azure registries."
13+
# deprecated: true
1314
# input:
1415
# selector:
1516
# - type: kubernetes

checks/kubernetes/uses_untrusted_ecr_registry.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# severity: MEDIUM
1111
# short_code: no-untrusted-ecr-domain
1212
# recommended_action: "Container image should be used from Amazon container Registry"
13+
# deprecated: true
1314
# input:
1415
# selector:
1516
# - type: kubernetes

checks/kubernetes/uses_untrusted_gcr_registry.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# severity: MEDIUM
1111
# short_code: use-gcr-domain
1212
# recommended_action: "Use images from trusted GCR registries."
13+
# deprecated: true
1314
# input:
1415
# selector:
1516
# - type: kubernetes

checks/kubernetes/uses_untrusted_public_registries.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# severity: MEDIUM
1111
# short_code: no-public-registries
1212
# recommended_action: "Use images from private registries."
13+
# deprecated: true
1314
# input:
1415
# selector:
1516
# - type: kubernetes
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# METADATA
2+
# title: Restrict container images to trusted registries
3+
# description: Ensure that all containers use images only from trusted registry domains.
4+
# scope: package
5+
# schemas:
6+
# - input: schema.kubernetes
7+
# related_resources:
8+
# - https://cloud.google.com/container-registry/docs/overview#registries
9+
# - https://docs.aws.amazon.com/general/latest/gr/ecr.html
10+
# custom:
11+
# id: KSV0125
12+
# avd_id: AVD-KSV-0125
13+
# severity: MEDIUM
14+
# short_code: use-trusted-registry
15+
# recommended_action: Use images from trusted registries.
16+
# input:
17+
# selector:
18+
# - type: kubernetes
19+
# subtypes:
20+
# - kind: pod
21+
# - kind: replicaset
22+
# - kind: replicationcontroller
23+
# - kind: deployment
24+
# - kind: deploymentconfig
25+
# - kind: statefulset
26+
# - kind: daemonset
27+
# - kind: cronjob
28+
# - kind: job
29+
package builtin.kubernetes.KSV0125
30+
31+
import rego.v1
32+
33+
import data.lib.kubernetes
34+
35+
import data.ksv0125
36+
37+
azure_registries := {"azurecr.io"}
38+
39+
ecr_registries := {
40+
"ecr.us-east-2.amazonaws.com",
41+
"ecr.us-east-1.amazonaws.com",
42+
"ecr.us-west-1.amazonaws.com",
43+
"ecr.us-west-2.amazonaws.com",
44+
"ecr.af-south-1.amazonaws.com",
45+
"ecr.ap-east-1.amazonaws.com",
46+
"ecr.ap-south-1.amazonaws.com",
47+
"ecr.ap-northeast-2.amazonaws.com",
48+
"ecr.ap-southeast-1.amazonaws.com",
49+
"ecr.ap-southeast-2.amazonaws.com",
50+
"ecr.ap-northeast-1.amazonaws.com",
51+
"ecr.ca-central-1.amazonaws.com",
52+
"ecr.cn-north-1.amazonaws.com.cn",
53+
"ecr.cn-northwest-1.amazonaws.com.cn",
54+
"ecr.eu-central-1.amazonaws.com",
55+
"ecr.eu-west-1.amazonaws.com",
56+
"ecr.eu-west-2.amazonaws.com",
57+
"ecr.eu-south-1.amazonaws.com",
58+
"ecr.eu-west-3.amazonaws.com",
59+
"ecr.eu-north-1.amazonaws.com",
60+
"ecr.me-south-1.amazonaws.com",
61+
"ecr.sa-east-1.amazonaws.com",
62+
"ecr.us-gov-east-1.amazonaws.com",
63+
"ecr.us-gov-west-1.amazonaws.com",
64+
}
65+
66+
# list of trusted GCR registries
67+
gcr_registries := {
68+
"gcr.io",
69+
"us.gcr.io",
70+
"eu.gcr.io",
71+
"asia.gcr.io",
72+
}
73+
74+
default_trusted_registries := (azure_registries | ecr_registries) | gcr_registries
75+
76+
all_trusted_registires := ksv0125.trusted_registries if {
77+
count(ksv0125.trusted_registries) > 0
78+
} else := default_trusted_registries
79+
80+
container_image_from_trusted_registry(container) if {
81+
image_parts := split(container.image, "/")
82+
count(image_parts) > 1
83+
registry = image_parts[0]
84+
some trusted in all_trusted_registires
85+
endswith(registry, trusted)
86+
}
87+
88+
deny contains res if {
89+
some container in kubernetes.containers
90+
not container_image_from_trusted_registry(container)
91+
msg := kubernetes.format(sprintf(
92+
"Container %s in %s %s (namespace: %s) uses an image from an untrusted registry.",
93+
[container.name, lower(kubernetes.kind), kubernetes.name, kubernetes.namespace],
94+
))
95+
res := result.new(msg, container)
96+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package builtin.kubernetes.KSV0125_test
2+
3+
import data.builtin.kubernetes.KSV0125 as check
4+
5+
import rego.v1
6+
7+
test_check_registry[name] if {
8+
some name, tc in {
9+
"trusted registry": {
10+
"image": "gcr.io/test:latest",
11+
"expected": 0,
12+
},
13+
"untrusted registry": {
14+
"image": "foo.io/test:latest",
15+
"expected": 1,
16+
},
17+
}
18+
19+
inp := {
20+
"apiVersion": "batch/v1",
21+
"kind": "Job",
22+
"metadata": {
23+
"name": "test",
24+
"namespace": "test",
25+
},
26+
"spec": {"template": {"spec": {"containers": [{
27+
"name": "test",
28+
"image": tc.image,
29+
}]}}},
30+
}
31+
32+
res := check.deny with input as inp
33+
34+
count(res) == tc.expected
35+
}
36+
37+
test_check_registry_custom_registries[name] if {
38+
some name, tc in {
39+
"trusted registry": {
40+
"image": "foo.io/test:latest",
41+
"expected": 0,
42+
},
43+
"untrusted registry": {
44+
"image": "gcr.io/test:latest",
45+
"expected": 1,
46+
},
47+
}
48+
49+
inp := {
50+
"apiVersion": "batch/v1",
51+
"kind": "Job",
52+
"metadata": {
53+
"name": "test",
54+
"namespace": "test",
55+
},
56+
"spec": {"template": {"spec": {"containers": [{
57+
"name": "test",
58+
"image": tc.image,
59+
}]}}},
60+
}
61+
62+
res := check.deny with input as inp
63+
with data.ksv0125.trusted_registries as ["foo.io"]
64+
65+
count(res) == tc.expected
66+
}

0 commit comments

Comments
 (0)