From 177405c6aa95926c816f13689421f8f5d642d7df Mon Sep 17 00:00:00 2001 From: kooomix Date: Tue, 14 Jan 2025 09:36:53 +0200 Subject: [PATCH] Refactor namespace checks for workload connections in gateway rules --- .../raw.rego | 54 +++++++++++++++---- .../raw.rego | 4 -- rules/exposure-to-internet/raw.rego | 23 ++++++-- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/rules/exposure-to-internet-via-gateway-api/raw.rego b/rules/exposure-to-internet-via-gateway-api/raw.rego index a8507707..da59f3d1 100644 --- a/rules/exposure-to-internet-via-gateway-api/raw.rego +++ b/rules/exposure-to-internet-via-gateway-api/raw.rego @@ -17,10 +17,11 @@ deny[msga] { not is_exposed_service(svc) wl := input[_] - wl.metadata.namespace == svc.metadata.namespace + is_same_namespace(wl.metadata, svc.metadata) spec_template_spec_patterns := {"Deployment", "ReplicaSet", "DaemonSet", "StatefulSet", "Pod", "Job", "CronJob"} spec_template_spec_patterns[wl.kind] - wl_connected_to_service(wl, svc) + pod := get_pod_spec(wl)["spec"] + wl_connected_to_service(pod, svc) result := svc_connected_to_httproute(svc, httproute) @@ -56,23 +57,56 @@ is_exposed_service(svc) { svc.spec.type == "LoadBalancer" } +wl_connected_to_service(wl, svc) { + -wl_connected_to_service(wl, svc) { - wl.metadata.namespace == svc.metadata.namespace + count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector) } -wl_connected_to_service(wl, svc) { - count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector) + +is_same_namespace(metadata1, metadata2) { + metadata1.namespace == metadata2.namespace +} + +is_same_namespace(metadata1, metadata2) { + not metadata1.namespace + not metadata2.namespace +} + +is_same_namespace(metadata1, metadata2) { + not metadata2.namespace + metadata1.namespace == "default" +} + +is_same_namespace(metadata1, metadata2) { + not metadata1.namespace + metadata2.namespace == "default" +} + + + +# get_volume - get resource spec paths for {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} +get_pod_spec(resources) := result { + resources_kinds := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} + resources_kinds[resources.kind] + result = {"spec": resources.spec.template, "start_of_path": "spec.template."} } -wl_connected_to_service(wl, svc) { - wl.spec.selector.matchLabels == svc.spec.selector +# get_volume - get resource spec paths for "Pod" +get_pod_spec(resources) := result { + resources.kind == "Pod" + result = {"spec": resources, "start_of_path": ""} } -wl_connected_to_service(wl, svc) { - count({x | svc.spec.selector[x] == wl.spec.template.metadata.labels[x]}) == count(svc.spec.selector) +# get_volume - get resource spec paths for "CronJob" +get_pod_spec(resources) := result { + resources.kind == "CronJob" + result = {"spec": resources.spec.jobTemplate.spec.template.spec, "start_of_path": "spec.jobTemplate.spec.template.spec."} } + + + svc_connected_to_httproute(svc, httproute) = result { rule := httproute.spec.rules[i] ref := rule.backendRefs[j] diff --git a/rules/exposure-to-internet-via-istio-ingress/raw.rego b/rules/exposure-to-internet-via-istio-ingress/raw.rego index e314e562..51b7dbf0 100644 --- a/rules/exposure-to-internet-via-istio-ingress/raw.rego +++ b/rules/exposure-to-internet-via-istio-ingress/raw.rego @@ -142,10 +142,6 @@ is_exposed_service(svc) { } -wl_connected_to_service(wl, svc) { - wl.metadata.namespace == svc.metadata.namespace -} - wl_connected_to_service(wl, svc) { count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector) } diff --git a/rules/exposure-to-internet/raw.rego b/rules/exposure-to-internet/raw.rego index 5cd67b87..edd18190 100644 --- a/rules/exposure-to-internet/raw.rego +++ b/rules/exposure-to-internet/raw.rego @@ -46,6 +46,7 @@ deny[msga] { wl := input[_] spec_template_spec_patterns := {"Deployment", "ReplicaSet", "DaemonSet", "StatefulSet", "Pod", "Job", "CronJob"} spec_template_spec_patterns[wl.kind] + is_same_namespace(wl.metadata, svc.metadata) wl_connected_to_service(wl, svc) result := svc_connected_to_ingress(svc, ingress) @@ -82,9 +83,6 @@ is_exposed_service(svc) { svc.spec.type == "LoadBalancer" } -wl_connected_to_service(wl, svc) { - wl.metadata.namespace == svc.metadata.namespace -} wl_connected_to_service(wl, svc) { count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector) @@ -107,3 +105,22 @@ svc_connected_to_ingress(svc, ingress) = result { } + +is_same_namespace(metadata1, metadata2) { + metadata1.namespace == metadata2.namespace +} + +is_same_namespace(metadata1, metadata2) { + not metadata1.namespace + not metadata2.namespace +} + +is_same_namespace(metadata1, metadata2) { + not metadata2.namespace + metadata1.namespace == "default" +} + +is_same_namespace(metadata1, metadata2) { + not metadata1.namespace + metadata2.namespace == "default" +}