diff --git a/compliance/cis_k8s/rules/cis_1_2_2/rule.rego b/compliance/cis_k8s/rules/cis_1_2_2/rule.rego new file mode 100644 index 00000000..cd464bac --- /dev/null +++ b/compliance/cis_k8s/rules/cis_1_2_2/rule.rego @@ -0,0 +1,26 @@ +package compliance.cis_k8s.rules.cis_1_2_2 + +import data.compliance.cis_k8s +import data.compliance.lib.common +import data.compliance.lib.data_adapter + +# Ensure that the --basic-auth-file argument is not set (Automated) +finding = result { + command_args := data_adapter.command_args + rule_evaluation := common.array_contains(command_args, "--basic-auth-file") == false + + # set result + result := { + "evaluation": common.calculate_result(rule_evaluation), + "evidence": {"command_args": command_args}, + } +} + +metadata = { + "name": "Ensure that the --basic-auth-file argument is not set", + "description": "Basic authentication uses plaintext credentials for authentication. Currently, the basic authentication credentials last indefinitely, and the password cannot be changed without restarting the API server. The basic authentication is currently supported for convenience. Hence, basic authentication should not be used.", + "impact": "You will have to configure and use alternate authentication mechanisms such as tokens and certificates. Username and password for basic authentication could no longer be used.", + "tags": array.concat(cis_k8s.default_tags, ["CIS 1.2.2", "API Server"]), + "benchmark": cis_k8s.benchmark_name, + "remediation": "Follow the documentation and configure alternate mechanisms for authentication. Then, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml on the master node and remove the --basic-auth-file= parameter.", +} diff --git a/compliance/cis_k8s/rules/cis_1_2_2/test.rego b/compliance/cis_k8s/rules/cis_1_2_2/test.rego new file mode 100644 index 00000000..60568bec --- /dev/null +++ b/compliance/cis_k8s/rules/cis_1_2_2/test.rego @@ -0,0 +1,18 @@ +package compliance.cis_k8s.rules.cis_1_2_2 + +import data.cis_k8s.test_data +import data.lib.test + +test_violation { + test.assert_fail(finding) with input as rule_input("api_server", "--basic-auth-file") +} + +test_pass { + test.assert_pass(finding) with input as rule_input("api_server", "") +} + +test_not_evaluated { + not finding with input as rule_input("some_process", "") +} + +rule_input(process_type, argument) = test_data.api_server_input(process_type, [argument]) diff --git a/compliance/cis_k8s/test_data.rego b/compliance/cis_k8s/test_data.rego index 51c4d531..a49190f2 100644 --- a/compliance/cis_k8s/test_data.rego +++ b/compliance/cis_k8s/test_data.rego @@ -9,3 +9,9 @@ filesystem_input(filename, mode, uid, gid) = { "uid": uid, "gid": gid, } + +# Recivies an array of arguments representing the API Server command +api_server_input(process_type, arguments) = { + "type": process_type, + "command": concat(" ", array.concat(["kube-apiserver"], arguments)), +} diff --git a/compliance/lib/common.rego b/compliance/lib/common.rego index ab1fd176..5006bf25 100644 --- a/compliance/lib/common.rego +++ b/compliance/lib/common.rego @@ -22,6 +22,35 @@ file_permission_match(filemode, user, group, other) { true } +array_contains(array, key) { + contains(array[_], key) +} else = false { + true +} + +# gets argument's value +get_arg_value(arguments, key) = value { + contains(arguments[i], key) + argument := arguments[i] + [_, value] := split(argument, "=") +} + +# checks if argument contains value (argument format is csv) +arg_values_contains(arguments, key, value) { + argument := get_arg_value(arguments, key) + values := split(argument, ",") + value = values[_] +} else = false { + true +} + +# checks if a argument is set to greater value then minimum +arg_at_least(arguments, key, minimum) { + value := get_arg_value(arguments, key) + to_number(value) >= minimum +} else = false { + true + # check if file is in path file_in_path(path, file_path) { closed_path := concat("", [file_path, "/"]) # make sure last dir name is closed by "/" diff --git a/compliance/lib/data_adapter.rego b/compliance/lib/data_adapter.rego index 4e06c4db..417384b7 100644 --- a/compliance/lib/data_adapter.rego +++ b/compliance/lib/data_adapter.rego @@ -28,3 +28,13 @@ owner_group_id = gid { is_filesystem gid = input.gid } + +is_process { + input.type == "api_server" +} + +# split the process args string into an array +command_args = args { + is_process + args = split(input.command, " ") +}