Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIS 6.2.1 Ensure that the 'log_checkpoints' database flag for Cloud SQL PostgreSQL instance is set to 'on' #410

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions policies/templates/gcp_postgresql_log_checkpoints_v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
apiVersion: templates.gatekeeper.sh/v1alpha1
kind: ConstraintTemplate
metadata:
name: gcp-postgresql-log-checkpoints-v1
spec:
crd:
spec:
names:
kind: GCPPostgreSQLCheckpointsConstraintV1
validation:
openAPIV3Schema:
properties: {}
targets:
validation.gcp.forsetisecurity.org:
rego: | #INLINE("validator/postgresql_log_checkpoints.rego")
#
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

package templates.gcp.GCPPostgreSQLCheckpointsConstraintV1

import data.validator.gcp.lib as lib

# A violation is generated only when the rule body evaluates to true.
deny[{
"msg": message,
"details": metadata,
}] {
constraint := input.constraint
lib.get_constraint_params(constraint, params)
asset := input.asset
asset.asset_type == "sqladmin.googleapis.com/Instance"
instance := asset.resource.data
key = "log_checkpoints"

# get instance settings
settings := lib.get_default(instance, "settings", {"databaseFlags": []})

# check if key is available and values are as expected
not settings_databaseflags(settings)

message := sprintf("On this resource %v Ensure the required key is '%v' and the value is ON.", [asset.name, key])
metadata := {"resource": asset.name, "key_in_violation": key}
}

# check for log_checkpoints under settings databaseflags - no violation
settings_databaseflags(settings) {
setdata := settings.databaseFlags[_]
setdata.name == "log_checkpoints"
setdata.value != "on"
}
#ENDINLINE
27 changes: 27 additions & 0 deletions samples/postgresql_log_checkpoints.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
apiVersion: constraints.gatekeeper.sh/v1alpha1
kind: GCPPostgreSQLCheckpointsConstraintV1
metadata:
name: postgresql_log_checkpoints
annotations:
bundles.validator.forsetisecurity.org/cis-v1.1: 6.2.1
description: Checks if the 'log_checkpoints' database flag for Cloud SQL PostgreSQL instance is set to 'on'
spec:
severity: high
match:
gcp:
target: ["organization/*"]
parameters: {}
48 changes: 48 additions & 0 deletions validator/postgresql_log_checkpoints.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

package templates.gcp.GCPPostgreSQLCheckpointsConstraintV1

import data.validator.gcp.lib as lib

# A violation is generated only when the rule body evaluates to true.
deny[{
"msg": message,
"details": metadata,
}] {
constraint := input.constraint
lib.get_constraint_params(constraint, params)
asset := input.asset
asset.asset_type == "sqladmin.googleapis.com/Instance"
instance := asset.resource.data
key = "log_checkpoints"

# get instance settings
settings := lib.get_default(instance, "settings", {"databaseFlags": []})

# check if key is available and values are as expected
not settings_databaseflags(settings)

message := sprintf("On this resource %v Ensure the required key is '%v' and the value is ON.", [asset.name, key])
metadata := {"resource": asset.name, "key_in_violation": key}
}

# check for log_checkpoints under settings databaseflags - no violation
settings_databaseflags(settings) {
setdata := settings.databaseFlags[_]
setdata.name == "log_checkpoints"
setdata.value != "on"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't you looking for cases where it is on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morgante I am looking for the case where it is ON condition. Fixed it for the corresponding key value.

}
51 changes: 51 additions & 0 deletions validator/postgresql_log_checkpoints_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package templates.gcp.GCPPostgreSQLCheckpointsConstraintV1

import data.validator.gcp.lib as lib
import data.validator.test_utils as test_utils

import data.test.fixtures.postgresql_log_checkpoints.assets.no_settings as fixture_no_settings
import data.test.fixtures.postgresql_log_checkpoints.assets.no_violations as fixture_no_violation
import data.test.fixtures.postgresql_log_checkpoints.assets.violations as fixture_violation

import data.test.fixtures.postgresql_log_checkpoints.constraints as fixture_constraint

template_name := "GCPPostgreSQLCheckpointsConstraintV1"

