From 47e49a488df4b16e87e5a8c7178af6d440aadb0b Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Mon, 15 Jul 2024 22:21:17 +0700 Subject: [PATCH 1/2] refactor(checks): migrate DigitalOcean spaces to Rego Signed-off-by: Nikita Pivkin --- .../digitalocean/spaces/AVD-DIG-0006/docs.md | 3 +- .../digitalocean/spaces/AVD-DIG-0007/docs.md | 3 +- .../digitalocean/spaces/AVD-DIG-0009/docs.md | 3 +- .../digitalocean/spaces/acl_no_public_read.go | 3 +- .../spaces/acl_no_public_read.rego | 45 ++++++++++++ .../spaces/acl_no_public_read_test.rego | 37 ++++++++++ .../spaces/disable_force_destroy.go | 3 +- .../spaces/disable_force_destroy.rego | 35 +++++++++ .../spaces/disable_force_destroy_test.go | 65 ----------------- .../spaces/disable_force_destroy_test.rego | 20 ++++++ .../digitalocean/spaces/versioning_enabled.go | 3 +- .../spaces/versioning_enabled.rego | 37 ++++++++++ .../spaces/versioning_enabled_test.go | 71 ------------------- .../spaces/versioning_enabled_test.rego | 20 ++++++ 14 files changed, 206 insertions(+), 142 deletions(-) create mode 100644 checks/cloud/digitalocean/spaces/acl_no_public_read.rego create mode 100644 checks/cloud/digitalocean/spaces/acl_no_public_read_test.rego create mode 100644 checks/cloud/digitalocean/spaces/disable_force_destroy.rego delete mode 100644 checks/cloud/digitalocean/spaces/disable_force_destroy_test.go create mode 100644 checks/cloud/digitalocean/spaces/disable_force_destroy_test.rego create mode 100644 checks/cloud/digitalocean/spaces/versioning_enabled.rego delete mode 100644 checks/cloud/digitalocean/spaces/versioning_enabled_test.go create mode 100644 checks/cloud/digitalocean/spaces/versioning_enabled_test.rego diff --git a/avd_docs/digitalocean/spaces/AVD-DIG-0006/docs.md b/avd_docs/digitalocean/spaces/AVD-DIG-0006/docs.md index 581bf747..0a27a2ce 100644 --- a/avd_docs/digitalocean/spaces/AVD-DIG-0006/docs.md +++ b/avd_docs/digitalocean/spaces/AVD-DIG-0006/docs.md @@ -1,8 +1,9 @@ Space bucket and bucket object permissions should be set to deny public access unless explicitly required. + ### Impact -The contents of the space can be accessed publicly + {{ remediationActions }} diff --git a/avd_docs/digitalocean/spaces/AVD-DIG-0007/docs.md b/avd_docs/digitalocean/spaces/AVD-DIG-0007/docs.md index ba0791c4..65d519c1 100644 --- a/avd_docs/digitalocean/spaces/AVD-DIG-0007/docs.md +++ b/avd_docs/digitalocean/spaces/AVD-DIG-0007/docs.md @@ -1,8 +1,9 @@ Versioning is a means of keeping multiple variants of an object in the same bucket. You can use the Spaces (S3) Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets. With versioning you can recover more easily from both unintended user actions and application failures. + ### Impact -Deleted or modified data would not be recoverable + {{ remediationActions }} diff --git a/avd_docs/digitalocean/spaces/AVD-DIG-0009/docs.md b/avd_docs/digitalocean/spaces/AVD-DIG-0009/docs.md index d999409d..a40e45b6 100644 --- a/avd_docs/digitalocean/spaces/AVD-DIG-0009/docs.md +++ b/avd_docs/digitalocean/spaces/AVD-DIG-0009/docs.md @@ -1,8 +1,9 @@ Enabling force destroy on a Spaces bucket means that the bucket can be deleted without the additional check that it is empty. This risks important data being accidentally deleted by a bucket removal process. + ### Impact -Accidental deletion of bucket objects + {{ remediationActions }} diff --git a/checks/cloud/digitalocean/spaces/acl_no_public_read.go b/checks/cloud/digitalocean/spaces/acl_no_public_read.go index cfa71538..31b7f744 100755 --- a/checks/cloud/digitalocean/spaces/acl_no_public_read.go +++ b/checks/cloud/digitalocean/spaces/acl_no_public_read.go @@ -27,7 +27,8 @@ var CheckAclNoPublicRead = rules.Register( Links: terraformAclNoPublicReadLinks, RemediationMarkdown: terraformAclNoPublicReadRemediationMarkdown, }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, bucket := range s.DigitalOcean.Spaces.Buckets { diff --git a/checks/cloud/digitalocean/spaces/acl_no_public_read.rego b/checks/cloud/digitalocean/spaces/acl_no_public_read.rego new file mode 100644 index 00000000..0c1d152d --- /dev/null +++ b/checks/cloud/digitalocean/spaces/acl_no_public_read.rego @@ -0,0 +1,45 @@ +# METADATA +# title: Spaces bucket or bucket object has public read acl set +# description: | +# Space bucket and bucket object permissions should be set to deny public access unless explicitly required. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://docs.digitalocean.com/reference/api/spaces-api/#access-control-lists-acls +# custom: +# id: AVD-DIG-0006 +# avd_id: AVD-DIG-0006 +# provider: digitalocean +# service: spaces +# severity: CRITICAL +# short_code: acl-no-public-read +# recommended_action: Apply a more restrictive ACL +# input: +# selector: +# - type: cloud +# subtypes: +# - service: spaces +# provider: digitalocean +# terraform: +# links: +# - https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/spaces_bucket#acl +# - https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/spaces_bucket_object#acl +# good_examples: checks/cloud/digitalocean/spaces/acl_no_public_read.tf.go +# bad_examples: checks/cloud/digitalocean/spaces/acl_no_public_read.tf.go +package builtin.digitalocean.spaces.digitalocean0006 + +import rego.v1 + +deny contains res if { + some bucket in input.digitalocean.spaces.buckets + bucket.acl.value == "public-read" + res := result.new("Bucket is publicly exposed.", bucket.acl) +} + +deny contains res if { + some bucket in input.digitalocean.spaces.buckets + some object in bucket.objects + object.acl.value == "public-read" + res := result.new("Object is publicly exposed.", object.acl) +} diff --git a/checks/cloud/digitalocean/spaces/acl_no_public_read_test.rego b/checks/cloud/digitalocean/spaces/acl_no_public_read_test.rego new file mode 100644 index 00000000..222c4894 --- /dev/null +++ b/checks/cloud/digitalocean/spaces/acl_no_public_read_test.rego @@ -0,0 +1,37 @@ +package builtin.digitalocean.spaces.digitalocean0006_test + +import rego.v1 + +import data.builtin.digitalocean.spaces.digitalocean0006 as check +import data.lib.test + +test_allow_acl_private_for_bucket if { + inp := {"digitalocean": {"spaces": {"buckets": [{"acl": {"value": "private"}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_acl_public_read_for_bucket if { + inp := {"digitalocean": {"spaces": {"buckets": [{"acl": {"value": "public-read"}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_private_acl_for_object if { + inp := {"digitalocean": {"spaces": {"buckets": [{"objects": [ + {"acl": {"value": "private"}}, + {"acl": {"value": "aws-exec-read"}}, + ]}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_public_read_acl_for_object if { + inp := {"digitalocean": {"spaces": {"buckets": [{"objects": [{"acl": {"value": "public-read"}}]}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/digitalocean/spaces/disable_force_destroy.go b/checks/cloud/digitalocean/spaces/disable_force_destroy.go index 9a297cae..c948c113 100755 --- a/checks/cloud/digitalocean/spaces/disable_force_destroy.go +++ b/checks/cloud/digitalocean/spaces/disable_force_destroy.go @@ -25,7 +25,8 @@ var CheckDisableForceDestroy = rules.Register( Links: terraformDisableForceDestroyLinks, RemediationMarkdown: terraformDisableForceDestroyRemediationMarkdown, }, - Severity: severity.Medium, + Severity: severity.Medium, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, bucket := range s.DigitalOcean.Spaces.Buckets { diff --git a/checks/cloud/digitalocean/spaces/disable_force_destroy.rego b/checks/cloud/digitalocean/spaces/disable_force_destroy.rego new file mode 100644 index 00000000..0b4be12f --- /dev/null +++ b/checks/cloud/digitalocean/spaces/disable_force_destroy.rego @@ -0,0 +1,35 @@ +# METADATA +# title: Force destroy is enabled on Spaces bucket which is dangerous +# description: | +# Enabling force destroy on a Spaces bucket means that the bucket can be deleted without the additional check that it is empty. This risks important data being accidentally deleted by a bucket removal process. +# scope: package +# schemas: +# - input: schema["cloud"] +# custom: +# id: AVD-DIG-0009 +# avd_id: AVD-DIG-0009 +# provider: digitalocean +# service: spaces +# severity: MEDIUM +# short_code: disable-force-destroy +# recommended_action: Don't use force destroy on bucket configuration +# input: +# selector: +# - type: cloud +# subtypes: +# - service: spaces +# provider: digitalocean +# terraform: +# links: +# - https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/spaces_bucket#force_destroy +# good_examples: checks/cloud/digitalocean/spaces/disable_force_destroy.tf.go +# bad_examples: checks/cloud/digitalocean/spaces/disable_force_destroy.tf.go +package builtin.digitalocean.spaces.digitalocean0009 + +import rego.v1 + +deny contains res if { + some bucket in input.digitalocean.spaces.buckets + bucket.forcedestroy.value == true + res := result.new("Bucket has force-destroy enabled.", bucket.forcedestroy) +} diff --git a/checks/cloud/digitalocean/spaces/disable_force_destroy_test.go b/checks/cloud/digitalocean/spaces/disable_force_destroy_test.go deleted file mode 100644 index 2000b77f..00000000 --- a/checks/cloud/digitalocean/spaces/disable_force_destroy_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package spaces - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/digitalocean/spaces" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckDisableForceDestroy(t *testing.T) { - tests := []struct { - name string - input spaces.Spaces - expected bool - }{ - { - name: "Space bucket force destroy enabled", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - ForceDestroy: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - { - name: "Space bucket force destroy disabled", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - ForceDestroy: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.DigitalOcean.Spaces = test.input - results := CheckDisableForceDestroy.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckDisableForceDestroy.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/digitalocean/spaces/disable_force_destroy_test.rego b/checks/cloud/digitalocean/spaces/disable_force_destroy_test.rego new file mode 100644 index 00000000..a62296a0 --- /dev/null +++ b/checks/cloud/digitalocean/spaces/disable_force_destroy_test.rego @@ -0,0 +1,20 @@ +package builtin.digitalocean.spaces.digitalocean0009_test + +import rego.v1 + +import data.builtin.digitalocean.spaces.digitalocean0009 as check +import data.lib.test + +test_allow_force_destroy_disabled if { + inp := {"digitalocean": {"spaces": {"buckets": [{"forcedestroy": {"value": false}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_force_destroy_enabled if { + inp := {"digitalocean": {"spaces": {"buckets": [{"forcedestroy": {"value": true}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/digitalocean/spaces/versioning_enabled.go b/checks/cloud/digitalocean/spaces/versioning_enabled.go index 0ec4e740..63d4e14e 100755 --- a/checks/cloud/digitalocean/spaces/versioning_enabled.go +++ b/checks/cloud/digitalocean/spaces/versioning_enabled.go @@ -27,7 +27,8 @@ var CheckVersioningEnabled = rules.Register( Links: terraformVersioningEnabledLinks, RemediationMarkdown: terraformVersioningEnabledRemediationMarkdown, }, - Severity: severity.Medium, + Severity: severity.Medium, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, bucket := range s.DigitalOcean.Spaces.Buckets { diff --git a/checks/cloud/digitalocean/spaces/versioning_enabled.rego b/checks/cloud/digitalocean/spaces/versioning_enabled.rego new file mode 100644 index 00000000..1667daac --- /dev/null +++ b/checks/cloud/digitalocean/spaces/versioning_enabled.rego @@ -0,0 +1,37 @@ +# METADATA +# title: Spaces buckets should have versioning enabled +# description: | +# Versioning is a means of keeping multiple variants of an object in the same bucket. You can use the Spaces (S3) Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets. With versioning you can recover more easily from both unintended user actions and application failures. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html +# custom: +# id: AVD-DIG-0007 +# avd_id: AVD-DIG-0007 +# provider: digitalocean +# service: spaces +# severity: MEDIUM +# short_code: versioning-enabled +# recommended_action: Enable versioning to protect against accidental or malicious removal or modification +# input: +# selector: +# - type: cloud +# subtypes: +# - service: spaces +# provider: digitalocean +# terraform: +# links: +# - https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/spaces_bucket#versioning +# good_examples: checks/cloud/digitalocean/spaces/versioning_enabled.tf.go +# bad_examples: checks/cloud/digitalocean/spaces/versioning_enabled.tf.go +package builtin.digitalocean.spaces.digitalocean0007 + +import rego.v1 + +deny contains res if { + some bucket in input.digitalocean.spaces.buckets + bucket.versioning.enabled.value == false + res := result.new("Bucket does not have versioning enabled.", bucket.versioning.enabled) +} diff --git a/checks/cloud/digitalocean/spaces/versioning_enabled_test.go b/checks/cloud/digitalocean/spaces/versioning_enabled_test.go deleted file mode 100644 index 1f16955f..00000000 --- a/checks/cloud/digitalocean/spaces/versioning_enabled_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package spaces - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/digitalocean/spaces" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckVersioningEnabled(t *testing.T) { - tests := []struct { - name string - input spaces.Spaces - expected bool - }{ - { - name: "Space bucket versioning disabled", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - Versioning: spaces.Versioning{ - Metadata: trivyTypes.NewTestMetadata(), - Enabled: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - expected: true, - }, - { - name: "Space bucket versioning enabled", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - Versioning: spaces.Versioning{ - Metadata: trivyTypes.NewTestMetadata(), - Enabled: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.DigitalOcean.Spaces = test.input - results := CheckVersioningEnabled.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckVersioningEnabled.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/digitalocean/spaces/versioning_enabled_test.rego b/checks/cloud/digitalocean/spaces/versioning_enabled_test.rego new file mode 100644 index 00000000..edcc8044 --- /dev/null +++ b/checks/cloud/digitalocean/spaces/versioning_enabled_test.rego @@ -0,0 +1,20 @@ +package builtin.digitalocean.spaces.digitalocean0007_test + +import rego.v1 + +import data.builtin.digitalocean.spaces.digitalocean0007 as check +import data.lib.test + +test_allow_versioning_enabled if { + inp := {"digitalocean": {"spaces": {"buckets": [{"versioning": {"enabled": {"value": true}}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_versioning_disabled if { + inp := {"digitalocean": {"spaces": {"buckets": [{"versioning": {"enabled": {"value": false}}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} From a42b5cb5303fa633e2629951e5dd6928f52010a5 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Wed, 21 Aug 2024 09:50:54 +0600 Subject: [PATCH 2/2] test: add functional tests Signed-off-by: Nikita Pivkin --- .../spaces/acl_no_public_read_test.go | 89 ------------- test/rego/digitalocean_spaces_test.go | 119 ++++++++++++++++++ test/rego/rego_checks_test.go | 8 +- 3 files changed, 124 insertions(+), 92 deletions(-) delete mode 100644 checks/cloud/digitalocean/spaces/acl_no_public_read_test.go create mode 100644 test/rego/digitalocean_spaces_test.go diff --git a/checks/cloud/digitalocean/spaces/acl_no_public_read_test.go b/checks/cloud/digitalocean/spaces/acl_no_public_read_test.go deleted file mode 100644 index 082dcfdd..00000000 --- a/checks/cloud/digitalocean/spaces/acl_no_public_read_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package spaces - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/digitalocean/spaces" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckAclNoPublicRead(t *testing.T) { - tests := []struct { - name string - input spaces.Spaces - expected bool - }{ - { - name: "Space bucket with public read ACL", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - ACL: trivyTypes.String("public-read", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - { - name: "Space bucket object with public read ACL", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), - Objects: []spaces.Object{ - { - Metadata: trivyTypes.NewTestMetadata(), - ACL: trivyTypes.String("public-read", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "Space bucket and bucket object with private ACL", - input: spaces.Spaces{ - Buckets: []spaces.Bucket{ - { - Metadata: trivyTypes.NewTestMetadata(), - ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), - Objects: []spaces.Object{ - { - Metadata: trivyTypes.NewTestMetadata(), - ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.DigitalOcean.Spaces = test.input - results := CheckAclNoPublicRead.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckAclNoPublicRead.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/test/rego/digitalocean_spaces_test.go b/test/rego/digitalocean_spaces_test.go new file mode 100644 index 00000000..ed03b7f3 --- /dev/null +++ b/test/rego/digitalocean_spaces_test.go @@ -0,0 +1,119 @@ +package test + +import ( + "github.com/aquasecurity/trivy/pkg/iac/providers/digitalocean" + "github.com/aquasecurity/trivy/pkg/iac/providers/digitalocean/spaces" + "github.com/aquasecurity/trivy/pkg/iac/state" + trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" +) + +var digitalOceanSpacesTestCases = testCases{ + "AVD-DIG-0006": { + { + name: "Space bucket with public read ACL", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + ACL: trivyTypes.String("public-read", trivyTypes.NewTestMetadata()), + }, + }, + }}}, + expected: true, + }, + { + name: "Space bucket object with public read ACL", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), + Objects: []spaces.Object{ + { + Metadata: trivyTypes.NewTestMetadata(), + ACL: trivyTypes.String("public-read", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "Space bucket and bucket object with private ACL", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), + Objects: []spaces.Object{ + { + Metadata: trivyTypes.NewTestMetadata(), + ACL: trivyTypes.String("private", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-DIG-0009": { + { + name: "Space bucket force destroy enabled", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + ForceDestroy: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }}}, + expected: true, + }, + { + name: "Space bucket force destroy disabled", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + ForceDestroy: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }}}, + expected: false, + }, + }, + "AVD-DIG-0007": { + { + name: "Space bucket versioning disabled", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + Versioning: spaces.Versioning{ + Metadata: trivyTypes.NewTestMetadata(), + Enabled: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "Space bucket versioning enabled", + input: state.State{DigitalOcean: digitalocean.DigitalOcean{Spaces: spaces.Spaces{ + Buckets: []spaces.Bucket{ + { + Metadata: trivyTypes.NewTestMetadata(), + Versioning: spaces.Versioning{ + Metadata: trivyTypes.NewTestMetadata(), + Enabled: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, +} diff --git a/test/rego/rego_checks_test.go b/test/rego/rego_checks_test.go index 182d84f9..72e3864e 100644 --- a/test/rego/rego_checks_test.go +++ b/test/rego/rego_checks_test.go @@ -61,15 +61,17 @@ func TestRegoChecks(t *testing.T) { azureAuthorizationTestCases, azureContainerTestCases, - googleDnsTestCases, + googleDnsTestCases, googleKmsTestCases, googleBigQueryTestCases, - githubTestCases, + githubTestCases, - nifcloudDnsTestCases, + nifcloudDnsTestCases, nifcloudNetworkTestCases, nifcloudSslCertificateTestCases, + + digitalOceanSpacesTestCases, ) regoScanner := rego.NewScanner(trivyTypes.SourceCloud)