diff --git a/src/confcom/azext_confcom/config.py b/src/confcom/azext_confcom/config.py index 609bc03e5ac..aff2399f2e7 100644 --- a/src/confcom/azext_confcom/config.py +++ b/src/confcom/azext_confcom/config.py @@ -196,6 +196,7 @@ DEFAULT_MOUNTS_USER_VIRTUAL_NODE = _config["mount"]["default_mounts_user_virtual_node"] DEFAULT_MOUNTS_VIRTUAL_NODE = _config["mount"]["default_mounts_virtual_node"] DEFAULT_MOUNTS_PRIVILEGED_VIRTUAL_NODE = _config["mount"]["default_mounts_virtual_node_privileged"] +DEFAULT_MOUNTS_WORKLOAD_IDENTITY_VIRTUAL_NODE = _config["mount"]["default_mounts_workload_identity_virtual_node"] # default mounts policy options for all containers DEFAULT_MOUNT_POLICY = _config["mount"]["default_policy"] # default rego policy to be added to all user containers diff --git a/src/confcom/azext_confcom/data/internal_config.json b/src/confcom/azext_confcom/data/internal_config.json index e9aa17a5b3b..e93fff7eea6 100644 --- a/src/confcom/azext_confcom/data/internal_config.json +++ b/src/confcom/azext_confcom/data/internal_config.json @@ -282,6 +282,14 @@ "mountType": "emptyDir", "mountPath": "/etc/hostname" } + ], + "default_mounts_workload_identity_virtual_node": [ + { + "name": "azure-tokens", + "mountType": "emptyDir", + "mountPath": "/var/run/secrets/azure/tokens", + "readonly": true + } ] }, "sidecar_base_names": [ diff --git a/src/confcom/azext_confcom/security_policy.py b/src/confcom/azext_confcom/security_policy.py index f0d845bc24d..9a369cc8a5b 100644 --- a/src/confcom/azext_confcom/security_policy.py +++ b/src/confcom/azext_confcom/security_policy.py @@ -1076,10 +1076,7 @@ def load_policy_from_virtual_node_yaml_str( # extract existing policy and fragments for diff mode metadata = case_insensitive_dict_get(yaml, config.VIRTUAL_NODE_YAML_METADATA) annotations = case_insensitive_dict_get(metadata, config.VIRTUAL_NODE_YAML_ANNOTATIONS) - labels = case_insensitive_dict_get(metadata, config.VIRTUAL_NODE_YAML_LABELS) or [] - use_workload_identity = ( - config.VIRTUAL_NODE_YAML_LABEL_WORKLOAD_IDENTITY in labels - and labels.get(config.VIRTUAL_NODE_YAML_LABEL_WORKLOAD_IDENTITY) == "true") + existing_policy = case_insensitive_dict_get(annotations, config.VIRTUAL_NODE_YAML_POLICY) try: if existing_policy: @@ -1095,6 +1092,12 @@ def load_policy_from_virtual_node_yaml_str( normalized_yaml = convert_to_pod_spec(yaml) volume_claim_templates = get_volume_claim_templates(yaml) + normalized_metadata = case_insensitive_dict_get(normalized_yaml, config.VIRTUAL_NODE_YAML_METADATA) + labels = case_insensitive_dict_get(normalized_metadata, config.VIRTUAL_NODE_YAML_LABELS) or [] + use_workload_identity = ( + config.VIRTUAL_NODE_YAML_LABEL_WORKLOAD_IDENTITY in labels + and labels.get(config.VIRTUAL_NODE_YAML_LABEL_WORKLOAD_IDENTITY) == "true") + spec = case_insensitive_dict_get(normalized_yaml, "spec") if not spec: eprint("YAML file does not contain a spec field") @@ -1124,8 +1127,6 @@ def load_policy_from_virtual_node_yaml_str( secrets_data, approve_wildcards=approve_wildcards ) - if use_workload_identity: - envs += config.VIRTUAL_NODE_ENV_RULES_WORKLOAD_IDENTITY # command command = case_insensitive_dict_get(container, config.VIRTUAL_NODE_YAML_COMMAND) or [] @@ -1135,6 +1136,10 @@ def load_policy_from_virtual_node_yaml_str( mounts = copy.deepcopy(config.DEFAULT_MOUNTS_VIRTUAL_NODE) volumes = case_insensitive_dict_get(spec, "volumes") or [] + if use_workload_identity: + envs += config.VIRTUAL_NODE_ENV_RULES_WORKLOAD_IDENTITY + mounts += config.DEFAULT_MOUNTS_WORKLOAD_IDENTITY_VIRTUAL_NODE + # there can be implicit volumes from volumeClaimTemplates # We need to add them to the list of volumes and note if they are readonly for volume_claim_template in volume_claim_templates: diff --git a/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py b/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py index 1610c68c73b..ca83719070e 100644 --- a/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py +++ b/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py @@ -577,8 +577,8 @@ def test_image_layers_python(self): aci_policy.populate_policy_content_for_all_images() layers = aci_policy.get_images()[0]._layers expected_layers = [ - "6ee0f2697647b69975229db7445260a1c9ae5b039f9a52a911e72b6c3302d391", - "3ba5dd39bf58f28b7e57a52d10edf1813fe3b1fd1d0ef57573b1b912d6b9d1f6" + "f4dbab29a5ddebfa8866d72df10d284ffb2b11292baf8d184b7bc1241d5074fd", + "c003cd912b804162760beb676e5b629a297d75fbdcffd2d3ee49bacc0b985a52" ] self.assertEqual(len(layers), len(expected_layers)) for i in range(len(expected_layers)): diff --git a/src/confcom/azext_confcom/tests/latest/test_confcom_virtual_node.py b/src/confcom/azext_confcom/tests/latest/test_confcom_virtual_node.py index b1b0ca7448a..2ae37aa9bac 100644 --- a/src/confcom/azext_confcom/tests/latest/test_confcom_virtual_node.py +++ b/src/confcom/azext_confcom/tests/latest/test_confcom_virtual_node.py @@ -385,9 +385,12 @@ def test_workload_identity(self): # have to extract the name from the pattern env_rule_names = [(env_rule['pattern']).split("=")[0] for env_rule in containers[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_ENVS]] + mounts = [mount[config.POLICY_FIELD_CONTAINERS_ELEMENTS_MOUNTS_DESTINATION] for mount in containers[0][config.ACI_FIELD_CONTAINERS_MOUNTS]] for var in config.VIRTUAL_NODE_ENV_RULES_WORKLOAD_IDENTITY: self.assertTrue(var['name'] in env_rule_names) + for mount in config.DEFAULT_MOUNTS_WORKLOAD_IDENTITY_VIRTUAL_NODE: + self.assertTrue(mount['mountPath'] in mounts) def test_volume_claim(self): virtual_node_policy = load_policy_from_virtual_node_yaml_str(self.custom_yaml_volume_claim)[0]