#1. postgresql with correct key
test_postgresql_log_checkpoints_no_violations {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test / fixture is confusingly named and I'm not sure if the logic is right. If it's meant to have no violations, you should not be expecting a violation. Please update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morgante I have fixed the naming for the correct key we are checking.

expected_resource_names := {"//cloudsql.googleapis.com/projects/my-test-project/instances/tf-pg-ha-62380f9c-no-violation"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you expecting this fixture to raise a violation? If so, it should not be called "with_correctkey" and you definitely should not expect a resource called "no-violation" to raise a violation. Either your naming or logic is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morgante This case(postgresql with correct key) don't raise a violation in our case. So I have removed the test case since it's not needed. Violated test cases alone is attached. Hope this is Ok. Please review it.

test_utils.check_test_violations_count(fixture_no_violation, [fixture_constraint], template_name, 1)
test_utils.check_test_violations_resources(fixture_no_violation, [fixture_constraint], template_name, expected_resource_names)
}

#2. postgresql without correct key
test_postgresql_log_checkpoints_violations {
expected_resource_names := {"//cloudsql.googleapis.com/projects/my-test-project/instances/tf-pg-ha-62380f9c-violation"}
test_utils.check_test_violations_count(fixture_violation, [fixture_constraint], template_name, 1)
test_utils.check_test_violations_resources(fixture_violation, [fixture_constraint], template_name, expected_resource_names)
}

#3. An instance without settings configured at all (settings doesn't exist).
test_postgresql_log_checkpoints_no_settings {
expected_resource_names := {"//cloudsql.googleapis.com/projects/my-test-project/instances/tf-pg-ha-62380f9c-no-settings"}
expected_field_name := "key_in_violation"
expected_field_values := {"log_checkpoints"}
test_utils.check_test_violations_count(fixture_no_settings, [fixture_constraint], template_name, 1)
test_utils.check_test_violations_resources(fixture_no_settings, [fixture_constraint], template_name, expected_resource_names)
test_utils.check_test_violations_metadata(fixture_no_settings, [fixture_constraint], template_name, expected_field_name, expected_field_values)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
[
{
"name": "//cloudsql.googleapis.com/projects/my-test-project/instances/tf-pg-ha-62380f9c-no-settings",
"asset_type": "sqladmin.googleapis.com/Instance",
"ancestry_path": "organization/614830067722/folder/561421552790/project/my-test-project",
"resource": {
"version": "v1beta4",
"discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/sqladmin/v1beta4/rest",
"discovery_name": "DatabaseInstance",
"parent": "//cloudresourcemanager.googleapis.com/projects/my-test-project",
"data": {
"databaseVersion": "POSTGRES_13",
"name": "tf-pg-ha-62380f9c-no-settings",
"project": "my-test-project",
"region": "us-central1",
"settings": {

}
}
}
},
{
"name": "//compute.googleapis.com/projects/my-test-project/zones/us-central1-f/instances/test-jumphost",
"asset_type": "compute.googleapis.com/Instance",
"ancestry_path": "organization/614830067722/folder/561421552790/project/my-test-project",
"resource": {
"version": "v1",
"discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
"discovery_name": "Instance",
"parent": "//cloudresourcemanager.googleapis.com/projects/my-test-project",
"data": {
"canIpForward": false,
"deletionProtection": false,
"disks": [
{
"autoDelete": true,
"boot": true,
"initializeParams": {
"diskSizeGb": "20",
"diskType": "projects/my-test-project/zones/us-central1-f/diskTypes/pd-standard",
"sourceImage": "projects/centos-cloud/global/images/centos-8-v20210512"
},
"mode": "READ_WRITE"
}
],
"displayDevice": {
"enableDisplay": false
},
"machineType": "projects/my-test-project/zones/us-central1-f/machineTypes/e2-micro",
"metadata": {
"items": [
{
"key": "block-project-ssh-keys",
"value": "true"
},
{
"key": "enable-oslogin",
"value": "false"
},
{
"key": "environment",
"value": "dev"
},
{
"key": "name",
"value": "test-jumphost"
},
{
"key": "serial-port-enable",
"value": "false"
},
{
"key": "startup-script",
"value": "echo instance created through terraform \u003e /readme.txt"
}
]
},
"name": "test-jumphost",
"networkInterfaces": [
{
"accessConfigs": [
{
"type": "ONE_TO_ONE_NAT"
}
],
"subnetwork": "projects/my-test-project/regions/us-central1/subnetworks/primary-dmz-subnet"
}
],
"scheduling": {
"automaticRestart": true
},
"serviceAccounts": [
{
"email": "default",
"scopes": [
"https://www.googleapis.com/auth/cloud-platform"
]
}
],
"shieldedInstanceConfig": {
"enableIntegrityMonitoring": true,
"enableSecureBoot": false,
"enableVtpm": true
},
"tags": {
"items": [
"ingress-inet",
"egress-inet"
]
}
}
}
}
]
Loading