From 2a0b0b6018991325fc827209510a0d2c808a433f Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Mon, 14 Sep 2026 08:45:34 +0100 Subject: [PATCH 1/8] fix(queries): correct mismatched expected/actual values across 22 queries --- .../ecs_service_without_running_tasks/query.rego | 6 +++--- .../sql_server_ingress_from_any_ip/query.rego | 4 ++-- .../email_notifications_set_off/query.rego | 2 +- .../amplify_app_access_token_exposed/query.rego | 8 ++++---- .../query.rego | 8 ++++---- .../amplify_app_oauth_token_exposed/query.rego | 16 ++++++++-------- .../query.rego | 8 ++++---- .../query.rego | 2 +- .../query.rego | 2 +- .../query.rego | 2 +- .../query.rego | 6 +++--- .../query.rego | 8 ++++---- .../query.rego | 8 ++++---- .../aws/dms_endpoint_password_exposed/query.rego | 8 ++++---- .../query.rego | 8 ++++---- .../ecs_service_without_running_tasks/query.rego | 4 ++-- .../query.rego | 4 ++-- .../aws/iam_policy_on_user/query.rego | 4 ++-- .../query.rego | 4 ++-- .../query.rego | 4 ++-- .../aws/ec2_instance_using_api_keys/query.rego | 8 ++++---- .../ecs_service_without_running_tasks/query.rego | 4 ++-- 22 files changed, 64 insertions(+), 64 deletions(-) diff --git a/assets/queries/ansible/aws/ecs_service_without_running_tasks/query.rego b/assets/queries/ansible/aws/ecs_service_without_running_tasks/query.rego index afc693972a8..52fd5b9a516 100644 --- a/assets/queries/ansible/aws/ecs_service_without_running_tasks/query.rego +++ b/assets/queries/ansible/aws/ecs_service_without_running_tasks/query.rego @@ -18,7 +18,7 @@ CxPolicy[result] { "searchKey": sprintf("name={{%s}}.{{%s}}", [task.name, modules[m]]), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("%s.deployment_configuration should be defined", [modules[m]]), - "keyActualValue": sprintf("%&s.deployment_configuration is undefined", [modules[m]]), + "keyActualValue": sprintf("%s.deployment_configuration is undefined", [modules[m]]), } } @@ -36,8 +36,8 @@ CxPolicy[result] { "resourceName": task.name, "searchKey": sprintf("name={{%s}}.{{%s}}.deployment_configuration", [task.name, modules[m]]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("%s.deployment_configuration should have at least 1 task running", [modules[m]]), - "keyActualValue": sprintf("%&s.deployment_configuration must have at least 1 task running", [modules[m]]), + "keyExpectedValue": sprintf("%s.deployment_configuration should have maximum_percent or minimum_healthy_percent defined", [modules[m]]), + "keyActualValue": sprintf("%s.deployment_configuration doesn't have maximum_percent or minimum_healthy_percent defined", [modules[m]]), } } diff --git a/assets/queries/ansible/azure/sql_server_ingress_from_any_ip/query.rego b/assets/queries/ansible/azure/sql_server_ingress_from_any_ip/query.rego index 38f57d88c7c..7d48290d868 100644 --- a/assets/queries/ansible/azure/sql_server_ingress_from_any_ip/query.rego +++ b/assets/queries/ansible/azure/sql_server_ingress_from_any_ip/query.rego @@ -17,8 +17,8 @@ CxPolicy[result] { "resourceName": task.name, "searchKey": sprintf("name={{%s}}.{{%s}}.end_ip_address", [task.name, modules[m]]), "issueType": "IncorrectValue", - "keyExpectedValue": "azure_rm_sqlfirewallrule should allow all IPs", - "keyActualValue": "azure_rm_sqlfirewallrule should not allow all IPs (range from start_ip_address to end_ip_address)", + "keyExpectedValue": "azure_rm_sqlfirewallrule should not allow all IPs", + "keyActualValue": "azure_rm_sqlfirewallrule allows all IPs (range from start_ip_address to end_ip_address)", } } diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/query.rego b/assets/queries/azureResourceManager/email_notifications_set_off/query.rego index 8442dc3a4e0..b6123312837 100644 --- a/assets/queries/azureResourceManager/email_notifications_set_off/query.rego +++ b/assets/queries/azureResourceManager/email_notifications_set_off/query.rego @@ -58,7 +58,7 @@ CxPolicy[result] { "searchKey": sprintf("%s.name={{%s}}.properties.%s.state", [common_lib.concat_path(path), value.name, emailType[x]]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("resource with type 'Microsoft.Security/securityContacts' %s should have '%s.state' property set to 'On'", [type ,emailType[x]]), - "keyActualValue": sprintf("resource with type 'Microsoft.Security/securityContacts' should have '%s.state' property set to 'Off'", [emailType[x]]), + "keyActualValue": sprintf("resource with type 'Microsoft.Security/securityContacts' has '%s.state' property set to 'Off'", [emailType[x]]), "searchLine": common_lib.build_search_line(path, ["properties", emailType[x], "state"]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego index c234af39a5f..a93bb8c28d9 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego @@ -23,8 +23,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -50,7 +50,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.AccessToken", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.AccessToken must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.AccessToken is defined as a plaintext value", [key]), } } @@ -75,6 +75,6 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.AccessToken", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.AccessToken must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.AccessToken is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego index ba47931720c..c7341b6ef0d 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego @@ -23,8 +23,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -51,7 +51,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } @@ -77,7 +77,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego index 999a915bd6b..ca958f9ba60 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego @@ -22,8 +22,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -46,10 +46,10 @@ CxPolicy[result] { "documentId": input.document[i].id, "resourceType": resource.Type, "resourceName": cf_lib.get_resource_name(resource, key), - "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), + "searchKey": sprintf("Resources.%s.Properties.OauthToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must not be in plain text string", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.OauthToken is defined as a plaintext value", [key]), } } @@ -71,9 +71,9 @@ CxPolicy[result] { "documentId": input.document[i].id, "resourceType": resource.Type, "resourceName": cf_lib.get_resource_name(resource, key), - "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), + "searchKey": sprintf("Resources.%s.Properties.OauthToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must not be in plain text string", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.OauthToken is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego index e28d16588da..f5b3463d946 100644 --- a/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego @@ -24,8 +24,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -51,7 +51,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } @@ -76,7 +76,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/api_gateway_deployment_without_access_log_setting/query.rego b/assets/queries/cloudFormation/aws/api_gateway_deployment_without_access_log_setting/query.rego index e4f9f431efa..a8360dddc16 100644 --- a/assets/queries/cloudFormation/aws/api_gateway_deployment_without_access_log_setting/query.rego +++ b/assets/queries/cloudFormation/aws/api_gateway_deployment_without_access_log_setting/query.rego @@ -37,7 +37,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s", [name]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s should have AWS::ApiGateway::Stage associated, DeploymentId.Ref should be the same as the ApiGateway::Stage resource", [name]), - "keyActualValue": sprintf("Resources.%s should have AWS::ApiGateway::Stage associated, DeploymentId.Ref should be the same in the ApiGateway::Stage resource", [name]), + "keyActualValue": sprintf("Resources.%s doesn't have a AWS::ApiGateway::Stage whose DeploymentId.Ref matches this resource", [name]), } } diff --git a/assets/queries/cloudFormation/aws/api_gateway_deployment_without_api_gateway_usage_plan_associated/query.rego b/assets/queries/cloudFormation/aws/api_gateway_deployment_without_api_gateway_usage_plan_associated/query.rego index d21841b27c2..045ab834e30 100644 --- a/assets/queries/cloudFormation/aws/api_gateway_deployment_without_api_gateway_usage_plan_associated/query.rego +++ b/assets/queries/cloudFormation/aws/api_gateway_deployment_without_api_gateway_usage_plan_associated/query.rego @@ -38,7 +38,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s", [name]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s should have AWS::ApiGateway::UsagePlan associated, RestApiId and StageName should be the same as the %s resource", [name, name]), - "keyActualValue": sprintf("Resources.%s should have AWS::ApiGateway::UsagePlan associated, RestApiId and StageName should be the same in the %s resource", [name, name]), + "keyActualValue": sprintf("Resources.%s doesn't have a AWS::ApiGateway::UsagePlan whose RestApiId and StageName match the %s resource", [name, name]), "searchLine": common_lib.build_search_line(["Resources", name], []), } } diff --git a/assets/queries/cloudFormation/aws/api_gateway_stage_without_api_gateway_usage_plan_associated/query.rego b/assets/queries/cloudFormation/aws/api_gateway_stage_without_api_gateway_usage_plan_associated/query.rego index 0d1e80d455d..07fba929e0c 100644 --- a/assets/queries/cloudFormation/aws/api_gateway_stage_without_api_gateway_usage_plan_associated/query.rego +++ b/assets/queries/cloudFormation/aws/api_gateway_stage_without_api_gateway_usage_plan_associated/query.rego @@ -38,7 +38,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s", [name]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s should have AWS::ApiGateway::UsagePlan associated, RestApiId and StageName should be the same as the %s resource", [name, name]), - "keyActualValue": sprintf("Resources.%s should have AWS::ApiGateway::UsagePlan associated, RestApiId and StageName should be the same in the %s resource", [name, name]), + "keyActualValue": sprintf("Resources.%s doesn't have a AWS::ApiGateway::UsagePlan whose RestApiId and StageName match the %s resource", [name, name]), "searchLine": common_lib.build_search_line(["Resources", name], []), } } diff --git a/assets/queries/cloudFormation/aws/api_gateway_without_security_policy/query.rego b/assets/queries/cloudFormation/aws/api_gateway_without_security_policy/query.rego index ade9781892b..a5b9d2fd3cd 100644 --- a/assets/queries/cloudFormation/aws/api_gateway_without_security_policy/query.rego +++ b/assets/queries/cloudFormation/aws/api_gateway_without_security_policy/query.rego @@ -17,8 +17,8 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, name), "searchKey": sprintf("Resources.%s.Properties.SecurityPolicy", [name]), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("Resources.%s.Properties.SecurityPolicy should not be defined", [name]), - "keyActualValue": sprintf("Resources.%s.Properties.SecurityPolicy is defined", [name]), + "keyExpectedValue": sprintf("Resources.%s.Properties.SecurityPolicy should be defined as TLS_1_2", [name]), + "keyActualValue": sprintf("Resources.%s.Properties.SecurityPolicy is not defined", [name]), } } @@ -37,6 +37,6 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.SecurityPolicy", [name]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.SecurityPolicy should be %s", [name, tls]), - "keyActualValue": sprintf("Resources.%s.Properties.SecurityPolicy should be %s", [name, tls]), + "keyActualValue": sprintf("Resources.%s.Properties.SecurityPolicy is %s", [name, resource.Properties.SecurityPolicy]), } } diff --git a/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego b/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego index 9b2a1f83fce..d1808217381 100644 --- a/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego @@ -21,8 +21,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -47,7 +47,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } @@ -73,6 +73,6 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego b/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego index c5e58cf715e..389db261147 100644 --- a/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego @@ -21,8 +21,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -47,7 +47,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.MongoDbSettings.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password is defined as a plaintext value", [key]), } } @@ -73,6 +73,6 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.MongoDbSettings.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego b/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego index b4398957457..c9b1329fb75 100644 --- a/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego @@ -21,8 +21,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -47,7 +47,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } @@ -73,7 +73,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego b/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego index 9b96f71cc76..a54ef581f9c 100644 --- a/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego +++ b/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego @@ -21,8 +21,8 @@ CxPolicy[result] { "resourceName": "n/a", "searchKey": sprintf("Parameters.%s.Default", [paramName]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Parameters.%s.Default should be defined", [paramName]), - "keyActualValue": sprintf("Parameters.%s.Default shouldn't be defined", [paramName]), + "keyExpectedValue": sprintf("Parameters.%s.Default should not be defined", [paramName]), + "keyActualValue": sprintf("Parameters.%s.Default is defined", [paramName]), } } @@ -48,7 +48,7 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.MasterUserPassword", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword is defined as a plaintext value", [key]), } } @@ -73,6 +73,6 @@ CxPolicy[result] { "searchKey": sprintf("Resources.%s.Properties.MasterUserPassword", [key]), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must not be in plain text string", [key]), - "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword must be defined as a parameter or have a secret manager referenced", [key]), + "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/ecs_service_without_running_tasks/query.rego b/assets/queries/cloudFormation/aws/ecs_service_without_running_tasks/query.rego index 84dee3ad626..835dde0d4ab 100644 --- a/assets/queries/cloudFormation/aws/ecs_service_without_running_tasks/query.rego +++ b/assets/queries/cloudFormation/aws/ecs_service_without_running_tasks/query.rego @@ -34,8 +34,8 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, name), "searchKey": sprintf("Resources.%s.Properties.DeploymentConfiguration", [name]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.DeploymentConfiguration should have at least 1 task running", [name]), - "keyActualValue": sprintf("Resources.%s.Properties.DeploymentConfiguration must have at least 1 task running", [name]), + "keyExpectedValue": sprintf("Resources.%s.Properties.DeploymentConfiguration should have MaximumPercent, MinimumHealthyPercent or DeploymentCircuitBreaker defined", [name]), + "keyActualValue": sprintf("Resources.%s.Properties.DeploymentConfiguration doesn't have MaximumPercent, MinimumHealthyPercent or DeploymentCircuitBreaker defined", [name]), } } diff --git a/assets/queries/cloudFormation/aws/iam_managed_policy_applied_to_a_user/query.rego b/assets/queries/cloudFormation/aws/iam_managed_policy_applied_to_a_user/query.rego index c169a268654..8ca504d6bb0 100644 --- a/assets/queries/cloudFormation/aws/iam_managed_policy_applied_to_a_user/query.rego +++ b/assets/queries/cloudFormation/aws/iam_managed_policy_applied_to_a_user/query.rego @@ -13,7 +13,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, name), "searchKey": sprintf("Resources.%s.Properties.Users", [name]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s is assigned to a set of users", [name]), - "keyActualValue": sprintf("Resources.%s should be assigned to a set of groups", [name]), + "keyExpectedValue": sprintf("Resources.%s should be assigned to a set of groups", [name]), + "keyActualValue": sprintf("Resources.%s is assigned to a set of users", [name]), } } diff --git a/assets/queries/cloudFormation/aws/iam_policy_on_user/query.rego b/assets/queries/cloudFormation/aws/iam_policy_on_user/query.rego index 33299cc4f22..bc6e62a6fcc 100644 --- a/assets/queries/cloudFormation/aws/iam_policy_on_user/query.rego +++ b/assets/queries/cloudFormation/aws/iam_policy_on_user/query.rego @@ -16,7 +16,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(document.Resources[policyName], policyName), "searchKey": sprintf("Resources.%s.Properties.Users", [policyName]), "issueType": "IncorrectValue", #"MissingAttribute" / "RedundantAttribute" - "keyExpectedValue": sprintf("Resources.%s is assigned to a set of users", [policyName]), - "keyActualValue": sprintf("Resources.%s should be assigned to a set of groups", [policyName]), + "keyExpectedValue": sprintf("Resources.%s should be assigned to a set of groups", [policyName]), + "keyActualValue": sprintf("Resources.%s is assigned to a set of users", [policyName]), } } diff --git a/assets/queries/dockerfile/missing_version_specification_in_dnf_install/query.rego b/assets/queries/dockerfile/missing_version_specification_in_dnf_install/query.rego index 0d50a1ebde0..eca6401f87a 100644 --- a/assets/queries/dockerfile/missing_version_specification_in_dnf_install/query.rego +++ b/assets/queries/dockerfile/missing_version_specification_in_dnf_install/query.rego @@ -24,7 +24,7 @@ CxPolicy[result] { "searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]), "issueType": "IncorrectValue", "keyExpectedValue": "Package version should be specified when using 'dnf install'", - "keyActualValue": "Package version should be pinned when running ´dnf install´", + "keyActualValue": sprintf("Package '%s' has no version specified", [packages[j]]), } } @@ -47,7 +47,7 @@ CxPolicy[result] { "searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]), "issueType": "IncorrectValue", "keyExpectedValue": "Package version should be specified when using 'dnf install'", - "keyActualValue": "Package version should be pinned when running ´dnf install´", + "keyActualValue": sprintf("Package '%s' has no version specified", [resource.Value[j]]), } } diff --git a/assets/queries/openAPI/3.0/security_requirement_object_with_wrong_scopes/query.rego b/assets/queries/openAPI/3.0/security_requirement_object_with_wrong_scopes/query.rego index 93f335cdc55..b665849efca 100644 --- a/assets/queries/openAPI/3.0/security_requirement_object_with_wrong_scopes/query.rego +++ b/assets/queries/openAPI/3.0/security_requirement_object_with_wrong_scopes/query.rego @@ -18,7 +18,7 @@ CxPolicy[result] { "documentId": doc.id, "searchKey": sprintf("%s", [openapi_lib.concat_path(path_t)]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("'security.%s' has no scopes defined for security scheme of type '%s'", [name, auth_no_scopes[t]]), - "keyActualValue": sprintf("'security.%s' has no scopes defined for security scheme of type '%s'", [name, auth_no_scopes[t]]), + "keyExpectedValue": sprintf("'security.%s' should have no scopes defined for security scheme of type '%s'", [name, auth_no_scopes[t]]), + "keyActualValue": sprintf("'security.%s' has scopes defined for security scheme of type '%s'", [name, auth_no_scopes[t]]), } } diff --git a/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego b/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego index 48c7ba01c7c..5afde5c3a2e 100644 --- a/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego +++ b/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego @@ -63,8 +63,8 @@ CxPolicy[result] { "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("aws_instance[%s].provisioner", [name]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("aws_instance[%s].provisioner.remote-exec should be used to configure AWS API keys", [name]), - "keyActualValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), + "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), + "keyActualValue": sprintf("aws_instance[%s].provisioner.remote-exec is being used to configure AWS API keys", [name]), } } @@ -81,8 +81,8 @@ CxPolicy[result] { "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("aws_instance[%s].provisioner", [name]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("aws_instance[%s].provisioner.file should be used to configure AWS API keys", [name]), - "keyActualValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), + "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), + "keyActualValue": sprintf("aws_instance[%s].provisioner.file is being used to configure AWS API keys", [name]), } } diff --git a/assets/queries/terraform/aws/ecs_service_without_running_tasks/query.rego b/assets/queries/terraform/aws/ecs_service_without_running_tasks/query.rego index e6de2c1d9ff..f7284c186fc 100644 --- a/assets/queries/terraform/aws/ecs_service_without_running_tasks/query.rego +++ b/assets/queries/terraform/aws/ecs_service_without_running_tasks/query.rego @@ -15,8 +15,8 @@ CxPolicy[result] { "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("aws_ecs_service[%s]", [name]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("'aws_ecs_service[%s]' has at least 1 task running", [name]), - "keyActualValue": sprintf("'aws_ecs_service[%s]' must have at least 1 task running", [name]), + "keyExpectedValue": sprintf("'aws_ecs_service[%s]' should have at least 1 task running", [name]), + "keyActualValue": sprintf("'aws_ecs_service[%s]' has desired_count set to 0", [name]), } } From a11eda056bb4bb6ec648ef59b906cdf283d8f779 Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Mon, 14 Sep 2026 09:24:36 +0100 Subject: [PATCH 2/8] update: positive expected results and add missing search_line to ec2_instance_using_api_keys terraform aws query --- .../test/positive_expected_result.json | 4 ++-- .../aws/ec2_instance_using_api_keys/query.rego | 4 ++++ .../test/positive_expected_result.json | 12 ++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/test/positive_expected_result.json b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/test/positive_expected_result.json index e205140998d..afa6c2ea811 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/test/positive_expected_result.json +++ b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/test/positive_expected_result.json @@ -6,7 +6,7 @@ "fileName": "positive2.yaml" }, { - "line": 4, + "line": 12, "fileName": "positive1.yaml", "queryName": "Amplify App OAuth Token Exposed", "severity": "HIGH" @@ -14,7 +14,7 @@ { "queryName": "Amplify App OAuth Token Exposed", "severity": "HIGH", - "line": 5, + "line": 8, "fileName": "positive3.json" }, { diff --git a/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego b/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego index 5afde5c3a2e..885afc9b65f 100644 --- a/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego +++ b/assets/queries/terraform/aws/ec2_instance_using_api_keys/query.rego @@ -29,6 +29,7 @@ CxPolicy[result] { "issueType": "MissingAttribute", "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), "keyActualValue": sprintf("aws_instance[%s].user_data is being used to configure AWS API keys", [name]), + "searchLine": common_lib.build_search_line(["resource", "aws_instance", name, "user_data"], []), } } @@ -47,6 +48,7 @@ CxPolicy[result] { "issueType": "MissingAttribute", "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), "keyActualValue": sprintf("aws_instance[%s].user_data is being used to configure AWS API keys", [name]), + "searchLine": common_lib.build_search_line(["resource", "aws_instance", name, "user_data_base64"], []), } } @@ -65,6 +67,7 @@ CxPolicy[result] { "issueType": "IncorrectValue", "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), "keyActualValue": sprintf("aws_instance[%s].provisioner.remote-exec is being used to configure AWS API keys", [name]), + "searchLine": common_lib.build_search_line(["resource", "aws_instance", name, "provisioner", "remote-exec"], []), } } @@ -83,6 +86,7 @@ CxPolicy[result] { "issueType": "IncorrectValue", "keyExpectedValue": sprintf("aws_instance[%s] should be using iam_instance_profile to assign a role with permissions", [name]), "keyActualValue": sprintf("aws_instance[%s].provisioner.file is being used to configure AWS API keys", [name]), + "searchLine": common_lib.build_search_line(["resource", "aws_instance", name, "provisioner", "file"], []), } } diff --git a/assets/queries/terraform/aws/ec2_instance_using_api_keys/test/positive_expected_result.json b/assets/queries/terraform/aws/ec2_instance_using_api_keys/test/positive_expected_result.json index 715b290c48f..6dca9653a8f 100644 --- a/assets/queries/terraform/aws/ec2_instance_using_api_keys/test/positive_expected_result.json +++ b/assets/queries/terraform/aws/ec2_instance_using_api_keys/test/positive_expected_result.json @@ -2,37 +2,37 @@ { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive1.tf" }, { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive2.tf" }, { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive3.tf" }, { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive4.tf" }, { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive5.tf" }, { "queryName": "EC2 Instance Using API Keys", "severity": "LOW", - "line": 5, + "line": 13, "fileName": "positive6.tf" }, { From 74900c3dbb25e95815adb63e211e55ac58fdd54a Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Mon, 14 Sep 2026 09:45:11 +0100 Subject: [PATCH 3/8] remove: not allowed action from validate cfn samples action --- .github/workflows/validate-cfn-samples.yml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/validate-cfn-samples.yml b/.github/workflows/validate-cfn-samples.yml index 25a156cd81f..7c6ea0efa6d 100644 --- a/.github/workflows/validate-cfn-samples.yml +++ b/.github/workflows/validate-cfn-samples.yml @@ -1,7 +1,6 @@ name: validate-cfn-samples on: - workflow_dispatch: pull_request: paths: - "assets/queries/cloudFormation/**/test/*.yaml" @@ -18,9 +17,6 @@ jobs: validate-cfn-syntax: name: Validate Cloudformation Syntax runs-on: cx-public-ubuntu-x64 - permissions: - contents: read # for actions/checkout to fetch code - pull-requests: read # for lots0logs/gh-action-get-changed-files to read the PR's changed file list steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -30,19 +26,13 @@ jobs: uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.x' - - name: Get commit changed files - if: github.event_name != 'workflow_dispatch' - uses: lots0logs/gh-action-get-changed-files@6cb5164a823dbf3318b7c8032a333b4b7ed425b2 # 2.2.2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - name: Get cfn-python-lint env: ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }} run: | pip config set global.index-url "https://:${ECHO_LIBRARIES_ACCESS_KEY}@pypi.echohq.com/simple" pip3 install -U cfn-lint --user - - name: Validate ALL cloudformation template samples - if: github.event_name == 'workflow_dispatch' + - name: Validate cloudformation template samples run: | python3 -u .github/scripts/samples-linters/validate-syntax.py \ "assets/queries/cloudFormation/**/test/*.yaml" \ @@ -51,13 +41,3 @@ jobs: --extra " --info --config-file .github/scripts/samples-linters/.cfnlintrc.yml" \ --skip ".github/scripts/samples-linters/ignore-list/cloudformation" \ --verbose - - name: Validate CHANGED cloudformation template samples - if: github.event_name != 'workflow_dispatch' - run: | - python3 -u .github/scripts/samples-linters/validate-syntax.py \ - "assets/queries/cloudFormation/**/test/*.yaml" \ - "assets/queries/cloudFormation/**/test/*.json" \ - --diff ${HOME}/files.json \ - --linter /home/runner/.local/bin/cfn-lint \ - --extra " --info --config-file .github/scripts/samples-linters/.cfnlintrc.yml" \ - --skip ".github/scripts/samples-linters/ignore-list/cloudformation" -vv From 990500d199a8dcde6e32452e00ab6b8442a69b14 Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Mon, 14 Sep 2026 10:05:12 +0100 Subject: [PATCH 4/8] fix: remove training ')' --- .../query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/query.rego b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/query.rego index 4186c969340..85f8c77035d 100644 --- a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/query.rego +++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/query.rego @@ -82,16 +82,16 @@ prepare_issue(val1, val2) = issue { } else = issue { val2 == "not defined" issue := { - "kav": sprintf("resource with type 'Microsoft.Storage/storageAccounts' publicNetworkAccess is set to '%s')", [val1]), + "kav": sprintf("resource with type 'Microsoft.Storage/storageAccounts' publicNetworkAccess is set to '%s'", [val1]), "sk": ".properties.publicNetworkAccess", "sl": ["properties", "publicNetworkAccess"], "issueType": "IncorrectValue" } } else = issue { issue := { - "kav": sprintf("resource with type 'Microsoft.Storage/storageAccounts' networkAcls.defaultAction is set to '%s')", [val2]), + "kav": sprintf("resource with type 'Microsoft.Storage/storageAccounts' networkAcls.defaultAction is set to '%s'", [val2]), "sk": ".properties.networkAcls", "sl": ["properties", "networkAcls"], "issueType": "IncorrectValue" } -} \ No newline at end of file +} From ca15394e7ef5d76d116a67c8ded89214eebf385a Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Mon, 14 Sep 2026 11:27:52 +0100 Subject: [PATCH 5/8] update: positive expected results with new query actual and expected values --- e2e/fixtures/E2E_CLI_091_RESULT.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/fixtures/E2E_CLI_091_RESULT.json b/e2e/fixtures/E2E_CLI_091_RESULT.json index 61f11420718..c12035900ad 100644 --- a/e2e/fixtures/E2E_CLI_091_RESULT.json +++ b/e2e/fixtures/E2E_CLI_091_RESULT.json @@ -116,7 +116,7 @@ "search_line": 7, "search_value": "", "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'alertNotifications.state' property set to 'On'", - "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'Off'" + "actual_value": "resource with type 'Microsoft.Security/securityContacts' has 'alertNotifications.state' property set to 'Off'" }, { "file_name": "test\\fixtures\\bicep_test\\test\\positive12.bicep", @@ -168,7 +168,7 @@ "search_line": 11, "search_value": "", "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'notificationsByRole.state' property set to 'On'", - "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'Off'" + "actual_value": "resource with type 'Microsoft.Security/securityContacts' has 'notificationsByRole.state' property set to 'Off'" }, { "file_name": "test\\fixtures\\bicep_test\\test\\positive1.bicep", @@ -181,7 +181,7 @@ "search_line": 7, "search_value": "", "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'alertNotifications.state' property set to 'On'", - "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'Off'" + "actual_value": "resource with type 'Microsoft.Security/securityContacts' has 'alertNotifications.state' property set to 'Off'" }, { "file_name": "test\\fixtures\\bicep_test\\test\\positive5.bicep", @@ -194,7 +194,7 @@ "search_line": 11, "search_value": "", "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'notificationsByRole.state' property set to 'On'", - "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'Off'" + "actual_value": "resource with type 'Microsoft.Security/securityContacts' has 'notificationsByRole.state' property set to 'Off'" } ] } From d273af84d4d70ada8de58eb182c190323fbc39e8 Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Fri, 2 Oct 2026 15:51:07 +0100 Subject: [PATCH 6/8] refactor: cloudformation queries with previous actual reverted expected value --- .../aws/amplify_app_access_token_exposed/query.rego | 4 ++-- .../amplify_app_basic_auth_config_password_exposed/query.rego | 4 ++-- .../aws/amplify_app_oauth_token_exposed/query.rego | 4 ++-- .../query.rego | 4 ++-- .../directory_service_simple_ad_password_exposed/query.rego | 4 ++-- .../query.rego | 4 ++-- .../aws/dms_endpoint_password_exposed/query.rego | 4 ++-- .../aws/docdb_cluster_master_password_in_plaintext/query.rego | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego index a93bb8c28d9..b3a86ff7f1e 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_access_token_exposed/query.rego @@ -49,7 +49,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.AccessToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.AccessToken is defined as a plaintext value", [key]), } } @@ -74,7 +74,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.AccessToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.AccessToken must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.AccessToken is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego index c7341b6ef0d..63657d9f1fa 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_basic_auth_config_password_exposed/query.rego @@ -50,7 +50,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } @@ -76,7 +76,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego index ca958f9ba60..409c9b3abeb 100644 --- a/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_app_oauth_token_exposed/query.rego @@ -48,7 +48,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.OauthToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.OauthToken is defined as a plaintext value", [key]), } } @@ -73,7 +73,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.OauthToken", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.OauthToken must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.OauthToken is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego b/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego index f5b3463d946..9b5ed703ec4 100644 --- a/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/amplify_branch_basic_auth_config_password_exposed/query.rego @@ -50,7 +50,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } @@ -75,7 +75,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.BasicAuthConfig.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.BasicAuthConfig.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego b/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego index d1808217381..941a8c946a2 100644 --- a/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/directory_service_simple_ad_password_exposed/query.rego @@ -46,7 +46,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } @@ -72,7 +72,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego b/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego index 389db261147..826d3c6540d 100644 --- a/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/dms_endpoint_mongo_db_settings_password_exposed/query.rego @@ -46,7 +46,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.MongoDbSettings.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password is defined as a plaintext value", [key]), } } @@ -72,7 +72,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.MongoDbSettings.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.MongoDbSettings.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego b/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego index c9b1329fb75..6fa3eb0b9a3 100644 --- a/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego +++ b/assets/queries/cloudFormation/aws/dms_endpoint_password_exposed/query.rego @@ -46,7 +46,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } @@ -72,7 +72,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.Password", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.Password must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.Password must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.Password is defined as a plaintext value", [key]), } } diff --git a/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego b/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego index a54ef581f9c..7ffa5000713 100644 --- a/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego +++ b/assets/queries/cloudFormation/aws/docdb_cluster_master_password_in_plaintext/query.rego @@ -47,7 +47,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.MasterUserPassword", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword is defined as a plaintext value", [key]), } } @@ -72,7 +72,7 @@ CxPolicy[result] { "resourceName": cf_lib.get_resource_name(resource, key), "searchKey": sprintf("Resources.%s.Properties.MasterUserPassword", [key]), "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must not be in plain text string", [key]), + "keyExpectedValue": sprintf("Resources.%s.Properties.MasterUserPassword must be defined as a parameter or have a secret manager referenced", [key]), "keyActualValue": sprintf("Resources.%s.Properties.MasterUserPassword is defined as a plaintext value", [key]), } } From 9a0bceb3d9a8ef9c7862e24a3f2b18121fa0405b Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Fri, 2 Oct 2026 15:59:52 +0100 Subject: [PATCH 7/8] add: missing transition to the query which we added searchLine to --- assets/similarityID_transition/terraform_aws.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/similarityID_transition/terraform_aws.yaml b/assets/similarityID_transition/terraform_aws.yaml index 55c0b0ff573..dfe03b99bb9 100644 --- a/assets/similarityID_transition/terraform_aws.yaml +++ b/assets/similarityID_transition/terraform_aws.yaml @@ -71,3 +71,7 @@ similarityIDChangeList: queryName: EFS Volume With Disabled Transit Encryption observations: "Changed search line to account with multiple Volume cases" change: 1 + - queryId: 0b93729a-d882-4803-bdc3-ac429a21f158 + queryName: EC2 Instance Using API Keys + observations: "Added searchLine to the query" + change: 4 From 9646705e225a792c6ca6cc870a421fdf9d8aa5bf Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Fri, 2 Oct 2026 17:51:31 +0100 Subject: [PATCH 8/8] refactor: terraform analog query and validate cfn samples to analyse only changed or added samples per PR --- .github/workflows/validate-cfn-samples.yml | 16 +++++++++++++++- .../query.rego | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/validate-cfn-samples.yml b/.github/workflows/validate-cfn-samples.yml index 7c6ea0efa6d..2ba59f906f0 100644 --- a/.github/workflows/validate-cfn-samples.yml +++ b/.github/workflows/validate-cfn-samples.yml @@ -22,6 +22,16 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + fetch-depth: 0 + - name: Detect changed cloudformation samples + uses: step-security/paths-filter@5c5241b8233e77b55b9046daf88f1cb7560281de # v4.0.1 + id: filter + with: + list-files: json + filters: | + samples: + - "assets/queries/cloudFormation/**/test/*.yaml" + - "assets/queries/cloudFormation/**/test/*.json" - name: Setup python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: @@ -32,11 +42,15 @@ jobs: run: | pip config set global.index-url "https://:${ECHO_LIBRARIES_ACCESS_KEY}@pypi.echohq.com/simple" pip3 install -U cfn-lint --user - - name: Validate cloudformation template samples + - name: Validate changed cloudformation template samples + env: + CHANGED_SAMPLES: ${{ steps.filter.outputs.samples_files }} run: | + echo "${CHANGED_SAMPLES}" > "${RUNNER_TEMP}/changed-cfn-samples.json" python3 -u .github/scripts/samples-linters/validate-syntax.py \ "assets/queries/cloudFormation/**/test/*.yaml" \ "assets/queries/cloudFormation/**/test/*.json" \ + --diff "${RUNNER_TEMP}/changed-cfn-samples.json" \ --linter /home/runner/.local/bin/cfn-lint \ --extra " --info --config-file .github/scripts/samples-linters/.cfnlintrc.yml" \ --skip ".github/scripts/samples-linters/ignore-list/cloudformation" \ diff --git a/assets/queries/terraform/aws/api_gateway_without_security_policy/query.rego b/assets/queries/terraform/aws/api_gateway_without_security_policy/query.rego index 22a03de450b..5e4e1227ad2 100644 --- a/assets/queries/terraform/aws/api_gateway_without_security_policy/query.rego +++ b/assets/queries/terraform/aws/api_gateway_without_security_policy/query.rego @@ -15,7 +15,7 @@ CxPolicy[result] { "searchKey": sprintf("aws_api_gateway_domain_name[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "aws_api_gateway_domain_name", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("aws_api_gateway_domain_name[%s].security_policy should be set", [name]), + "keyExpectedValue": sprintf("aws_api_gateway_domain_name[%s].security_policy should be set to TLS_1_2", [name]), "keyActualValue": sprintf("aws_api_gateway_domain_name[%s].security_policy is undefined", [name]), "remediation": "security_policy = \"TLS_1_2\"", "remediationType": "addition",