diff --git a/docs/intents/escape-to-host.md b/docs/intents/escape-to-host.md index 8a4f56df..c54821cf 100644 --- a/docs/intents/escape-to-host.md +++ b/docs/intents/escape-to-host.md @@ -30,7 +30,7 @@ The escapeToHost intent results in `KyvernoPolicy` and a couple of `KubearmorPol ``` params: - psa_level: ["restricted"] + psaLevel: ["restricted"] ``` - The `escapeToHost` intent and corresponding policy work together to establish a strong security posture for the application. By enforcing pod security standards, the policy reduces the risk of container escape, which is critical for maintaining the integrity of the host system. diff --git a/examples/clusterscoped/escape-to-host-si-csib-with-params.yaml b/examples/clusterscoped/escape-to-host-si-csib-with-params.yaml index 6d9b7f10..3e82d76c 100644 --- a/examples/clusterscoped/escape-to-host-si-csib-with-params.yaml +++ b/examples/clusterscoped/escape-to-host-si-csib-with-params.yaml @@ -11,7 +11,7 @@ spec: description: "A attacker can breach container boundaries and can gain access to the host machine" action: Block params: - psa_level: ["restricted"] + psaLevel: ["restricted"] --- apiVersion: intent.security.nimbus.com/v1alpha1 kind: ClusterSecurityIntentBinding diff --git a/examples/namespaced/escape-to-host-with-params.yaml b/examples/namespaced/escape-to-host-with-params.yaml index f6a09a0b..a43903c6 100644 --- a/examples/namespaced/escape-to-host-with-params.yaml +++ b/examples/namespaced/escape-to-host-with-params.yaml @@ -11,7 +11,7 @@ spec: description: "A attacker can breach container boundaries and can gain access to the host machine" action: Block params: - psa_level: ["restricted"] + psaLevel: ["restricted"] --- apiVersion: intent.security.nimbus.com/v1alpha1 kind: SecurityIntentBinding diff --git a/examples/namespaced/virtual-patch-si-sib.yaml b/examples/namespaced/virtual-patch-si-sib.yaml index 959e02c8..31504de8 100644 --- a/examples/namespaced/virtual-patch-si-sib.yaml +++ b/examples/namespaced/virtual-patch-si-sib.yaml @@ -13,7 +13,7 @@ spec: to any production server. Check and apply virtual patch for a given set of CVEs as per a schedule action: Block params: - cve_list: + cveList: - "CVE-2024-4439" - "CVE-2024-27268" schedule: ["0 23 * * SUN"] diff --git a/pkg/adapter/nimbus-kyverno/processor/kcpbuilder.go b/pkg/adapter/nimbus-kyverno/processor/kcpbuilder.go index 58d2f045..7710c752 100644 --- a/pkg/adapter/nimbus-kyverno/processor/kcpbuilder.go +++ b/pkg/adapter/nimbus-kyverno/processor/kcpbuilder.go @@ -185,16 +185,16 @@ func clusterCocoRuntimeAddition(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1 } func clusterEscapeToHost(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1.Rule) kyvernov1.ClusterPolicy { - var psa_level api.Level = api.LevelBaseline + var psaLevel api.Level = api.LevelBaseline - if rule.Params["psa_level"] != nil { + if rule.Params["psaLevel"] != nil { - switch rule.Params["psa_level"][0] { + switch rule.Params["psaLevel"][0] { case "restricted": - psa_level = api.LevelRestricted + psaLevel = api.LevelRestricted default: - psa_level = api.LevelBaseline + psaLevel = api.LevelBaseline } } @@ -296,7 +296,7 @@ func clusterEscapeToHost(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1.Rule) }, Validation: kyvernov1.Validation{ PodSecurity: &kyvernov1.PodSecurity{ - Level: psa_level, + Level: psaLevel, Version: "latest", }, }, diff --git a/pkg/adapter/nimbus-kyverno/processor/kpbuilder.go b/pkg/adapter/nimbus-kyverno/processor/kpbuilder.go index b0c81471..a21d9a7a 100644 --- a/pkg/adapter/nimbus-kyverno/processor/kpbuilder.go +++ b/pkg/adapter/nimbus-kyverno/processor/kpbuilder.go @@ -7,6 +7,7 @@ import ( "context" "encoding/json" "fmt" + "os" "strconv" "strings" @@ -52,7 +53,7 @@ func BuildKpsFrom(logger logr.Logger, np *v1alpha1.NimbusPolicy) []kyvernov1.Pol kp.Annotations = make(map[string]string) kp.Annotations["policies.kyverno.io/description"] = nimbusRule.Description kp.Spec.Background = &background - + if nimbusRule.Rule.RuleAction == "Block" { kp.Spec.ValidationFailureAction = kyvernov1.ValidationFailureAction("Enforce") } else { @@ -98,47 +99,46 @@ func watchCVES(np *v1alpha1.NimbusPolicy, logger logr.Logger) { if rule.Params["schedule"] != nil { schedule = rule.Params["schedule"][0] } - // Schedule the deletion of the Nimbus policy - c := cron.New() - _, err := c.AddFunc(schedule, func() { - logger.Info("Checking for CVE updates and updation of policies") - err := deleteNimbusPolicy(np, logger) - if err != nil { - logger.Error(err, "error while updating policies") - } - }) - if err != nil { - logger.Error(err, "error while adding the schedule to update policies") - } - c.Start() + // Schedule the deletion of the Nimbus policy + c := cron.New() + _, err := c.AddFunc(schedule, func() { + logger.Info("Checking for CVE updates and updation of policies") + err := deleteNimbusPolicy(np, logger) + if err != nil { + logger.Error(err, "error while updating policies") + } + }) + if err != nil { + logger.Error(err, "error while adding the schedule to update policies") + os.Exit(1) + } + c.Start() } - - func deleteNimbusPolicy(np *v1alpha1.NimbusPolicy, logger logr.Logger) error { - nimbusPolicyGVR := schema.GroupVersionResource{Group: "intent.security.nimbus.com", Version: "v1alpha1", Resource: "nimbuspolicies"} - err := client.Resource(nimbusPolicyGVR).Namespace(np.Namespace).Delete(context.TODO(), np.Name,metav1.DeleteOptions{}) + nimbusPolicyGVR := schema.GroupVersionResource{Group: "intent.security.nimbus.com", Version: "v1alpha1", Resource: "nimbuspolicies"} + err := client.Resource(nimbusPolicyGVR).Namespace(np.Namespace).Delete(context.TODO(), np.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("failed to delete Nimbus Policy: %s", err.Error()) } logger.Info("Nimbus policy deleted successfully") - return nil + return nil } func escapeToHost(np *v1alpha1.NimbusPolicy) kyvernov1.Policy { rule := np.Spec.NimbusRules[0].Rule - var psa_level api.Level = api.LevelBaseline + var psaLevel api.Level = api.LevelBaseline var matchResourceFilters []kyvernov1.ResourceFilter - if rule.Params["psa_level"] != nil { + if rule.Params["psaLevel"] != nil { - switch rule.Params["psa_level"][0] { + switch rule.Params["psaLevel"][0] { case "restricted": - psa_level = api.LevelRestricted + psaLevel = api.LevelRestricted default: - psa_level = api.LevelBaseline + psaLevel = api.LevelBaseline } } @@ -183,7 +183,7 @@ func escapeToHost(np *v1alpha1.NimbusPolicy) kyvernov1.Policy { }, Validation: kyvernov1.Validation{ PodSecurity: &kyvernov1.PodSecurity{ - Level: psa_level, + Level: psaLevel, Version: "latest", }, }, @@ -205,7 +205,7 @@ func cocoRuntimeAddition(np *v1alpha1.NimbusPolicy) ([]kyvernov1.Policy, error) runtimeClass := "kata-clh" params := np.Spec.NimbusRules[0].Rule.Params["runtimeClass"] if params != nil { - runtimeClass = params[0] + runtimeClass = params[0] } patchStrategicMerge := map[string]interface{}{ "spec": map[string]interface{}{ @@ -353,7 +353,7 @@ func cocoRuntimeAddition(np *v1alpha1.NimbusPolicy) ([]kyvernov1.Policy, error) func virtualPatch(np *v1alpha1.NimbusPolicy, logger logr.Logger) ([]kyvernov1.Policy, error) { rule := np.Spec.NimbusRules[0].Rule - requiredCVES := rule.Params["cve_list"] + requiredCVES := rule.Params["cveList"] var kps []kyvernov1.Policy resp, err := utils.FetchVirtualPatchData[[]map[string]any]() if err != nil { @@ -378,28 +378,32 @@ func virtualPatch(np *v1alpha1.NimbusPolicy, logger logr.Logger) ([]kyvernov1.Po karmorPol, err := generatePol("karmor", cve, image, np, policyData, karmorPolCount, logger) if err != nil { logger.V(2).Error(err, "Error while generating karmor policy") + } else { + kps = append(kps, karmorPol) + karmorPolCount += 1 } - kps = append(kps, karmorPol) - karmorPolCount += 1 + } policyData, ok = pol["kyverno"].(map[string]any) if ok { kyvernoPol, err := generatePol("kyverno", cve, image, np, policyData, kyvPolCount, logger) if err != nil { logger.V(2).Error(err, "Error while generating kyverno policy") + } else { + kps = append(kps, kyvernoPol) + kyvPolCount += 1 } - kps = append(kps, kyvernoPol) - kyvPolCount += 1 } - + policyData, ok = pol["netpol"].(map[string]any) if ok { netPol, err := generatePol("netpol", cve, image, np, policyData, netPolCount, logger) if err != nil { logger.V(2).Error(err, "Error while generating network policy") + } else { + kps = append(kps, netPol) + netPolCount += 1 } - kps = append(kps, netPol) - netPolCount += 1 } } } @@ -431,14 +435,13 @@ func generatePol(polengine string, cve string, image string, np *v1alpha1.Nimbus preConditionMap := map[string]any{ "all": []any{ map[string]any{ - "key": image, + "key": image, "operator": "AnyIn", - "value": "{{ request.object.spec.containers[].image }}", + "value": "{{ request.object.spec.containers[].image }}", }, }, } preconditionBytes, _ := json.Marshal(preConditionMap) - getPodName := kyvernov1.ContextEntry{ Name: "podName", @@ -457,12 +460,10 @@ func generatePol(polengine string, cve string, image string, np *v1alpha1.Nimbus jmesPathContainerNameQuery := "request.object.spec.containers[?(@.image=='" + image + "')].name | [0]" - delete(policyData, "apiVersion") delete(policyData, "kind") - generatorPolicyName := np.Name + "-" + cve + "-"+ polengine + "-" + strconv.Itoa(count) - + generatorPolicyName := np.Name + "-" + cve + "-" + polengine + "-" + strconv.Itoa(count) // kubearmor policy generation @@ -667,6 +668,5 @@ func generatePol(polengine string, cve string, image string, np *v1alpha1.Nimbus }, } } - return pol, nil } diff --git a/pkg/adapter/nimbus-kyverno/utils/utils.go b/pkg/adapter/nimbus-kyverno/utils/utils.go index 6d1b48b6..c619658d 100644 --- a/pkg/adapter/nimbus-kyverno/utils/utils.go +++ b/pkg/adapter/nimbus-kyverno/utils/utils.go @@ -10,7 +10,6 @@ import ( "reflect" "slices" "strings" - "sync" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "golang.org/x/text/cases" @@ -19,7 +18,6 @@ import ( ) var VirtualPatchData []map[string]any -var mu sync.RWMutex func GetGVK(kind string) string { // Map to store the mappings of kinds to their corresponding API versions