From 878623cd0c7889615d6601c1174d015880ad4474 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Tue, 22 Oct 2024 16:40:30 +0600 Subject: [PATCH 1/5] fix(checks): handle of unresolvable values Signed-off-by: Nikita Pivkin --- Makefile | 22 ++++++++-- .../aws/apigateway/enable_access_logging.rego | 11 +++-- checks/cloud/aws/apigateway/enable_cache.rego | 7 +++- .../apigateway/enable_cache_encryption.rego | 7 +++- .../cloud/aws/apigateway/enable_tracing.rego | 7 +++- .../aws/apigateway/no_public_access.rego | 14 +++++-- .../aws/athena/enable_at_rest_encryption.rego | 11 ++--- .../cloud/aws/cloudfront/enable_logging.rego | 7 +++- checks/cloud/aws/cloudfront/enable_waf.rego | 8 +++- .../cloudtrail/encryption_customer_key.rego | 7 +++- .../ensure_cloudwatch_integration.rego | 7 +++- .../cloudwatch/log_group_customer_key.rego | 7 +++- .../aws/documentdb/enable_log_export.rego | 7 ++++ .../documentdb/enable_log_export_test.rego | 5 +++ .../documentdb/encryption_customer_key.rego | 9 +++-- .../dynamodb/enable_at_rest_encryption.rego | 15 ++++++- .../cloud/aws/dynamodb/enable_recovery.rego | 23 ++++++++--- .../aws/dynamodb/table_customer_key.rego | 25 ++++++++---- .../add_description_to_security_group.rego | 7 +++- ...dd_description_to_security_group_rule.rego | 7 +++- .../aws/ec2/as_enforce_http_token_imds.rego | 17 +++++--- .../aws/ec2/encryption_customer_key.rego | 7 +++- .../aws/ec2/enforce_http_token_imds.rego | 13 ++++-- .../aws/ec2/enforce_http_token_imds_test.rego | 9 +++++ .../require_vpc_flow_logs_for_all_vpcs.rego | 14 ++++++- .../aws/ecr/repository_customer_key.rego | 15 ++++--- checks/cloud/aws/eks/encrypt_secrets.rego | 15 ++++--- .../add_description_for_security_group.rego | 7 +++- .../elasticache/enable_backup_retention.rego | 6 ++- checks/cloud/aws/iam/no_password_reuse.rego | 4 +- .../aws/iam/remove_expired_certificates.rego | 4 +- .../aws/iam/set_minimum_password_length.rego | 9 ++++- .../kinesis/enable_in_transit_encryption.rego | 25 ++++++++++-- checks/cloud/aws/kms/auto_rotate_keys.rego | 20 ++++++++-- .../cloud/aws/lambda/restrict_source_arn.rego | 14 ++++++- checks/cloud/aws/mq/enable_audit_logging.rego | 15 +++++-- .../cloud/aws/mq/enable_general_logging.rego | 14 ++++++- .../aws/neptune/encryption_customer_key.rego | 8 +++- .../aws/rds/encrypt_cluster_storage_data.rego | 15 ++++--- .../rds/encrypt_instance_storage_data.rego | 13 ++++-- ...ance_insights_encryption_customer_key.rego | 8 +++- .../aws/rds/specify_backup_retention.rego | 10 +++-- .../add_description_to_security_group.rego | 8 +++- .../aws/redshift/encryption_customer_key.rego | 16 +++++--- checks/cloud/aws/redshift/use_vpc.rego | 8 +++- .../cloud/aws/s3/encryption_customer_key.rego | 17 ++++++-- .../aws/sam/enable_api_access_logging.rego | 11 ++++- .../sam/enable_http_api_access_logging.rego | 11 ++++- .../aws/sns/enable_topic_encryption.rego | 11 ++++- .../aws/sns/enable_topic_encryption_test.rego | 6 +++ .../aws/sqs/enable_queue_encryption.rego | 14 ++++++- .../aws/ssm/secret_use_customer_key.rego | 8 +++- .../account_identity_registered.rego | 7 +++- .../container/configured_network_policy.rego | 7 +++- .../azure/database/no_public_access.rego | 8 ++-- .../azure/database/retention_period_set.rego | 6 ++- .../keyvault/content_type_for_secret.rego | 8 +++- .../azure/network/retention_policy_set.rego | 4 +- .../set_required_contact_details.rego | 9 +++-- .../actions/no_plain_text_action_secrets.rego | 4 +- .../compute/disk_encryption_customer_key.rego | 7 +++- .../compute/no_default_service_account.rego | 7 +--- .../vm_disk_encryption_customer_key.rego | 7 +++- .../google/gke/no_legacy_authentication.rego | 6 ++- .../cloud/google/gke/use_service_account.rego | 17 +++++--- ...ns_on_workload_identity_pool_provider.rego | 8 +++- .../sql/enable_pg_temp_file_logging.rego | 5 ++- .../google/sql/encrypt_in_transit_data.rego | 4 +- .../bucket_encryption_customer_key.rego | 14 ++++++- .../add_description_to_security_group.rego | 8 +++- ...dd_description_to_security_group_rule.rego | 14 ++++++- .../add_security_group_to_instance.rego | 8 +++- ...add_description_to_nas_security_group.rego | 8 +++- .../network/add_security_group_to_router.rego | 8 +++- .../add_security_group_to_vpn_gateway.rego | 8 +++- .../add_description_to_db_security_group.rego | 8 +++- .../rdb/specify_backup_retention.rego | 4 +- .../openstack/compute/no_public_access.rego | 6 ++- .../add_description_to_security_group.rego | 10 ++++- lib/cloud/value.rego | 40 +++++++++++++++++++ 80 files changed, 647 insertions(+), 188 deletions(-) create mode 100644 lib/cloud/value.rego diff --git a/Makefile b/Makefile index e6c528cd..3e09184a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ DYNAMIC_REGO_FOLDER=./checks/kubernetes/policies/dynamic +BUNDLE_FILE=bundle.tar.gz +REGISTRY_PORT=5111 .PHONY: test test: @@ -44,9 +46,23 @@ create-bundle: .PHONY: verify-bundle verify-bundle: - cp bundle.tar.gz scripts/bundle.tar.gz + cp $(BUNDLE_FILE) scripts/$(BUNDLE_FILE) cd scripts && go run verify-bundle.go - rm scripts/bundle.tar.gz + rm scripts/$(BUNDLE_FILE) build-opa: - go build ./cmd/opa \ No newline at end of file + go build ./cmd/opa + +start-registry: + docker run --rm -it -d -p ${REGISTRY_PORT}:5000 --name registry registry:2 + +stop-registry: + docker stop registry + +push-bundle: create-bundle + @REPO=localhost:${REGISTRY_PORT}/trivy-checks:latest ;\ + echo "Pushing to repository: $$REPO" ;\ + docker run --rm -it --net=host -v $$PWD/${BUNDLE_FILE}:/${BUNDLE_FILE} bitnami/oras:latest push \ + $$REPO \ + --config "/dev/null:application/vnd.cncf.openpolicyagent.config.v1+json" \ + "$(BUNDLE_FILE):application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip" diff --git a/checks/cloud/aws/apigateway/enable_access_logging.rego b/checks/cloud/aws/apigateway/enable_access_logging.rego index 11e1c61d..17da53cc 100644 --- a/checks/cloud/aws/apigateway/enable_access_logging.rego +++ b/checks/cloud/aws/apigateway/enable_access_logging.rego @@ -34,10 +34,11 @@ package builtin.aws.apigateway.aws0001 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some stage in input.aws.apigateway.v1.apis[_].stages - not logging_is_configured(stage) + logging_is_not_configured(stage) res := result.new( "Access logging is not configured.", metadata.obj_by_path(stage, ["accesslogging", "cloudwatchloggrouparn"]), @@ -46,14 +47,16 @@ deny contains res if { deny contains res if { some stage in input.aws.apigateway.v2.apis[_].stages - not logging_is_configured(stage) + logging_is_not_configured(stage) res := result.new( "Access logging is not configured.", metadata.obj_by_path(stage, ["accesslogging", "cloudwatchloggrouparn"]), ) } -logging_is_configured(stage) if { +logging_is_not_configured(stage) if { isManaged(stage) - stage.accesslogging.cloudwatchloggrouparn.value != "" + value.is_empty(stage.accesslogging.cloudwatchloggrouparn) } + +logging_is_not_configured(stage) if not stage.accesslogging.cloudwatchloggrouparn diff --git a/checks/cloud/aws/apigateway/enable_cache.rego b/checks/cloud/aws/apigateway/enable_cache.rego index 6cd4d742..885f1200 100644 --- a/checks/cloud/aws/apigateway/enable_cache.rego +++ b/checks/cloud/aws/apigateway/enable_cache.rego @@ -31,6 +31,7 @@ package builtin.aws.apigateway.aws0190 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some api in input.aws.apigateway.v1.apis @@ -39,9 +40,13 @@ deny contains res if { isManaged(stage) some settings in stage.restmethodsettings isManaged(settings) - not settings.cacheenabled.value + cache_is_not_enabled(settings) res := result.new( "Cache data is not enabled.", metadata.obj_by_path(settings, ["cacheenabled"]), ) } + +cache_is_not_enabled(settings) if value.is_false(settings.cacheenabled) + +cache_is_not_enabled(settings) if not settings.cacheenabled diff --git a/checks/cloud/aws/apigateway/enable_cache_encryption.rego b/checks/cloud/aws/apigateway/enable_cache_encryption.rego index ed5d19e8..0072e8fd 100644 --- a/checks/cloud/aws/apigateway/enable_cache_encryption.rego +++ b/checks/cloud/aws/apigateway/enable_cache_encryption.rego @@ -29,6 +29,7 @@ package builtin.aws.apigateway.aws0002 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some api in input.aws.apigateway.v1.apis @@ -38,10 +39,14 @@ deny contains res if { some settings in stage.restmethodsettings isManaged(settings) settings.cacheenabled.value - not settings.cachedataencrypted.value + cache_is_not_encrypted(settings) res := result.new( "Cache data is not encrypted.", metadata.obj_by_path(settings, ["cachedataencrypted"]), ) } + +cache_is_not_encrypted(settings) if value.is_false(settings.cachedataencrypted) + +cache_is_not_encrypted(settings) if not settings.cachedataencrypted diff --git a/checks/cloud/aws/apigateway/enable_tracing.rego b/checks/cloud/aws/apigateway/enable_tracing.rego index f3e4bff8..798b500f 100644 --- a/checks/cloud/aws/apigateway/enable_tracing.rego +++ b/checks/cloud/aws/apigateway/enable_tracing.rego @@ -29,15 +29,20 @@ package builtin.aws.apigateway.aws0003 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some api in input.aws.apigateway.v1.apis isManaged(api) some stage in api.stages isManaged(stage) - not stage.xraytracingenabled.value + tracing_is_not_enabled(stage) res := result.new( "X-Ray tracing is not enabled.", metadata.obj_by_path(stage, ["xraytracingenabled"]), ) } + +tracing_is_not_enabled(stage) if value.is_false(stage.xraytracingenabled) + +tracing_is_not_enabled(stage) if not stage.xraytracingenabled diff --git a/checks/cloud/aws/apigateway/no_public_access.rego b/checks/cloud/aws/apigateway/no_public_access.rego index fad776c7..71800d85 100644 --- a/checks/cloud/aws/apigateway/no_public_access.rego +++ b/checks/cloud/aws/apigateway/no_public_access.rego @@ -28,18 +28,24 @@ package builtin.aws.apigateway.aws0004 import rego.v1 +import data.lib.cloud.value + authorization_none := "NONE" deny contains res if { some api in input.aws.apigateway.v1.apis isManaged(api) some method in api.resources[_].methods - not method_is_option(method) - not is_apikey_required(api) + method_is_not_option(method) + apikey_is_not_required(api) method.authorizationtype.value == authorization_none res := result.new("Authorization is not enabled for this method.", method.authorizationtype) } -method_is_option(method) := method.httpmethod.value == "OPTION" +method_is_not_option(method) if value.is_not_equal(method.httpmethod, "OPTION") + +method_is_not_option(method) if not method.httpmethod + +apikey_is_not_required(api) if value.is_false(api.apikeyrequired) -is_apikey_required(api) := api.apikeyrequired.value +apikey_is_not_required(api) if not api.apikeyrequired diff --git a/checks/cloud/aws/athena/enable_at_rest_encryption.rego b/checks/cloud/aws/athena/enable_at_rest_encryption.rego index 46d44ddd..4a5afb1c 100644 --- a/checks/cloud/aws/athena/enable_at_rest_encryption.rego +++ b/checks/cloud/aws/athena/enable_at_rest_encryption.rego @@ -35,12 +35,13 @@ package builtin.aws.athena.aws0006 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value encryption_type_none := "" deny contains res if { some workgroup in input.aws.athena.workgroups - not is_encrypted(workgroup) + not_encrypted(workgroup) res := result.new( "Workgroup does not have encryption configured.", metadata.obj_by_path(workgroup, ["encryption", "type"]), @@ -49,13 +50,13 @@ deny contains res if { deny contains res if { some database in input.aws.athena.databases - not is_encrypted(database) + not_encrypted(database) res := result.new( "Database does not have encryption configured.", metadata.obj_by_path(database, ["encryption", "type"]), ) } -is_encrypted(obj) if { - obj.encryption.type.value != encryption_type_none -} +not_encrypted(encryptable) if value.is_equal(encryptable.encryption.type, encryption_type_none) + +not_encrypted(encryptable) if not encryptable.encryption.type diff --git a/checks/cloud/aws/cloudfront/enable_logging.rego b/checks/cloud/aws/cloudfront/enable_logging.rego index 4c39ef09..814dccd6 100644 --- a/checks/cloud/aws/cloudfront/enable_logging.rego +++ b/checks/cloud/aws/cloudfront/enable_logging.rego @@ -34,14 +34,17 @@ package builtin.aws.cloudfront.aws0010 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some dist in input.aws.cloudfront.distributions - not has_logging_bucket(dist) + without_logging_bucket(dist) res := result.new( "Distribution does not have logging enabled", metadata.obj_by_path(dist, ["logging", "bucket"]), ) } -has_logging_bucket(dist) := dist.logging.bucket.value != "" +without_logging_bucket(dist) if value.is_empty(dist.logging.bucket) + +without_logging_bucket(dist) if not dist.logging.bucket diff --git a/checks/cloud/aws/cloudfront/enable_waf.rego b/checks/cloud/aws/cloudfront/enable_waf.rego index c34cbe62..0488b452 100644 --- a/checks/cloud/aws/cloudfront/enable_waf.rego +++ b/checks/cloud/aws/cloudfront/enable_waf.rego @@ -33,13 +33,17 @@ package builtin.aws.cloudfront.aws0011 import rego.v1 +import data.lib.cloud.value + deny contains res if { some dist in input.aws.cloudfront.distributions - not is_waf_enabled(dist) + waf_not_enabled(dist) res := result.new( "Distribution does not utilise a WAF.", object.get(dist, "wafid", dist), ) } -is_waf_enabled(dist) := dist.wafid.value != "" +waf_not_enabled(dist) if value.is_empty(dist.wafid) + +waf_not_enabled(dist) if not dist.wafid diff --git a/checks/cloud/aws/cloudtrail/encryption_customer_key.rego b/checks/cloud/aws/cloudtrail/encryption_customer_key.rego index c5b586fe..fadaa292 100644 --- a/checks/cloud/aws/cloudtrail/encryption_customer_key.rego +++ b/checks/cloud/aws/cloudtrail/encryption_customer_key.rego @@ -37,14 +37,17 @@ package builtin.aws.cloudtrail.aws0015 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some trail in input.aws.cloudtrail.trails - not use_cms(trail) + without_cmk(trail) res := result.new( "CloudTrail does not use a customer managed key to encrypt the logs.", metadata.obj_by_path(trail, ["kmskeyid"]), ) } -use_cms(trail) if trail.kmskeyid.value != "" +without_cmk(trail) if value.is_empty(trail.kmskeyid) + +without_cmk(trail) if not trail.kmskeyid diff --git a/checks/cloud/aws/cloudtrail/ensure_cloudwatch_integration.rego b/checks/cloud/aws/cloudtrail/ensure_cloudwatch_integration.rego index a587c494..05388f6c 100644 --- a/checks/cloud/aws/cloudtrail/ensure_cloudwatch_integration.rego +++ b/checks/cloud/aws/cloudtrail/ensure_cloudwatch_integration.rego @@ -47,14 +47,17 @@ package builtin.aws.cloudtrail.aws0162 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some trail in input.aws.cloudtrail.trails - not is_logging_configured(trail) + logging_is_not_configured(trail) res := result.new( "Trail does not have CloudWatch logging configured", metadata.obj_by_path(trail, ["cloudwatchlogsloggrouparn"]), ) } -is_logging_configured(trail) if trail.cloudwatchlogsloggrouparn.value != "" +logging_is_not_configured(trail) if value.is_empty(trail.cloudwatchlogsloggrouparn) + +logging_is_not_configured(trail) if not trail.cloudwatchlogsloggrouparn diff --git a/checks/cloud/aws/cloudwatch/log_group_customer_key.rego b/checks/cloud/aws/cloudwatch/log_group_customer_key.rego index e128b4a8..8708763b 100644 --- a/checks/cloud/aws/cloudwatch/log_group_customer_key.rego +++ b/checks/cloud/aws/cloudwatch/log_group_customer_key.rego @@ -34,14 +34,17 @@ package builtin.aws.cloudwatch.aws0017 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some group in input.aws.cloudwatch.loggroups - not has_cms(group) + without_cmk(group) res := result.new( "Log group is not encrypted.", metadata.obj_by_path(group, ["kmskeyid"]), ) } -has_cms(group) if group.kmskeyid.value != "" +without_cmk(group) if value.is_empty(group.kmskeyid) + +without_cmk(group) if not group.kmskeyid diff --git a/checks/cloud/aws/documentdb/enable_log_export.rego b/checks/cloud/aws/documentdb/enable_log_export.rego index 041166a0..659f33ca 100644 --- a/checks/cloud/aws/documentdb/enable_log_export.rego +++ b/checks/cloud/aws/documentdb/enable_log_export.rego @@ -33,6 +33,8 @@ package builtin.aws.documentdb.aws0020 import rego.v1 +import data.lib.cloud.value + log_export_audit := "audit" log_export_profiler := "profiler" @@ -47,3 +49,8 @@ export_audit_or_profiler(cluster) if { some log in cluster.enabledlogexports log.value in [log_export_audit, log_export_profiler] } + +export_audit_or_profiler(cluster) if { + some log in cluster.enabledlogexports + value.is_unresolvable(log) +} diff --git a/checks/cloud/aws/documentdb/enable_log_export_test.rego b/checks/cloud/aws/documentdb/enable_log_export_test.rego index 95cb64a1..02154706 100644 --- a/checks/cloud/aws/documentdb/enable_log_export_test.rego +++ b/checks/cloud/aws/documentdb/enable_log_export_test.rego @@ -24,3 +24,8 @@ test_allow_export_mixed if { inp := {"aws": {"documentdb": {"clusters": [{"enabledlogexports": [{"value": "audit"}, {"value": "profiler"}]}]}}} test.assert_empty(check.deny) with input as inp } + +test_allow_export_mixed_with_unresolvable if { + inp := {"aws": {"documentdb": {"clusters": [{"enabledlogexports": [{"value": "foo"}, {"value": "bar", "unresolvable": true}]}]}}} + test.assert_empty(check.deny) with input as inp +} diff --git a/checks/cloud/aws/documentdb/encryption_customer_key.rego b/checks/cloud/aws/documentdb/encryption_customer_key.rego index 0c58ecb1..0778ae7f 100644 --- a/checks/cloud/aws/documentdb/encryption_customer_key.rego +++ b/checks/cloud/aws/documentdb/encryption_customer_key.rego @@ -34,11 +34,12 @@ package builtin.aws.documentdb.aws0022 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some cluster in input.aws.documentdb.clusters isManaged(cluster) - not has_cms(cluster) + without_cmk(cluster) res := result.new( "Cluster encryption does not use a customer-managed KMS key.", metadata.obj_by_path(cluster, ["kmskeyid"]), @@ -49,11 +50,13 @@ deny contains res if { some cluster in input.aws.documentdb.clusters some instance in cluster.instances isManaged(instance) - not has_cms(instance) + without_cmk(instance) res := result.new( "Instance encryption does not use a customer-managed KMS key.", metadata.obj_by_path(instance, ["kmskeyid"]), ) } -has_cms(obj) if obj.kmskeyid.value != "" +without_cmk(obj) if value.is_empty(obj.kmskeyid) + +without_cmk(obj) if not obj.kmskeyid diff --git a/checks/cloud/aws/dynamodb/enable_at_rest_encryption.rego b/checks/cloud/aws/dynamodb/enable_at_rest_encryption.rego index db6c7463..7415b02c 100644 --- a/checks/cloud/aws/dynamodb/enable_at_rest_encryption.rego +++ b/checks/cloud/aws/dynamodb/enable_at_rest_encryption.rego @@ -34,8 +34,19 @@ package builtin.aws.dynamodb.aws0023 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.dynamodb.daxclusters - cluster.serversideencryption.enabled.value == false - res := result.new("DAX encryption is not enabled.", cluster.serversideencryption.enabled) + not_encrypted(cluster) + + res := result.new( + "DAX encryption is not enabled.", + metadata.obj_by_path(cluster, ["serversideencryption", "enabled"]), + ) } + +not_encrypted(cluster) if value.is_false(cluster.serversideencryption.enabled) + +not_encrypted(cluster) if not cluster.serversideencryption.enabled diff --git a/checks/cloud/aws/dynamodb/enable_recovery.rego b/checks/cloud/aws/dynamodb/enable_recovery.rego index 3e19dca2..19bcdd56 100644 --- a/checks/cloud/aws/dynamodb/enable_recovery.rego +++ b/checks/cloud/aws/dynamodb/enable_recovery.rego @@ -31,16 +31,27 @@ package builtin.aws.dynamodb.aws0024 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.dynamodb.daxclusters - cluster.pointintimerecovery.value == false - - res := result.new("Point-in-time recovery is not enabled.", cluster.pointintimerecovery) + recovery_is_not_enabled(cluster) + res := result.new( + "Point-in-time recovery is not enabled.", + metadata.obj_by_path(cluster, ["pointintimerecovery"]), + ) } deny contains res if { some table in input.aws.dynamodb.tables - table.pointintimerecovery.value == false - - res := result.new("Point-in-time recovery is not enabled.", table.pointintimerecovery) + recovery_is_not_enabled(table) + res := result.new( + "Point-in-time recovery is not enabled.", + metadata.obj_by_path(table, ["pointintimerecovery"]), + ) } + +recovery_is_not_enabled(obj) if value.is_false(obj.pointintimerecovery) + +recovery_is_not_enabled(obj) if not obj.pointintimerecovery diff --git a/checks/cloud/aws/dynamodb/table_customer_key.rego b/checks/cloud/aws/dynamodb/table_customer_key.rego index a762aebc..344192ae 100644 --- a/checks/cloud/aws/dynamodb/table_customer_key.rego +++ b/checks/cloud/aws/dynamodb/table_customer_key.rego @@ -30,20 +30,31 @@ package builtin.aws.dynamodb.aws0025 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some table in input.aws.dynamodb.tables - table.serversideencryption.enabled.value == false - res := result.new("Table encryption does not use a customer-managed KMS key.", table.serversideencryption.enabled) + not_encrypted(table) + res := result.new( + "Table encryption does not use a customer-managed KMS key.", + metadata.obj_by_path(table, ["serversideencryption", "enabled"]), + ) } deny contains res if { some table in input.aws.dynamodb.tables table.serversideencryption.enabled.value - not valid_key(table.serversideencryption.kmskeyid.value) + non_valid_key(table) res := result.new("Table encryption explicitly uses the default KMS key.", table.serversideencryption.kmskeyid) } -valid_key(k) if { - k != "" - k != "alias/aws/dynamodb" -} +not_encrypted(table) if value.is_false(table.serversideencryption.enabled) + +not_encrypted(table) if not table.serversideencryption.enabled + +non_valid_key(table) if value.is_empty(table.serversideencryption.kmskeyid) + +non_valid_key(table) if value.is_equal(table.serversideencryption.kmskeyid, "alias/aws/dynamodb") + +non_valid_key(table) if not table.serversideencryption.kmskeyid diff --git a/checks/cloud/aws/ec2/add_description_to_security_group.rego b/checks/cloud/aws/ec2/add_description_to_security_group.rego index ae7d812f..1a7b8b59 100644 --- a/checks/cloud/aws/ec2/add_description_to_security_group.rego +++ b/checks/cloud/aws/ec2/add_description_to_security_group.rego @@ -39,11 +39,12 @@ package builtin.aws.ec2.aws0099 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some sg in input.aws.ec2.securitygroups isManaged(sg) - not has_description(sg) + without_description(sg) res := result.new( "Security group does not have a description.", metadata.obj_by_path(sg, ["description"]), @@ -57,4 +58,6 @@ deny contains res if { res := result.new("Security group explicitly uses the default description.", sg.description) } -has_description(sg) if sg.description.value != "" +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/checks/cloud/aws/ec2/add_description_to_security_group_rule.rego b/checks/cloud/aws/ec2/add_description_to_security_group_rule.rego index e23c8a33..463a67dc 100644 --- a/checks/cloud/aws/ec2/add_description_to_security_group_rule.rego +++ b/checks/cloud/aws/ec2/add_description_to_security_group_rule.rego @@ -39,6 +39,7 @@ package builtin.aws.ec2.aws0124 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some group in input.aws.ec2.securitygroups @@ -46,11 +47,13 @@ deny contains res if { object.get(group, "egressrules", []), object.get(group, "ingressrules", []), ) - not has_description(rule) + without_description(rule) res := result.new( "Security group rule does not have a description.", metadata.obj_by_path(rule, ["description"]), ) } -has_description(rule) if rule.description.value != "" +without_description(rule) if value.is_empty(rule.description) + +without_description(rule) if not rule.description diff --git a/checks/cloud/aws/ec2/as_enforce_http_token_imds.rego b/checks/cloud/aws/ec2/as_enforce_http_token_imds.rego index ed22174e..29da56d7 100644 --- a/checks/cloud/aws/ec2/as_enforce_http_token_imds.rego +++ b/checks/cloud/aws/ec2/as_enforce_http_token_imds.rego @@ -40,11 +40,12 @@ package builtin.aws.ec2.aws0130 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some config in input.aws.ec2.launchconfigurations - not is_tokens_required(config) - not is_endpoint_disabled(config) + tokens_is_not_required(config) + endpoint_is_not_disabled(config) res := result.new( "Launch configuration does not require IMDS access to require a token", metadata.obj_by_path(config, ["metadataoptions", "httptokens"]), @@ -53,14 +54,18 @@ deny contains res if { deny contains res if { some tpl in input.aws.ec2.launchtemplates - not is_tokens_required(tpl.instance) - not is_endpoint_disabled(tpl.instance) + tokens_is_not_required(tpl.instance) + endpoint_is_not_disabled(tpl.instance) res := result.new( "Launch template does not require IMDS access to require a token", metadata.obj_by_path(tpl.instance, ["metadataoptions", "httptokens"]), ) } -is_tokens_required(instance) if instance.metadataoptions.httptokens.value == "required" +tokens_is_not_required(instance) if value.is_not_equal(instance.metadataoptions.httptokens, "required") -is_endpoint_disabled(instance) if instance.metadataoptions.httpendpoint.value == "disabled" +tokens_is_not_required(instance) if not instance.metadataoptions.httptokens + +endpoint_is_not_disabled(instance) if value.is_not_equal(instance.metadataoptions.httpendpoint, "disabled") + +endpoint_is_not_disabled(instance) if not instance.metadataoptions.httpendpoint diff --git a/checks/cloud/aws/ec2/encryption_customer_key.rego b/checks/cloud/aws/ec2/encryption_customer_key.rego index 2fc2cae7..596bd384 100644 --- a/checks/cloud/aws/ec2/encryption_customer_key.rego +++ b/checks/cloud/aws/ec2/encryption_customer_key.rego @@ -36,15 +36,18 @@ package builtin.aws.ec2.aws0027 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some volume in input.aws.ec2.volumes isManaged(volume) - not has_cms(volume) + without_cmk(volume) res := result.new( "EBS volume does not use a customer-managed KMS key.", metadata.obj_by_path(volume, ["encryption", "kmskeyid"]), ) } -has_cms(volume) if volume.encryption.kmskeyid.value != "" +without_cmk(volume) if value.is_empty(volume.encryption.kmskeyid) + +without_cmk(volume) if not volume.encryption.kmskeyid diff --git a/checks/cloud/aws/ec2/enforce_http_token_imds.rego b/checks/cloud/aws/ec2/enforce_http_token_imds.rego index b8cdc172..821d6fe2 100644 --- a/checks/cloud/aws/ec2/enforce_http_token_imds.rego +++ b/checks/cloud/aws/ec2/enforce_http_token_imds.rego @@ -35,17 +35,22 @@ package builtin.aws.ec2.aws0028 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some instance in input.aws.ec2.instances - not is_tokens_required(instance) - not is_endpoint_disabled(instance) + tokens_is_not_required(instance) + endpoint_is_not_disabled(instance) res := result.new( "Instance does not require IMDS access to require a token.", metadata.obj_by_path(instance, ["metadataoptions", "httptokens"]), ) } -is_tokens_required(instance) if instance.metadataoptions.httptokens.value == "required" +tokens_is_not_required(instance) if value.is_not_equal(instance.metadataoptions.httptokens, "required") -is_endpoint_disabled(instance) if instance.metadataoptions.httpendpoint.value == "disabled" +tokens_is_not_required(instance) if not instance.metadataoptions.httptokens + +endpoint_is_not_disabled(instance) if value.is_not_equal(instance.metadataoptions.httpendpoint, "disabled") + +endpoint_is_not_disabled(instance) if not instance.metadataoptions.httpendpoint diff --git a/checks/cloud/aws/ec2/enforce_http_token_imds_test.rego b/checks/cloud/aws/ec2/enforce_http_token_imds_test.rego index 919d8d92..d2ea6602 100644 --- a/checks/cloud/aws/ec2/enforce_http_token_imds_test.rego +++ b/checks/cloud/aws/ec2/enforce_http_token_imds_test.rego @@ -33,3 +33,12 @@ test_allow_instance_with_endpoint_disabled if { } build_input(meta_opts) := {"aws": {"ec2": {"instances": [{"metadataoptions": meta_opts}]}}} + +test_allow_instance_with_tokens_unresolvable if { + inp := build_input({ + "httptokens": {"value": "", "unresolvable": true}, + "httpendpoint": {"value": "enabled"}, + }) + + test.assert_empty(check.deny) with input as inp +} diff --git a/checks/cloud/aws/ec2/require_vpc_flow_logs_for_all_vpcs.rego b/checks/cloud/aws/ec2/require_vpc_flow_logs_for_all_vpcs.rego index a01bdace..b9b5ab53 100644 --- a/checks/cloud/aws/ec2/require_vpc_flow_logs_for_all_vpcs.rego +++ b/checks/cloud/aws/ec2/require_vpc_flow_logs_for_all_vpcs.rego @@ -27,8 +27,18 @@ package builtin.aws.ec2.aws0178 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some vpc in input.aws.ec2.vpcs - vpc.flowlogsenabled.value == false - res := result.new("VPC does not have VPC Flow Logs enabled.", vpc.flowlogsenabled) + logs_disabled(vpc) + res := result.new( + "VPC does not have VPC Flow Logs enabled.", + metadata.obj_by_path(vpc, ["flowlogsenabled"]), + ) } + +logs_disabled(vpc) if value.is_false(vpc.flowlogsenabled) + +logs_disabled(vpc) if not vpc.flowlogsenabled diff --git a/checks/cloud/aws/ecr/repository_customer_key.rego b/checks/cloud/aws/ecr/repository_customer_key.rego index a45aca9c..2bdfe078 100644 --- a/checks/cloud/aws/ecr/repository_customer_key.rego +++ b/checks/cloud/aws/ecr/repository_customer_key.rego @@ -34,23 +34,28 @@ package builtin.aws.ecr.aws0033 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some repo in input.aws.ecr.repositories - not is_encyption_type_kms(repo.encryption.type) + encyption_type_no_kms(repo) res := result.new("Repository is not encrypted using KMS.", repo.encryption.type) } deny contains res if { some repo in input.aws.ecr.repositories - is_encyption_type_kms(repo.encryption.type) - not has_cms(repo) + repo.encryption.type.value == "KMS" + without_cmk(repo) res := result.new( "Repository encryption does not use a customer managed KMS key.", metadata.obj_by_path(repo, ["encryption", "kmskeyid"]), ) } -is_encyption_type_kms(typ) if typ.value == "KMS" +encyption_type_no_kms(repo) if value.is_not_equal(repo.encryption.type, "KMS") -has_cms(repo) if repo.encryption.kmskeyid.value != "" +encyption_type_no_kms(repo) if not repo.encryption.type + +without_cmk(repo) if value.is_empty(repo.encryption.kmskeyid) + +without_cmk(repo) if not repo.encryption.kmskeyid diff --git a/checks/cloud/aws/eks/encrypt_secrets.rego b/checks/cloud/aws/eks/encrypt_secrets.rego index d2e0811c..22e1b18c 100644 --- a/checks/cloud/aws/eks/encrypt_secrets.rego +++ b/checks/cloud/aws/eks/encrypt_secrets.rego @@ -34,10 +34,11 @@ package builtin.aws.eks.aws0039 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some cluster in input.aws.eks.clusters - not secret_encryption_enabled(cluster) + secret_encryption_not_enabled(cluster) res := result.new( "Cluster does not have secret encryption enabled.", metadata.obj_by_path(cluster, ["encryption", "secrets"]), @@ -46,14 +47,18 @@ deny contains res if { deny contains res if { some cluster in input.aws.eks.clusters - secret_encryption_enabled(cluster) - not has_cms(cluster) + cluster.encryption.secrets.value + without_cmk(cluster) res := result.new( "Cluster encryption requires a KMS key ID, which is missing", metadata.obj_by_path(cluster, ["encryption", "kmskeyid"]), ) } -secret_encryption_enabled(cluster) if cluster.encryption.secrets.value == true +secret_encryption_not_enabled(cluster) if value.is_false(cluster.encryption.secrets) -has_cms(cluster) if cluster.encryption.kmskeyid.value != "" +secret_encryption_not_enabled(cluster) if not cluster.encryption.secrets + +without_cmk(cluster) if value.is_empty(cluster.encryption.kmskeyid) + +without_cmk(cluster) if not cluster.encryption.kmskeyid diff --git a/checks/cloud/aws/elasticache/add_description_for_security_group.rego b/checks/cloud/aws/elasticache/add_description_for_security_group.rego index 78135fdd..2b286d37 100644 --- a/checks/cloud/aws/elasticache/add_description_for_security_group.rego +++ b/checks/cloud/aws/elasticache/add_description_for_security_group.rego @@ -35,14 +35,17 @@ package builtin.aws.elasticache.aws0049 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some secgroup in input.aws.elasticache.securitygroups - not has_description(secgroup) + without_description(secgroup) res := result.new( "Security group does not have a description.", metadata.obj_by_path(secgroup, ["description"]), ) } -has_description(sg) if sg.description.value != "" +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/checks/cloud/aws/elasticache/enable_backup_retention.rego b/checks/cloud/aws/elasticache/enable_backup_retention.rego index 0a8aa6fe..7458fbcb 100644 --- a/checks/cloud/aws/elasticache/enable_backup_retention.rego +++ b/checks/cloud/aws/elasticache/enable_backup_retention.rego @@ -33,10 +33,12 @@ package builtin.aws.elasticache.aws0050 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.elasticache.clusters cluster.engine.value == "redis" - cluster.nodetype.value != "cache.t1.micro" - cluster.snapshotretentionlimit.value == 0 + value.is_not_equal(cluster.nodetype, "cache.t1.micro") + value.is_equal(cluster.snapshotretentionlimit, 0) res := result.new("Cluster snapshot retention is not enabled.", cluster.snapshotretentionlimit) } diff --git a/checks/cloud/aws/iam/no_password_reuse.rego b/checks/cloud/aws/iam/no_password_reuse.rego index c822f6d0..588b076a 100644 --- a/checks/cloud/aws/iam/no_password_reuse.rego +++ b/checks/cloud/aws/iam/no_password_reuse.rego @@ -39,9 +39,11 @@ package builtin.aws.iam.aws0056 import rego.v1 +import data.lib.cloud.value + deny contains res if { policy := input.aws.iam.passwordpolicy isManaged(policy) - policy.reusepreventioncount.value < 5 + value.less_than(policy.reusepreventioncount, 5) res := result.new("Password policy allows reuse of recent passwords.", policy) } diff --git a/checks/cloud/aws/iam/remove_expired_certificates.rego b/checks/cloud/aws/iam/remove_expired_certificates.rego index d733ce7a..2f99c9e6 100644 --- a/checks/cloud/aws/iam/remove_expired_certificates.rego +++ b/checks/cloud/aws/iam/remove_expired_certificates.rego @@ -34,9 +34,11 @@ package builtin.aws.iam.aws0168 import rego.v1 +import data.lib.cloud.value + deny contains res if { some certificate in input.aws.iam.servercertificates + not value.is_unresolvable(certificate.expiration) time.parse_rfc3339_ns(certificate.expiration.value) < time.now_ns() - res := result.new("Certificate has expired", certificate) } diff --git a/checks/cloud/aws/iam/set_minimum_password_length.rego b/checks/cloud/aws/iam/set_minimum_password_length.rego index a7d5b86c..6f0c662b 100644 --- a/checks/cloud/aws/iam/set_minimum_password_length.rego +++ b/checks/cloud/aws/iam/set_minimum_password_length.rego @@ -39,11 +39,16 @@ package builtin.aws.iam.aws0063 import rego.v1 +import data.lib.cloud.value + msg := "Password policy allows a maximum password age of greater than 90 days" deny contains res if { policy := input.aws.iam.passwordpolicy isManaged(policy) - policy.minimumlength.value < 14 - res := result.new("Password policy allows a maximum password age of greater than 90 days", policy.minimumlength) + value.less_than(policy.minimumlength, 14) + res := result.new( + "Password policy allows a maximum password age of greater than 90 days", + policy.minimumlength, + ) } diff --git a/checks/cloud/aws/kinesis/enable_in_transit_encryption.rego b/checks/cloud/aws/kinesis/enable_in_transit_encryption.rego index 5ab7e363..bf7f6d2c 100644 --- a/checks/cloud/aws/kinesis/enable_in_transit_encryption.rego +++ b/checks/cloud/aws/kinesis/enable_in_transit_encryption.rego @@ -33,15 +33,32 @@ package builtin.aws.kinesis.aws0064 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some stream in input.aws.kinesis.streams - stream.encryption.type.value != "KMS" - res := result.new("Stream does not use KMS encryption.", stream.encryption.type) + encryption_is_not_kms(stream) + res := result.new( + "Stream does not use KMS encryption.", + metadata.obj_by_path(stream, ["encryption", "type"]), + ) } +encryption_is_not_kms(stream) if value.is_not_equal(stream.encryption.type, "KMS") + +encryption_is_not_kms(stream) if not stream.encryption.type + deny contains res if { some stream in input.aws.kinesis.streams stream.encryption.type.value == "KMS" - stream.encryption.kmskeyid.value == "" - res := result.new("Stream does not use a custom-managed KMS key.", stream.encryption.kmskeyid) + without_cmk(stream) + res := result.new( + "Stream does not use a custom-managed KMS key.", + metadata.obj_by_path(stream, ["encryption", "kmskeyid"]), + ) } + +without_cmk(stream) if value.is_empty(stream.encryption.kmskeyid) + +without_cmk(stream) if not stream.encryption.kmskeyid diff --git a/checks/cloud/aws/kms/auto_rotate_keys.rego b/checks/cloud/aws/kms/auto_rotate_keys.rego index be879027..804c9333 100644 --- a/checks/cloud/aws/kms/auto_rotate_keys.rego +++ b/checks/cloud/aws/kms/auto_rotate_keys.rego @@ -30,9 +30,23 @@ package builtin.aws.kms.aws0065 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some key in input.aws.kms.keys - key.usage.value != "SIGN_VERIFY" - key.rotationenabled.value == false - res := result.new("Key does not have rotation enabled.", key.rotationenabled) + is_not_sign_key(key) + rotation_disabled(key) + res := result.new( + "Key does not have rotation enabled.", + metadata.obj_by_path(key, ["rotationenabled"]), + ) } + +is_not_sign_key(key) if value.is_not_equal(key.usage, "SIGN_VERIFY") + +is_not_sign_key(key) if not key.usage + +rotation_disabled(key) if value.is_false(key.rotationenabled) + +rotation_disabled(key) if not key.rotationenabled diff --git a/checks/cloud/aws/lambda/restrict_source_arn.rego b/checks/cloud/aws/lambda/restrict_source_arn.rego index 5cbc9c6a..f197ab8d 100644 --- a/checks/cloud/aws/lambda/restrict_source_arn.rego +++ b/checks/cloud/aws/lambda/restrict_source_arn.rego @@ -35,10 +35,20 @@ package builtin.aws.lambda.aws0067 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some func in input.aws.lambda.functions some permission in func.permissions endswith(permission.principal.value, ".amazonaws.com") - permission.sourcearn.value == "" - res := result.new("Lambda permission lacks source ARN for *.amazonaws.com principal.", permission.sourcearn) + sourcearn_is_missed(permission) + res := result.new( + "Lambda permission lacks source ARN for *.amazonaws.com principal.", + metadata.obj_by_path(permission, ["sourcearn"]), + ) } + +sourcearn_is_missed(permission) if value.is_empty(permission.sourcearn) + +sourcearn_is_missed(permission) if not permission.sourcearn diff --git a/checks/cloud/aws/mq/enable_audit_logging.rego b/checks/cloud/aws/mq/enable_audit_logging.rego index 94eb0a9c..abe7ea30 100644 --- a/checks/cloud/aws/mq/enable_audit_logging.rego +++ b/checks/cloud/aws/mq/enable_audit_logging.rego @@ -33,9 +33,18 @@ package builtin.aws.mq.aws0070 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some broker in input.aws.mq.brokers - broker.logging.audit.value == false - - res := result.new("Broker does not have audit logging enabled.", broker.logging.audit) + logging_disabled(broker) + res := result.new( + "Broker does not have audit logging enabled.", + metadata.obj_by_path(broker, ["logging", "audit"]), + ) } + +logging_disabled(broker) if value.is_false(broker.logging.audit) + +logging_disabled(broker) if not broker.logging.audit diff --git a/checks/cloud/aws/mq/enable_general_logging.rego b/checks/cloud/aws/mq/enable_general_logging.rego index 82ec21e1..c1a6d4e1 100644 --- a/checks/cloud/aws/mq/enable_general_logging.rego +++ b/checks/cloud/aws/mq/enable_general_logging.rego @@ -33,8 +33,18 @@ package builtin.aws.mq.aws0071 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some broker in input.aws.mq.brokers - broker.logging.general.value == false - res := result.new("Broker does not have general logging enabled.", broker.logging.general) + logging_disabled(broker) + res := result.new( + "Broker does not have general logging enabled.", + metadata.obj_by_path(broker, ["logging", "general"]), + ) } + +logging_disabled(broker) if value.is_false(broker.logging.general) + +logging_disabled(broker) if not broker.logging.general diff --git a/checks/cloud/aws/neptune/encryption_customer_key.rego b/checks/cloud/aws/neptune/encryption_customer_key.rego index f70495d1..c4cc1d89 100644 --- a/checks/cloud/aws/neptune/encryption_customer_key.rego +++ b/checks/cloud/aws/neptune/encryption_customer_key.rego @@ -33,13 +33,17 @@ package builtin.aws.neptune.aws0128 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.neptune.clusters - not has_kms_key(cluster) + without_cmk(cluster) res := result.new( "Cluster does not encrypt data with a customer managed key.", object.get(cluster, "kmskeyid", cluster), ) } -has_kms_key(cluster) if cluster.kmskeyid.value != "" +without_cmk(cluster) if value.is_empty(cluster.kmskeyid) + +without_cmk(cluster) if not cluster.kmskeyid diff --git a/checks/cloud/aws/rds/encrypt_cluster_storage_data.rego b/checks/cloud/aws/rds/encrypt_cluster_storage_data.rego index dd4e51a7..f94848df 100644 --- a/checks/cloud/aws/rds/encrypt_cluster_storage_data.rego +++ b/checks/cloud/aws/rds/encrypt_cluster_storage_data.rego @@ -35,11 +35,12 @@ package builtin.aws.rds.aws0079 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some cluster in input.aws.rds.clusters isManaged(cluster) - not encryption_enabled(cluster) + encryption_disabled(cluster) res := result.new( "Cluster does not have storage encryption enabled.", metadata.obj_by_path(cluster, ["encryption", "encryptstorage"]), @@ -49,14 +50,18 @@ deny contains res if { deny contains res if { some cluster in input.aws.rds.clusters isManaged(cluster) - encryption_enabled(cluster) - not has_kms_key(cluster) + cluster.encryption.encryptstorage.value + without_cmk(cluster) res := result.new( "Cluster does not specify a customer managed key for storage encryption.", metadata.obj_by_path(cluster, ["encryption", "kmskeyid"]), ) } -encryption_enabled(cluster) := cluster.encryption.encryptstorage.value +encryption_disabled(cluster) if value.is_false(cluster.encryption.encryptstorage) -has_kms_key(cluster) := cluster.encryption.kmskeyid.value != "" +encryption_disabled(cluster) if not cluster.encryption.encryptstorage + +without_cmk(cluster) if value.is_empty(cluster.encryption.kmskeyid) + +without_cmk(cluster) if not cluster.encryption.kmskeyid diff --git a/checks/cloud/aws/rds/encrypt_instance_storage_data.rego b/checks/cloud/aws/rds/encrypt_instance_storage_data.rego index 196202e1..6ca4d2d4 100644 --- a/checks/cloud/aws/rds/encrypt_instance_storage_data.rego +++ b/checks/cloud/aws/rds/encrypt_instance_storage_data.rego @@ -35,15 +35,22 @@ package builtin.aws.rds.aws0080 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some instance in input.aws.rds.instances - not has_replication_source_arn(instance) - not instance.encryption.encryptstorage.value + without_replication_source_arn(instance) + encryption_disabled(instance) res := result.new( "Instance does not have storage encryption enabled.", metadata.obj_by_path(instance, ["encryption", "encryptstorage"]), ) } -has_replication_source_arn(instance) := instance.replciationsourcearn.value != "" +without_replication_source_arn(instance) if value.is_empty(instance.replciationsourcearn) + +without_replication_source_arn(instance) if not instance.replciationsourcearn + +encryption_disabled(instance) if value.is_false(instance.encryption.encryptstorage) + +encryption_disabled(instance) if not instance.encryption.encryptstorage diff --git a/checks/cloud/aws/rds/performance_insights_encryption_customer_key.rego b/checks/cloud/aws/rds/performance_insights_encryption_customer_key.rego index 42068773..13d60513 100644 --- a/checks/cloud/aws/rds/performance_insights_encryption_customer_key.rego +++ b/checks/cloud/aws/rds/performance_insights_encryption_customer_key.rego @@ -36,6 +36,8 @@ package builtin.aws.rds.aws0078 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.rds.clusters some instance in cluster.instances @@ -58,7 +60,9 @@ deny contains res if { kms_key_not_used(instance) if { isManaged(instance) instance.performanceinsights.enabled.value - not has_perfomance_insights_kms_key_id(instance) + perfomance_insights_kms_key_id_missed(instance) } -has_perfomance_insights_kms_key_id(instance) := instance.performanceinsights.kmskeyid.value != "" +perfomance_insights_kms_key_id_missed(instance) if value.is_empty(instance.performanceinsights.kmskeyid) + +perfomance_insights_kms_key_id_missed(instance) if not instance.performanceinsights.kmskeyid diff --git a/checks/cloud/aws/rds/specify_backup_retention.rego b/checks/cloud/aws/rds/specify_backup_retention.rego index dd6c0052..38e02d6d 100644 --- a/checks/cloud/aws/rds/specify_backup_retention.rego +++ b/checks/cloud/aws/rds/specify_backup_retention.rego @@ -34,6 +34,8 @@ package builtin.aws.rds.aws0077 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.rds.clusters has_low_backup_retention_period(cluster) @@ -54,8 +56,10 @@ deny contains res if { has_low_backup_retention_period(instance) if { isManaged(instance) - not has_replication_source(instance) - instance.backupretentionperioddays.value < 2 + without_replication_source(instance) + value.less_than(instance.backupretentionperioddays, 2) } -has_replication_source(instance) := instance.replicationsourcearn.value != "" +without_replication_source(instance) if value.is_empty(instance.replicationsourcearn) + +without_replication_source(instance) if not instance.replicationsourcearn diff --git a/checks/cloud/aws/redshift/add_description_to_security_group.rego b/checks/cloud/aws/redshift/add_description_to_security_group.rego index 329e677c..77431e20 100644 --- a/checks/cloud/aws/redshift/add_description_to_security_group.rego +++ b/checks/cloud/aws/redshift/add_description_to_security_group.rego @@ -29,13 +29,17 @@ package builtin.aws.redshift.aws0083 import rego.v1 +import data.lib.cloud.value + deny contains res if { some group in input.aws.redshift.securitygroups - not has_description(group) + without_description(group) res := result.new( "Security group has no description.", object.get(group, "description", group), ) } -has_description(group) if group.description.value != "" +without_description(group) if value.is_empty(group.description) + +without_description(group) if not group.description diff --git a/checks/cloud/aws/redshift/encryption_customer_key.rego b/checks/cloud/aws/redshift/encryption_customer_key.rego index a9c705f9..626e24de 100644 --- a/checks/cloud/aws/redshift/encryption_customer_key.rego +++ b/checks/cloud/aws/redshift/encryption_customer_key.rego @@ -33,9 +33,11 @@ package builtin.aws.redshift.aws0084 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.redshift.clusters - not is_encrypted(cluster) + is_not_encrypted(cluster) res := result.new( "Cluster does not have encryption enabled.", cluster.encryption, @@ -44,14 +46,18 @@ deny contains res if { deny contains res if { some cluster in input.aws.redshift.clusters - is_encrypted(cluster) - not has_kms_key(cluster) + cluster.encryption.enabled.value + without_cmk(cluster) res := result.new( "Cluster does not use a customer managed encryption key.", cluster.encryption, ) } -is_encrypted(cluster) if cluster.encryption.enabled.value +is_not_encrypted(cluster) if value.is_false(cluster.encryption.enabled) + +is_not_encrypted(cluster) if not cluster.encryption.enabled + +without_cmk(cluster) if value.is_empty(cluster.encryption.kmskeyid) -has_kms_key(cluster) if cluster.encryption.kmskeyid.value != "" +without_cmk(cluster) if not cluster.encryption.kmskeyid diff --git a/checks/cloud/aws/redshift/use_vpc.rego b/checks/cloud/aws/redshift/use_vpc.rego index ac83e72c..1a712aca 100644 --- a/checks/cloud/aws/redshift/use_vpc.rego +++ b/checks/cloud/aws/redshift/use_vpc.rego @@ -34,13 +34,17 @@ package builtin.aws.redshift.aws0127 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.aws.redshift.clusters - not has_subnet_group_name(cluster) + subnet_group_name_missed(cluster) res := result.new( "Cluster is deployed outside of a VPC.", object.get(cluster, "subnetgroupname", cluster), ) } -has_subnet_group_name(cluster) if cluster.subnetgroupname.value != "" +subnet_group_name_missed(cluster) if value.is_empty(cluster.subnetgroupname) + +subnet_group_name_missed(cluster) if not cluster.subnetgroupname diff --git a/checks/cloud/aws/s3/encryption_customer_key.rego b/checks/cloud/aws/s3/encryption_customer_key.rego index 92f679df..6529cb84 100644 --- a/checks/cloud/aws/s3/encryption_customer_key.rego +++ b/checks/cloud/aws/s3/encryption_customer_key.rego @@ -33,14 +33,16 @@ package builtin.aws.s3.aws0132 import rego.v1 +import data.lib.cloud.value + deny contains res if { some bucket in input.aws.s3.buckets # Log buckets don't support non AES256 encryption - this rule doesn't apply here # https://aws.amazon.com/premiumsupport/knowledge-center/s3-server-access-log-not-delivered/ - not is_log_bucket(bucket) + non_log_bucket(bucket) - not has_encryption(bucket) + without_cmk(bucket) res := result.new( "Bucket does not encrypt data with a customer managed key.", @@ -48,6 +50,13 @@ deny contains res if { ) } -is_log_bucket(bucket) := lower(bucket.acl.value) == "log-delivery-write" +non_log_bucket(bucket) if { + not value.is_unresolvable(bucket.acl) + lower(bucket.acl.value) != "log-delivery-write" +} + +non_log_bucket(bucket) if not bucket.acl + +without_cmk(bucket) if value.is_empty(bucket.encryption.kmskeyid) -has_encryption(bucket) := bucket.encryption.kmskeyid.value != "" +without_cmk(bucket) if not bucket.encryption.kmskeyid diff --git a/checks/cloud/aws/sam/enable_api_access_logging.rego b/checks/cloud/aws/sam/enable_api_access_logging.rego index 247c9e6c..8f052c1f 100644 --- a/checks/cloud/aws/sam/enable_api_access_logging.rego +++ b/checks/cloud/aws/sam/enable_api_access_logging.rego @@ -28,12 +28,19 @@ package builtin.aws.sam.aws0113 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some api in input.aws.sam.apis isManaged(api) - api.accesslogging.cloudwatchloggrouparn.value == "" + without_logging(api) res := result.new( "Access logging is not configured.", - api.accesslogging, + metadata.obj_by_path(api, ["accesslogging", "cloudwatchloggrouparn"]), ) } + +without_logging(api) if value.is_empty(api.accesslogging.cloudwatchloggrouparn) + +without_logging(api) if not api.accesslogging.cloudwatchloggrouparn diff --git a/checks/cloud/aws/sam/enable_http_api_access_logging.rego b/checks/cloud/aws/sam/enable_http_api_access_logging.rego index fbdddcec..b6a24470 100644 --- a/checks/cloud/aws/sam/enable_http_api_access_logging.rego +++ b/checks/cloud/aws/sam/enable_http_api_access_logging.rego @@ -28,12 +28,19 @@ package builtin.aws.sam.aws0116 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some api in input.aws.sam.httpapis isManaged(api) - api.accesslogging.cloudwatchloggrouparn.value == "" + without_logging(api) res := result.new( "Access logging is not configured.", - api.accesslogging, + metadata.obj_by_path(api, ["accesslogging", "cloudwatchloggrouparn"]), ) } + +without_logging(api) if value.is_empty(api.accesslogging.cloudwatchloggrouparn) + +without_logging(api) if not api.accesslogging.cloudwatchloggrouparn diff --git a/checks/cloud/aws/sns/enable_topic_encryption.rego b/checks/cloud/aws/sns/enable_topic_encryption.rego index d41a659e..c31860fd 100644 --- a/checks/cloud/aws/sns/enable_topic_encryption.rego +++ b/checks/cloud/aws/sns/enable_topic_encryption.rego @@ -33,11 +33,18 @@ package builtin.aws.sns.aws0095 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some topic in input.aws.sns.topics - topic.encryption.kmskeyid.value == "" + not_encrypted(topic) res := result.new( "Topic does not have encryption enabled.", - topic.encryption.kmskeyid, + metadata.obj_by_path(topic, ["encryption", "kmskeyid"]), ) } + +not_encrypted(topic) if value.is_empty(topic.encryption.kmskeyid) + +not_encrypted(topic) if not topic.encryption.kmskeyid diff --git a/checks/cloud/aws/sns/enable_topic_encryption_test.rego b/checks/cloud/aws/sns/enable_topic_encryption_test.rego index 31dea02d..0ee6db84 100644 --- a/checks/cloud/aws/sns/enable_topic_encryption_test.rego +++ b/checks/cloud/aws/sns/enable_topic_encryption_test.rego @@ -16,3 +16,9 @@ test_allow_topic_with_encryption if { test.assert_empty(check.deny) with input as inp } + +test_allow_topic_without_encryption_but_unresolvable if { + inp := {"aws": {"sns": {"topics": [{"encryption": {"kmskeyid": {"value": "", "unresolvable": true}}}]}}} + + test.assert_empty(check.deny) with input as inp +} diff --git a/checks/cloud/aws/sqs/enable_queue_encryption.rego b/checks/cloud/aws/sqs/enable_queue_encryption.rego index d5e4395a..68eabade 100644 --- a/checks/cloud/aws/sqs/enable_queue_encryption.rego +++ b/checks/cloud/aws/sqs/enable_queue_encryption.rego @@ -33,10 +33,20 @@ package builtin.aws.sqs.aws0096 import rego.v1 +import data.lib.cloud.value + deny contains res if { some queue in input.aws.sqs.queues isManaged(queue) - queue.encryption.kmskeyid.value == "" - queue.encryption.managedencryption.value == false + without_cmk(queue) + not_encrypted(queue) res := result.new("Queue is not encrypted", queue.encryption) } + +without_cmk(queue) if value.is_empty(queue.encryption.kmskeyid) + +without_cmk(queue) if not queue.encryption.kmskeyid + +not_encrypted(queue) if value.is_false(queue.encryption.managedencryption) + +not_encrypted(queue) if not queue.encryption.managedencryption diff --git a/checks/cloud/aws/ssm/secret_use_customer_key.rego b/checks/cloud/aws/ssm/secret_use_customer_key.rego index 152c330b..e99cc390 100644 --- a/checks/cloud/aws/ssm/secret_use_customer_key.rego +++ b/checks/cloud/aws/ssm/secret_use_customer_key.rego @@ -33,9 +33,11 @@ package builtin.aws.ssm.aws0098 import rego.v1 +import data.lib.cloud.value + deny contains res if { some secret in input.aws.ssm.secrets - secret.kmskeyid.value == "" + without_cmk(secret) res := result.new("Secret is not encrypted with a customer managed key.", secret.kmskeyid) } @@ -44,3 +46,7 @@ deny contains res if { secret.kmskeyid.value == "alias/aws/secretsmanager" res := result.new("Secret explicitly uses the default key.", secret.kmskeyid) } + +without_cmk(secret) if value.is_empty(secret.kmskeyid) + +without_cmk(secret) if not secret.kmskeyid diff --git a/checks/cloud/azure/appservice/account_identity_registered.rego b/checks/cloud/azure/appservice/account_identity_registered.rego index b01c6ada..27232d4e 100644 --- a/checks/cloud/azure/appservice/account_identity_registered.rego +++ b/checks/cloud/azure/appservice/account_identity_registered.rego @@ -29,15 +29,18 @@ package builtin.azure.appservice.azure0002 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some service in input.azure.appservice.services isManaged(service) - not has_identity_type(service) + identity_type_missed(service) res := result.new( "App service does not have an identity type.", metadata.obj_by_path(service, ["identity", "type"]), ) } -has_identity_type(service) := service.identity.type.value != "" +identity_type_missed(service) if value.is_empty(service.identity.type) + +identity_type_missed(service) if not service.identity.type diff --git a/checks/cloud/azure/container/configured_network_policy.rego b/checks/cloud/azure/container/configured_network_policy.rego index da371e3e..8026be4e 100644 --- a/checks/cloud/azure/container/configured_network_policy.rego +++ b/checks/cloud/azure/container/configured_network_policy.rego @@ -31,14 +31,17 @@ package builtin.azure.container.azure0043 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some cluster in input.azure.container.kubernetesclusters - not has_network_policy(cluster) + network_policy_missed(cluster) res := result.new( "Kubernetes cluster does not have a network policy set.", metadata.obj_by_path(cluster, ["networkprofile", "networkpolicy"]), ) } -has_network_policy(cluster) := cluster.networkprofile.networkpolicy.value != "" +network_policy_missed(cluster) if value.is_empty(cluster.networkprofile.networkpolicy) + +network_policy_missed(cluster) if not cluster.networkprofile.networkpolicy diff --git a/checks/cloud/azure/database/no_public_access.rego b/checks/cloud/azure/database/no_public_access.rego index 227b392b..e73ed07b 100644 --- a/checks/cloud/azure/database/no_public_access.rego +++ b/checks/cloud/azure/database/no_public_access.rego @@ -35,11 +35,9 @@ import data.lib.cloud.metadata deny contains res if { some server in database.all_servers - is_public_access_enabled(server) + server.enablepublicnetworkaccess.value res := result.new( - "Database server does not have public access enabled.", - metadata.obj_by_path(server, "enablepublicnetworkaccess"), + "Database server has public network access enabled.", + server.enablepublicnetworkaccess, ) } - -is_public_access_enabled(server) := server.enablepublicnetworkaccess.value == true diff --git a/checks/cloud/azure/database/retention_period_set.rego b/checks/cloud/azure/database/retention_period_set.rego index e7d88620..929c8f66 100644 --- a/checks/cloud/azure/database/retention_period_set.rego +++ b/checks/cloud/azure/database/retention_period_set.rego @@ -33,11 +33,13 @@ package builtin.azure.database.azure0025 import rego.v1 +import data.lib.cloud.value + deny contains res if { some server in input.azure.database.mssqlservers some policy in server.extendedauditingpolicies - policy.retentionindays.value < 90 - policy.retentionindays.value != 0 + value.less_than(policy.retentionindays, 90) + value.is_not_equal(policy.retentionindays, 0) res := result.new( "Server has a retention period of less than 90 days.", diff --git a/checks/cloud/azure/keyvault/content_type_for_secret.rego b/checks/cloud/azure/keyvault/content_type_for_secret.rego index 48048d23..1be5757f 100644 --- a/checks/cloud/azure/keyvault/content_type_for_secret.rego +++ b/checks/cloud/azure/keyvault/content_type_for_secret.rego @@ -32,14 +32,18 @@ package builtin.azure.keyvault.azure0015 import rego.v1 +import data.lib.cloud.value + deny contains res if { some vault in input.azure.keyvault.vaults some secret in vault.secrets - not secret_has_content_type(secret) + secret_without_content_type(secret) res := result.new( "Secret does not have a content-type specified.", object.get(secret, "contenttype", secret), ) } -secret_has_content_type(secret) := secret.contenttype.value != "" +secret_without_content_type(secret) if value.is_empty(secret.contenttype) + +secret_without_content_type(secret) if not secret.contenttype diff --git a/checks/cloud/azure/network/retention_policy_set.rego b/checks/cloud/azure/network/retention_policy_set.rego index 3c81d871..67b800ee 100644 --- a/checks/cloud/azure/network/retention_policy_set.rego +++ b/checks/cloud/azure/network/retention_policy_set.rego @@ -36,6 +36,8 @@ import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value + flowlogs := input.azure.network.networkwatcherflowlogs deny contains res if { @@ -54,7 +56,7 @@ deny contains res if { isManaged(flowlog) flowlog.retentionpolicy.enabled.value - flowlog.retentionpolicy.days.value < 90 + value.less_than(flowlog.retentionpolicy.days, 90) res := result.new( "Flow log has a log retention policy of less than 90 days.", metadata.obj_by_path(flowlog, ["retentionpolicy", "days"]), diff --git a/checks/cloud/azure/securitycenter/set_required_contact_details.rego b/checks/cloud/azure/securitycenter/set_required_contact_details.rego index e54e593c..d879df7b 100644 --- a/checks/cloud/azure/securitycenter/set_required_contact_details.rego +++ b/checks/cloud/azure/securitycenter/set_required_contact_details.rego @@ -32,15 +32,18 @@ package builtin.azure.securitycenter.azure0046 import rego.v1 +import data.lib.cloud.value + deny contains res if { some contact in input.azure.securitycenter.contacts isManaged(contact) - - not contact_has_phone(contact) + contact_without_phone(contact) res := result.new( "Security contact does not have a phone number listed.", object.get(contact, "phone", contact), ) } -contact_has_phone(contact) := contact.phone.value != "" +contact_without_phone(contact) if value.is_empty(contact.phone) + +contact_without_phone(contact) if not contact.phone diff --git a/checks/cloud/github/actions/no_plain_text_action_secrets.rego b/checks/cloud/github/actions/no_plain_text_action_secrets.rego index 889e383c..bf8981d5 100644 --- a/checks/cloud/github/actions/no_plain_text_action_secrets.rego +++ b/checks/cloud/github/actions/no_plain_text_action_secrets.rego @@ -32,8 +32,10 @@ package builtin.github.actions.github0002 import rego.v1 +import data.lib.cloud.value + deny contains res if { some secret in input.github.environmentsecrets - secret.plaintextvalue.value != "" + value.is_not_empty(secret.plaintextvalue) res := result.new("Secret has plain text value", secret.plaintextvalue) } diff --git a/checks/cloud/google/compute/disk_encryption_customer_key.rego b/checks/cloud/google/compute/disk_encryption_customer_key.rego index e512fa67..105cee30 100644 --- a/checks/cloud/google/compute/disk_encryption_customer_key.rego +++ b/checks/cloud/google/compute/disk_encryption_customer_key.rego @@ -29,14 +29,17 @@ package builtin.google.compute.google0034 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some disk in input.google.compute.disks - not is_disk_encrypted(disk) + disk_not_encrypted(disk) res := result.new( "Disk is not encrypted with a customer managed key.", metadata.obj_by_path(disk, ["encryption", "kmskeylink"]), ) } -is_disk_encrypted(disk) := disk.encryption.kmskeylink.value != "" +disk_not_encrypted(disk) if value.is_empty(disk.encryption.kmskeylink) + +disk_not_encrypted(disk) if not disk.encryption.kmskeylink diff --git a/checks/cloud/google/compute/no_default_service_account.rego b/checks/cloud/google/compute/no_default_service_account.rego index 5508e7e7..d78c2f79 100644 --- a/checks/cloud/google/compute/no_default_service_account.rego +++ b/checks/cloud/google/compute/no_default_service_account.rego @@ -30,12 +30,9 @@ import rego.v1 deny contains res if { some instance in input.google.compute.instances - service_account := instance.serviceaccount - is_default_service_account(service_account) + instance.serviceaccount.isdefault.value res := result.new( "Instance uses the default service account.", - object.get(service_account, "email", service_account), + instance.serviceaccount.isdefault, ) } - -is_default_service_account(service_account) := service_account.isdefault.value == true diff --git a/checks/cloud/google/compute/vm_disk_encryption_customer_key.rego b/checks/cloud/google/compute/vm_disk_encryption_customer_key.rego index 53678b83..a04bda5c 100644 --- a/checks/cloud/google/compute/vm_disk_encryption_customer_key.rego +++ b/checks/cloud/google/compute/vm_disk_encryption_customer_key.rego @@ -29,6 +29,7 @@ package builtin.google.compute.google0033 import rego.v1 import data.lib.cloud.metadata +import data.lib.cloud.value deny contains res if { some instance in input.google.compute.instances @@ -39,11 +40,13 @@ deny contains res if { some disk in disks - not disk_is_encrypted(disk) + disk_is_not_encrypted(disk) res := result.new( "Instance disk encryption does not use a customer managed key.", metadata.obj_by_path(disk, ["encryption", "kmskeylink"]), ) } -disk_is_encrypted(disk) := disk.encryption.kmskeylink.value != "" +disk_is_not_encrypted(disk) if value.is_empty(disk.encryption.kmskeylink) + +disk_is_not_encrypted(disk) if not disk.encryption.kmskeylink diff --git a/checks/cloud/google/gke/no_legacy_authentication.rego b/checks/cloud/google/gke/no_legacy_authentication.rego index 60dae1f8..ca24d3dd 100644 --- a/checks/cloud/google/gke/no_legacy_authentication.rego +++ b/checks/cloud/google/gke/no_legacy_authentication.rego @@ -32,9 +32,11 @@ package builtin.google.gke.google0064 import rego.v1 +import data.lib.cloud.value + deny contains res if { some cluster in input.google.gke.clusters - cluster.masterauth.clientcertificate.issuecertificate.value == true + cluster.masterauth.clientcertificate.issuecertificate.value res := result.new( "Cluster allows the use of certificates for master authentication.", cluster.masterauth.clientcertificate.issuecertificate, @@ -44,7 +46,7 @@ deny contains res if { deny contains res if { some cluster in input.google.gke.clusters not cluster.masterauth.clientcertificate.issuecertificate.value - cluster.masterauth.username.value != "" + value.is_not_empty(cluster.masterauth.username) res := result.new( "Cluster allows the use of basic auth for master authentication.", cluster.masterauth.username, diff --git a/checks/cloud/google/gke/use_service_account.rego b/checks/cloud/google/gke/use_service_account.rego index 358860fe..835af21b 100644 --- a/checks/cloud/google/gke/use_service_account.rego +++ b/checks/cloud/google/gke/use_service_account.rego @@ -30,22 +30,29 @@ package builtin.google.gke.google0050 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some cluster in input.google.gke.clusters - cluster.removedefaultnodepool.value == false - cluster.nodeconfig.serviceaccount.value == "" + value.is_false(cluster.removedefaultnodepool) + default_account_is_not_overrided(cluster.nodeconfig) res := result.new( "Cluster does not override the default service account.", - cluster.nodeconfig.serviceaccount, + metadata.obj_by_path(cluster, ["nodeconfig", "serviceaccount"]), ) } deny contains res if { some cluster in input.google.gke.clusters some pool in cluster.nodepools - pool.nodeconfig.serviceaccount.value == "" + default_account_is_not_overrided(pool.nodeconfig) res := result.new( "Node pool does not override the default service account.", - pool.nodeconfig.serviceaccount, + metadata.obj_by_path(pool, ["nodeconfig", "serviceaccount"]), ) } + +default_account_is_not_overrided(nodeconfig) if value.is_empty(nodeconfig.serviceaccount) + +default_account_is_not_overrided(nodeconfig) if not nodeconfig.serviceaccount diff --git a/checks/cloud/google/iam/no_conditions_on_workload_identity_pool_provider.rego b/checks/cloud/google/iam/no_conditions_on_workload_identity_pool_provider.rego index 35594d64..e8f47def 100644 --- a/checks/cloud/google/iam/no_conditions_on_workload_identity_pool_provider.rego +++ b/checks/cloud/google/iam/no_conditions_on_workload_identity_pool_provider.rego @@ -30,13 +30,17 @@ package builtin.google.iam.google0068 import rego.v1 +import data.lib.cloud.value + deny contains res if { some provider in input.google.iam.workloadidentitypoolproviders - not has_conditions(provider) + without_conditions(provider) res := result.new( "This workload identity pool provider configuration has no conditions set.", object.get(provider, "attributecondition", provider), ) } -has_conditions(provider) := provider.attributecondition.value != "" +without_conditions(provider) if value.is_empty(provider.attributecondition) + +without_conditions(provider) if not provider.attributecondition diff --git a/checks/cloud/google/sql/enable_pg_temp_file_logging.rego b/checks/cloud/google/sql/enable_pg_temp_file_logging.rego index a923c548..1c0d9da1 100644 --- a/checks/cloud/google/sql/enable_pg_temp_file_logging.rego +++ b/checks/cloud/google/sql/enable_pg_temp_file_logging.rego @@ -30,6 +30,7 @@ package builtin.google.sql.google0014 import rego.v1 +import data.lib.cloud.value import data.lib.google.database deny contains res if { @@ -41,11 +42,11 @@ deny contains res if { } check_log_temp_file_size(logtempfilesize) := msg if { - logtempfilesize.value < 0 + value.less_than(logtempfilesize, 0) msg := "Database instance has temporary file logging disabled." } check_log_temp_file_size(logtempfilesize) := msg if { - logtempfilesize.value > 0 + value.greater_than(logtempfilesize, 0) msg := "Database instance has temporary file logging disabled for files of certain sizes." } diff --git a/checks/cloud/google/sql/encrypt_in_transit_data.rego b/checks/cloud/google/sql/encrypt_in_transit_data.rego index 9a00211c..9846cae3 100644 --- a/checks/cloud/google/sql/encrypt_in_transit_data.rego +++ b/checks/cloud/google/sql/encrypt_in_transit_data.rego @@ -30,6 +30,8 @@ package builtin.google.sql.google0015 import rego.v1 +import data.lib.cloud.value + ssl_mode_trusted_client_certificate_required := "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" deny contains res if { @@ -55,4 +57,4 @@ is_ssl_enforced(ipconf) if { ipconf.requiretls.value == true } -has_ssl_mode(ipconf) if ipconf.sslmode.value != "" +has_ssl_mode(ipconf) if not value.is_empty(ipconf.sslmode) diff --git a/checks/cloud/google/storage/bucket_encryption_customer_key.rego b/checks/cloud/google/storage/bucket_encryption_customer_key.rego index db94d3e7..ba58cd32 100644 --- a/checks/cloud/google/storage/bucket_encryption_customer_key.rego +++ b/checks/cloud/google/storage/bucket_encryption_customer_key.rego @@ -30,9 +30,19 @@ package builtin.google.storage.google0066 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some bucket in input.google.storage.buckets isManaged(bucket) - bucket.encryption.defaultkmskeyname.value == "" - res := result.new("Storage bucket encryption does not use a customer-managed key.", bucket.encryption.defaultkmskeyname) + without_cmk(bucket) + res := result.new( + "Storage bucket encryption does not use a customer-managed key.", + metadata.obj_by_path(bucket, ["encryption", "defaultkmskeyname"]), + ) } + +without_cmk(bucket) if value.is_empty(bucket.encryption.defaultkmskeyname) + +without_cmk(bucket) if not bucket.encryption.defaultkmskeyname diff --git a/checks/cloud/nifcloud/computing/add_description_to_security_group.rego b/checks/cloud/nifcloud/computing/add_description_to_security_group.rego index bf82d7e7..820b7521 100644 --- a/checks/cloud/nifcloud/computing/add_description_to_security_group.rego +++ b/checks/cloud/nifcloud/computing/add_description_to_security_group.rego @@ -34,9 +34,11 @@ package builtin.nifcloud.computing.nifcloud0002 import rego.v1 +import data.lib.cloud.value + deny contains res if { some sg in input.nifcloud.computing.securitygroups - sg.description.value == "" + without_description(sg) res := result.new("Security group does not have a description.", sg.description) } @@ -45,3 +47,7 @@ deny contains res if { sg.description.value == "Managed by Terraform" res := result.new("Security group explicitly uses the default description.", sg.description) } + +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/checks/cloud/nifcloud/computing/add_description_to_security_group_rule.rego b/checks/cloud/nifcloud/computing/add_description_to_security_group_rule.rego index ddf7c5da..55e09830 100644 --- a/checks/cloud/nifcloud/computing/add_description_to_security_group_rule.rego +++ b/checks/cloud/nifcloud/computing/add_description_to_security_group_rule.rego @@ -34,6 +34,9 @@ package builtin.nifcloud.computing.nifcloud0003 import rego.v1 +import data.lib.cloud.metadata +import data.lib.cloud.value + deny contains res if { some sg in input.nifcloud.computing.securitygroups some rule in array.concat( @@ -41,6 +44,13 @@ deny contains res if { object.get(sg, "egressrules", []), ) - rule.description.value == "" - res := result.new("Security group rule does not have a description.", rule.description) + without_description(rule) + res := result.new( + "Security group rule does not have a description.", + metadata.obj_by_path(rule, ["description"]), + ) } + +without_description(rule) if value.is_empty(rule.description) + +without_description(rule) if not rule.description diff --git a/checks/cloud/nifcloud/computing/add_security_group_to_instance.rego b/checks/cloud/nifcloud/computing/add_security_group_to_instance.rego index 7b2bf36a..8524be4a 100644 --- a/checks/cloud/nifcloud/computing/add_security_group_to_instance.rego +++ b/checks/cloud/nifcloud/computing/add_security_group_to_instance.rego @@ -32,8 +32,14 @@ package builtin.nifcloud.computing.nifcloud0004 import rego.v1 +import data.lib.cloud.value + deny contains res if { some instance in input.nifcloud.computing.instances - instance.securitygroup.value == "" + without_sg(instance) res := result.new("Instance does not have a securiy group.", instance.securitygroup) } + +without_sg(instance) if value.is_empty(instance.securitygroup) + +without_sg(instance) if not instance.securitygroup diff --git a/checks/cloud/nifcloud/nas/add_description_to_nas_security_group.rego b/checks/cloud/nifcloud/nas/add_description_to_nas_security_group.rego index 6b6b66a6..1ec72e25 100644 --- a/checks/cloud/nifcloud/nas/add_description_to_nas_security_group.rego +++ b/checks/cloud/nifcloud/nas/add_description_to_nas_security_group.rego @@ -34,9 +34,11 @@ package builtin.nifcloud.nas.nifcloud0015 import rego.v1 +import data.lib.cloud.value + deny contains res if { some sg in input.nifcloud.nas.nassecuritygroups - sg.description.value == "" + without_description(sg) res := result.new("NAS security group does not have a description.", sg.description) } @@ -45,3 +47,7 @@ deny contains res if { sg.description.value == "Managed by Terraform" res := result.new("NAS security group explicitly uses the default description.", sg.description) } + +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/checks/cloud/nifcloud/network/add_security_group_to_router.rego b/checks/cloud/nifcloud/network/add_security_group_to_router.rego index bc7f3850..f8137c2d 100644 --- a/checks/cloud/nifcloud/network/add_security_group_to_router.rego +++ b/checks/cloud/nifcloud/network/add_security_group_to_router.rego @@ -32,8 +32,14 @@ package builtin.nifcloud.network.nifcloud0016 import rego.v1 +import data.lib.cloud.value + deny contains res if { some router in input.nifcloud.network.routers - router.securitygroup.value == "" + without_sg(router) res := result.new("Router does not have a securiy group.", router.securitygroup) } + +without_sg(router) if value.is_empty(router.securitygroup) + +without_sg(router) if not router.securitygroup diff --git a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego index cc5e0530..1ea8fe7b 100644 --- a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego +++ b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego @@ -32,8 +32,14 @@ package builtin.nifcloud.network.nifcloud0018 import rego.v1 +import data.lib.cloud.value + deny contains res if { some gateway in input.nifcloud.network.vpngateways - gateway.securitygroup.value == "" + without_sg(gateway) res := result.new("VpnGateway does not have a securiy group.", gateway.securitygroup) } + +without_sg(gateway) if value.is_empty(gateway.securitygroup) + +without_sg(gateway) if not gateway.securitygroup diff --git a/checks/cloud/nifcloud/rdb/add_description_to_db_security_group.rego b/checks/cloud/nifcloud/rdb/add_description_to_db_security_group.rego index 47b07378..760bacb5 100644 --- a/checks/cloud/nifcloud/rdb/add_description_to_db_security_group.rego +++ b/checks/cloud/nifcloud/rdb/add_description_to_db_security_group.rego @@ -34,9 +34,11 @@ package builtin.nifcloud.rdb.nifcloud0012 import rego.v1 +import data.lib.cloud.value + deny contains res if { some sg in input.nifcloud.rdb.dbsecuritygroups - sg.description.value == "" + without_description(sg) res := result.new("DB security group does not have a description.", sg.description) } @@ -45,3 +47,7 @@ deny contains res if { sg.description.value == "Managed by Terraform" res := result.new("DB security group explicitly uses the default description.", sg.description) } + +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/checks/cloud/nifcloud/rdb/specify_backup_retention.rego b/checks/cloud/nifcloud/rdb/specify_backup_retention.rego index 324f1c4a..f579e4d3 100644 --- a/checks/cloud/nifcloud/rdb/specify_backup_retention.rego +++ b/checks/cloud/nifcloud/rdb/specify_backup_retention.rego @@ -30,8 +30,10 @@ package builtin.nifcloud.rdb.nifcloud0009 import rego.v1 +import data.lib.cloud.value + deny contains res if { some db in input.nifcloud.rdb.dbinstances - db.backupretentionperioddays.value < 2 + value.less_than(db.backupretentionperioddays, 2) res := result.new("Instance has very low backup retention period.", db.backupretentionperioddays) } diff --git a/checks/cloud/openstack/compute/no_public_access.rego b/checks/cloud/openstack/compute/no_public_access.rego index a721df8b..248492aa 100644 --- a/checks/cloud/openstack/compute/no_public_access.rego +++ b/checks/cloud/openstack/compute/no_public_access.rego @@ -28,10 +28,12 @@ package builtin.openstack.compute.openstack0002 import rego.v1 +import data.lib.cloud.value + deny contains res if { some rule in input.openstack.compute.firewall.allowrules is_rule_enabled(rule) - rule.destination.value == "" + value.is_empty(rule.destination) res := result.new("Firewall rule does not restrict destination address internally.", rule) } @@ -45,7 +47,7 @@ deny contains res if { deny contains res if { some rule in input.openstack.compute.firewall.allowrules is_rule_enabled(rule) - rule.source.value == "" + value.is_empty(rule.source) res := result.new("Firewall rule does not restrict source address internally.", rule.source) } diff --git a/checks/cloud/openstack/networking/add_description_to_security_group.rego b/checks/cloud/openstack/networking/add_description_to_security_group.rego index 59b50e1f..dc9fe7b1 100644 --- a/checks/cloud/openstack/networking/add_description_to_security_group.rego +++ b/checks/cloud/openstack/networking/add_description_to_security_group.rego @@ -26,8 +26,14 @@ package builtin.openstack.networking.openstack0005 import rego.v1 +import data.lib.cloud.value + deny contains res if { some sg in input.openstack.networking.securitygroups - sg.description.value == "" - res := result.new("Security group rule allows egress to multiple public addresses.", sg.description) + without_description(sg) + res := result.new("Network security group does not have a description.", sg.description) } + +without_description(sg) if value.is_empty(sg.description) + +without_description(sg) if not sg.description diff --git a/lib/cloud/value.rego b/lib/cloud/value.rego new file mode 100644 index 00000000..0a2838a0 --- /dev/null +++ b/lib/cloud/value.rego @@ -0,0 +1,40 @@ +# METADATA +# custom: +# library: true +package lib.cloud.value + +import rego.v1 + +is_unresolvable(val) if val.unresolvable + +# string + +is_empty(val) := is_equal(val, "") + +is_not_empty(val) := is_not_equal(val, "") + +# int + +less_than(val, other) := false if { + is_unresolvable(val) +} else := val.value < other + +greater_than(val, other) := false if { + is_unresolvable(val) +} else := val.value > other + +# bool + +is_true(val) := is_equal(val, true) + +is_false(val) := is_equal(val, false) + +# common + +is_equal(val, raw) := false if { + is_unresolvable(val) +} else := val.value == raw + +is_not_equal(val, raw) := false if { + is_unresolvable(val) +} else := val.value != raw From 89d7c53612c3c1e9e9ea81c8ff71212750f609ba Mon Sep 17 00:00:00 2001 From: Nic Wortel Date: Tue, 29 Oct 2024 10:25:40 +0100 Subject: [PATCH 2/5] Allow the `ADD` instruction with HTTP, HTTPS and Git URLs COPY should be preferred over ADD when simply copying a file from the build context to the container. However, ADD supports additional features such as fetching files from remote HTTP(S) and Git URLS and extracting tar files. See https://docs.docker.com/build/building/best-practices/#add-or-copy, https://github.com/aquasecurity/trivy/issues/7806 and https://github.com/aquasecurity/trivy/discussions/7791. --- checks/docker/add_instead_of_copy.rego | 3 +++ checks/docker/add_instead_of_copy_test.rego | 27 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/checks/docker/add_instead_of_copy.rego b/checks/docker/add_instead_of_copy.rego index 3f70f21a..7e9d135c 100644 --- a/checks/docker/add_instead_of_copy.rego +++ b/checks/docker/add_instead_of_copy.rego @@ -24,6 +24,9 @@ get_add[output] { args := concat(" ", add.Value) not contains(args, ".tar") + not contains(args, "http://") + not contains(args, "https://") + not contains(args, "git@") not is_command_with_hash(add.Value, "file:") not is_command_with_hash(add.Value, "multi:") diff --git a/checks/docker/add_instead_of_copy_test.rego b/checks/docker/add_instead_of_copy_test.rego index 6e40f658..049e90bf 100644 --- a/checks/docker/add_instead_of_copy_test.rego +++ b/checks/docker/add_instead_of_copy_test.rego @@ -70,3 +70,30 @@ test_add_tar_allowed { count(r) == 0 } + +test_add_http_url_allowed { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [{"Cmd": "add", "Value": ["http://example.com/foo.txt", "bar.txt"]}], + }]} + + count(r) == 0 +} + +test_add_https_url_allowed { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [{"Cmd": "add", "Value": ["https://example.com/foo.txt", "bar.txt"]}], + }]} + + count(r) == 0 +} + +test_add_git_url_allowed { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [{"Cmd": "add", "Value": ["git@github.com:user/repo.git", "/usr/src/things/"]}], + }]} + + count(r) == 0 +} From 99a48a13e095fee5f11b0660486439cf18080fb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:07:55 +0000 Subject: [PATCH 3/5] chore(deps): bump mvdan.cc/sh/v3 in the common group Bumps the common group with 1 update: [mvdan.cc/sh/v3](https://github.com/mvdan/sh). Updates `mvdan.cc/sh/v3` from 3.9.0 to 3.10.0 - [Release notes](https://github.com/mvdan/sh/releases) - [Changelog](https://github.com/mvdan/sh/blob/master/CHANGELOG.md) - [Commits](https://github.com/mvdan/sh/compare/v3.9.0...v3.10.0) --- updated-dependencies: - dependency-name: mvdan.cc/sh/v3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: common ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index b1fdae8f..3c38d79d 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/samber/lo v1.47.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 - mvdan.cc/sh/v3 v3.9.0 + mvdan.cc/sh/v3 v3.10.0 ) require ( @@ -130,7 +130,7 @@ require ( golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect diff --git a/go.sum b/go.sum index 9c3aa37c..8defb916 100644 --- a/go.sum +++ b/go.sum @@ -310,8 +310,8 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= @@ -476,11 +476,11 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -553,8 +553,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -mvdan.cc/sh/v3 v3.9.0 h1:it14fyjCdQUk4jf/aYxLO3FG8jFarR9GzMCtnlvvD7c= -mvdan.cc/sh/v3 v3.9.0/go.mod h1:cdBk8bgoiBI7lSZqK5JhUuq7OB64VQ7fgm85xelw3Nk= +mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4= +mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY= oras.land/oras-go/v2 v2.3.1 h1:lUC6q8RkeRReANEERLfH86iwGn55lbSWP20egdFHVec= oras.land/oras-go/v2 v2.3.1/go.mod h1:5AQXVEu1X/FKp1F9DMOb5ZItZBOa0y5dha0yCm4NR9c= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= From b9b40904c9b0e217aa8f7238a473ca3b006bff09 Mon Sep 17 00:00:00 2001 From: Simar Date: Tue, 29 Oct 2024 19:46:31 -0600 Subject: [PATCH 4/5] test(bundle): Disable canary builds --- scripts/verify-bundle.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify-bundle.go b/scripts/verify-bundle.go index e3946c3c..af770203 100644 --- a/scripts/verify-bundle.go +++ b/scripts/verify-bundle.go @@ -15,7 +15,7 @@ import ( var bundlePath = "bundle.tar.gz" var OrasPush = []string{"--artifact-type", "application/vnd.cncf.openpolicyagent.config.v1+json", fmt.Sprintf("%s:application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip", bundlePath)} -var supportedTrivyVersions = []string{"latest", "canary"} // TODO: add more versions +var supportedTrivyVersions = []string{"latest"} // TODO: add more versions func createRegistryContainer(ctx context.Context) (testcontainers.Container, string) { reqReg := testcontainers.ContainerRequest{ From 1ec0a737c4937f5ee81ca6c4d6cd4cf046f5e418 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Wed, 30 Oct 2024 11:16:14 +0600 Subject: [PATCH 5/5] fix: do not use deny in rule name Signed-off-by: Nikita Pivkin --- checks/docker/leaked_secrets.rego | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/checks/docker/leaked_secrets.rego b/checks/docker/leaked_secrets.rego index c3025ba8..8af9555f 100644 --- a/checks/docker/leaked_secrets.rego +++ b/checks/docker/leaked_secrets.rego @@ -207,8 +207,8 @@ use_command_to_setup_credentials(instruction) if { } is_secret_key(s) if { - regex.match(deny_secrets_pattern, s) - not regex.match(allow_secrets_pattern, s) + regex.match(forbidden_secrets_pattern, s) + not regex.match(allowed_secrets_pattern, s) } # adopt https://github.com/moby/buildkit/blob/62bda5c1caae9935a2051e96443d554f7ab7ef2d/frontend/dockerfile/dockerfile2llb/convert.go#L2469 @@ -218,15 +218,15 @@ build_secrets_pattern(tokens) := sprintf(secrets_regex_pattern, [concat("|", tok # these tokens cover the following keywords # https://github.com/danielmiessler/SecLists/blob/master/Discovery/Variables/secret-keywords.txt -deny_secrets_tokens := { +forbidden_secret_tokens := { "apikey", "auth", "credential", "credentials", "key", "password", "pword", "passwd", "secret", "token", "usr", "psw", } -deny_secrets_pattern := build_secrets_pattern(deny_secrets_tokens) +forbidden_secrets_pattern := build_secrets_pattern(forbidden_secret_tokens) -allow_secrets_tokens := {"public"} +allowed_secret_tokens := {"public"} -allow_secrets_pattern := build_secrets_pattern(allow_secrets_tokens) +allowed_secrets_pattern := build_secrets_pattern(allowed_secret_tokens)