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

release: 2023/10/02 #3

Merged
merged 1 commit into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion sdk/rego
Submodule rego updated 96 files
+101 −0 decision/aws/cloudtrail/cloudtrail_cloudwatch_logs_integration.gen.rego
+24 −24 decision/aws/cloudtrail/cloudtrail_cmk_encryption.gen.rego
+107 −0 decision/aws/cloudtrail/cloudtrail_log_bucket_accessibility.gen.rego
+101 −0 decision/aws/cloudtrail/cloudtrail_log_file_validation.gen.rego
+25 −25 decision/aws/cloudtrail/cloudtrail_usage.gen.rego
+104 −0 decision/aws/config/config_recorder_status.gen.rego
+0 −0 decision/aws/ebs/ebs_volume_encryption_baseline.gen.rego
+104 −0 decision/aws/iam/iam_access_analyzers.gen.rego
+107 −0 decision/aws/iam/iam_account_alternate_contact.gen.rego
+110 −0 decision/aws/iam/iam_console_user_keys.gen.rego
+1 −1 decision/aws/iam/iam_credentials_inventory.gen.rego
+102 −0 decision/aws/iam/iam_role_for_support.gen.rego
+1 −1 decision/aws/iam/iam_root_user_key.gen.rego
+104 −0 decision/aws/iam/iam_server_certificates.gen.rego
+101 −0 decision/aws/iam/iam_user_available_access_keys.gen.rego
+102 −0 decision/aws/iam/iam_user_group_permission_assignment.gen.rego
+105 −0 decision/aws/iam/iam_user_mfa.gen.rego
+101 −0 decision/aws/kms/kms_symmetric_cmk_rotation.gen.rego
+101 −0 decision/aws/logmetric/logmetric_bucket_policy_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_cloudtrail_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_cmk_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_config_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_console_auth_failure.gen.rego
+101 −0 decision/aws/logmetric/logmetric_console_root_user_usage.gen.rego
+101 −0 decision/aws/logmetric/logmetric_console_signin_mfa.gen.rego
+101 −0 decision/aws/logmetric/logmetric_iam_policy_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_nacl_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_network_gateway_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_organizations_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_route_table_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_security_group_changes.gen.rego
+101 −0 decision/aws/logmetric/logmetric_unauthorized_api_calls.gen.rego
+101 −0 decision/aws/logmetric/logmetric_vpc_changes.gen.rego
+14 −2 decision/aws/networking/networking_sg_baseline.gen.rego
+1 −1 decision/aws/networking/networking_sg_ingress_v4.gen.rego
+102 −0 decision/aws/networking/networking_vpc_flow_logging.gen.rego
+1 −1 decision/aws/rds/rds_instance_accessibility.gen.rego
+101 −0 decision/aws/s3/s3_bucket_read_trail.gen.rego
+101 −0 decision/aws/s3/s3_bucket_write_trail.gen.rego
+104 −0 decision/aws/securityhub/securityhub_usage.gen.rego
+0 −0 decision/googlecloud/appengine/appengine_http.gen.rego
+0 −0 decision/googlecloud/asset/asset_management.gen.rego
+1 −1 decision/googlecloud/bigquery/bigquery_dataset_encryption_cmek.gen.rego
+1 −1 decision/googlecloud/bigquery/bigquery_table_encryption_cmek.gen.rego
+110 −0 decision/googlecloud/compute/compute_instance_confidential_computing.gen.rego
+1 −1 decision/googlecloud/compute/compute_instance_ip_forwarding.gen.rego
+1 −1 decision/googlecloud/compute/compute_instance_serial_port.gen.rego
+1 −1 decision/googlecloud/compute/compute_instance_shielded_vm.gen.rego
+114 −0 decision/googlecloud/credential/credential_api_keys_restriction.gen.rego
+101 −0 decision/googlecloud/credential/credential_api_keys_rotation.gen.rego
+101 −0 decision/googlecloud/credential/credential_api_keys_scope.gen.rego
+101 −0 decision/googlecloud/credential/credential_api_keys_usage.gen.rego
+24 −24 decision/googlecloud/dataproc/dataproc_encryption_key.gen.rego
+104 −0 decision/googlecloud/functions/functions_environment_variables.gen.rego
+104 −0 decision/googlecloud/iam/iam_service_account_admin_separation.gen.rego
+1 −0 decision/googlecloud/iam/iam_service_account_key.gen.rego
+102 −0 decision/googlecloud/iam/iam_service_account_key_rotation.gen.rego
+104 −0 decision/googlecloud/kms/kms_admin_separation.gen.rego
+25 −25 decision/googlecloud/kms/kms_key_accessibility.gen.rego
+30 −24 decision/googlecloud/kms/kms_key_rotation.gen.rego
+0 −0 decision/googlecloud/logging/logging_api_audit.gen.rego
+107 −0 decision/googlecloud/logging/logging_bucket_retention_policy.gen.rego
+25 −25 decision/googlecloud/logging/logging_full_export.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_audit_config_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_custom_role_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_firewall_rule_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_network_route_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_project_ownership_changes.gen.rego
+24 −24 decision/googlecloud/logmetric/logmetric_sql_config_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_storage_iam_changes.gen.rego
+101 −0 decision/googlecloud/logmetric/logmetric_vpc_network_changes.gen.rego
+2 −1 decision/googlecloud/networking/networking_dns_log.gen.rego
+101 −0 decision/googlecloud/networking/networking_fw_rule_iap.gen.rego
+27 −24 decision/googlecloud/networking/networking_legacy_network.gen.rego
+1 −0 decision/googlecloud/networking/networking_ssh_access.gen.rego
+1 −0 decision/googlecloud/networking/networking_vpc_flow_log.gen.rego
+1 −1 decision/googlecloud/sql/sql_instance_accessibility.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_mysql_local_infile.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_mysql_show_database.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_centralized_logging.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_connections.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_disconnections.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_error_verbosity.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_hostname.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_min_duration_statement.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_min_error_statement.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_min_messages.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_postgresql_log_statement.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_3625_trace_flag.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_contained_db_authentication.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_cross_db_ownership_chaining.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_external_scripts.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_remote_access.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_user_connections.gen.rego
+101 −0 decision/googlecloud/sql/sql_instance_sqlserver_user_options.gen.rego
+64 −0 thirdparty/aws/region.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
aws {
accounts {
cloudTrail {
trails {
metadata {
id
displayName
}
cloudWatchLogGroup {
arn
}
status {
latestCloudWatchLogsDeliveredAt
}

tags {
key
value
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package policy.aws.cloudtrail.cloudwatch_logs_integration

import data.shisho

# this policy checks if the CloudWatch has not logged within the last 1 day
# please adjust the `must_alert_if_not_log_for` variable depending on your needs
must_alert_if_not_log_for := 1

decisions[d] {
account := input.aws.accounts[_]
trail := account.cloudTrail.trails[_]

allowed := has_logs_within_recent_days(trail)
d := shisho.decision.aws.cloudtrail.cloudwatch_logs_integration({
"allowed": allow_if_excluded(allowed, trail),
"subject": trail.metadata.id,
"payload": shisho.decision.aws.cloudtrail.cloudwatch_logs_integration_payload({"integrated": allowed}),
})
}

has_logs_within_recent_days(trail) {
trail.status.latestCloudWatchLogsDeliveredAt == null
} else {
# There is a log group associated with the trail
trail.cloudWatchLogGroup.arn != ""

# The log delivery is still active within the specified days
lat := timestamp_ns(trail.status.latestCloudWatchLogsDeliveredAt)
logged_within_recent_days(lat, must_alert_if_not_log_for)
} else = false

timestamp_ns(t) := 0 {
t == null
} else := time.parse_rfc3339_ns(t)

logged_within_recent_days(ts, d) {
now := time.now_ns()
diff_ns := now - ts

# confirm the difference is less than `d` days
diff_ns < (((1000000000 * 60) * 60) * 24) * d
} else = false

allow_if_excluded(allowed, r) {
data.params != null

tag := data.params.tag_exceptions[_]
elements := split(tag, "=")

tag_key := elements[0]
tag_value := concat("=", array.slice(elements, 1, count(elements)))

t := r.tags[_]
t.key == tag_key
t.value == tag_value
} else := allowed
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package policy.aws.cloudtrail.cloudwatch_logs_integration

import data.shisho
import future.keywords

now_ns := time.now_ns()

today_string := date_string(now_ns)

two_months_ago_string := date_string(time.add_date(now_ns, 0, -2, 0))

date_string(date_ns) := date_as_string if {
date := time.date(date_ns)
date_as_string := sprintf("%d-%s-%sT00:00:00Z", [date[0], format_digit(date[1]), format_digit(date[2])])
}

format_digit(digit) = formatted_digit if {
digit < 10
formatted_digit := sprintf("0%d", [digit])
} else = sprintf("%d", [digit])

test_whether_cloudtrail_is_integrated_with_cloudwatch_logs if {
# check if the CloudTrail is integrated with CloudWatch logs
count([d |
decisions[d]
shisho.decision.is_allowed(d)
]) == 2 with input as {"aws": {"accounts": [{"cloudTrail": {"trails": [
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-1",
"displayName": "test-trail-1",
},
"cloudWatchLogGroup": {"arn": "arn:aws:logs:ap-northeast-1:779392177777:log-group:test-trail-1/CloudTrailLogs:*"},
"status": {"latestCloudWatchLogsDeliveredAt": null},
},
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-2",
"displayName": "test-trail-2",
},
"cloudWatchLogGroup": {"arn": "arn:aws:logs:ap-northeast-1:779392177777:log-group:test-trail-2/CloudTrailLogs:*"},
"status": {"latestCloudWatchLogsDeliveredAt": today_string},
},
]}}]}}

# check if the CloudTrail is not integrated with CloudWatch logs
count([d |
decisions[d]
not shisho.decision.is_allowed(d)
]) == 3 with input as {"aws": {"accounts": [{"cloudTrail": {"trails": [
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-1",
"displayName": "test-trail-1",
},
"cloudWatchLogGroup": {"arn": "arn:aws:logs:ap-northeast-1:779392177777:log-group:test-trail-1/CloudTrailLogs:*"},
"status": {"latestCloudWatchLogsDeliveredAt": ""},
},
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-2",
"displayName": "test-trail-2",
},
"cloudWatchLogGroup": {"arn": "arn:aws:logs:ap-northeast-1:779392177777:log-group:test-trail-2/CloudTrailLogs:*"},
"status": {"latestCloudWatchLogsDeliveredAt": two_months_ago_string},
},
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-3",
"displayName": "test-trail-3",
},
"cloudWatchLogGroup": {"arn": ""},
"status": {"latestCloudWatchLogsDeliveredAt": today_string},
},
]}}]}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
aws {
accounts {
cloudTrail {
trails {
metadata {
id
displayName
}
kmsKeyId

tags {
key
value
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package policy.aws.cloudtrail.cmk_encryption

import data.shisho

decisions[d] {
account := input.aws.accounts[_]
trail := account.cloudTrail.trails[_]

d := shisho.decision.aws.cloudtrail.cmk_encryption({
"allowed": allow_if_excluded(trail.kmsKeyId != "", trail),
"subject": trail.metadata.id,
"payload": shisho.decision.aws.cloudtrail.cmk_encryption_payload({"kms_key_id": trail.kmsKeyId}),
})
}

allow_if_excluded(allowed, r) {
data.params != null

tag := data.params.tag_exceptions[_]
elements := split(tag, "=")

tag_key := elements[0]
tag_value := concat("=", array.slice(elements, 1, count(elements)))

t := r.tags[_]
t.key == tag_key
t.value == tag_value
} else := allowed
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package policy.aws.cloudtrail.cmk_encryption

import data.shisho
import future.keywords

test_whether_cloudtrail_is_encrypted_by_kms_cmk if {
# check if the CloudTrail is encrypted by KMS CMK
count([d |
decisions[d]
shisho.decision.is_allowed(d)
]) == 2 with input as {"aws": {"accounts": [{"cloudTrail": {"trails": [
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-1",
"displayName": "test-trail-1",
},
"kmsKeyId": "arn:aws:kms:ap-northeast-1:779392177777:key/6c7079dc-390c-4724-9e29-920317477777",
},
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-2",
"displayName": "test-trail-2",
},
"kmsKeyId": "arn:aws:kms:ap-northeast-1:779392177777:key/6c7079dc-390c-4724-9e29-920317488888",
},
]}}]}}

# check if the CloudTrail is not encrypted by KMS CMK
count([d |
decisions[d]
not shisho.decision.is_allowed(d)
]) == 2 with input as {"aws": {"accounts": [{"cloudTrail": {"trails": [
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-1",
"displayName": "test-trail-1",
},
"kmsKeyId": "",
},
{
"metadata": {
"id": "aws-cloudtrail-trail|ap-northeast-1|test-trail-2",
"displayName": "test-trail-2",
},
"kmsKeyId": "",
},
]}}]}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
aws {
accounts {
cloudTrail {
trails {
metadata {
id
displayName
}
s3Bucket {
name
aclGrants {
grantee {
displayName
uri
}
permission
}
policy {
rawDocument
}
}

tags {
key
value
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package policy.aws.cloudtrail.log_bucket_accessibility

import data.shisho

decisions[d] {
account := input.aws.accounts[_]
trail := account.cloudTrail.trails[_]

accessible := is_publicly_accessible(trail.s3Bucket)
d := shisho.decision.aws.cloudtrail.log_bucket_accessibility({
"allowed": allow_if_excluded(accessible == false, trail),
"subject": trail.metadata.id,
"payload": shisho.decision.aws.cloudtrail.log_bucket_accessibility_payload({
"bucket_name": trail.s3Bucket.name,
"acl_rules": [{
"grantee_url": grant.grantee.displayName,
"permission": grant.permission,
} |
grant := trail.s3Bucket.aclGrants[_]
],
"bucket_policy_document": trail.s3Bucket.policy.rawDocument,
}),
})
}

is_publicly_accessible(s3Bucket) {
has_insecure_acl_grants(s3Bucket.aclGrants)
} else {
has_insecure_bucket_policy(s3Bucket.policy.rawDocument)
} else = false

has_insecure_acl_grants(grants) {
grant := grants[_]
denied_uris := [
"https://acs.amazonaws.com/groups/global/AllUsers",
"https://acs.amazonaws.com/groups/global/AuthenticatedUsers",
]
denied_uris[_] == grant.grantee.uri
} else = false

has_insecure_bucket_policy(raw_document) {
p := json.unmarshal(raw_document)

statement := p.Statement[_]
statement.Effect == "Allow"
is_public_principal(statement.Principal)
} else = false

is_public_principal(principal) {
principal == "*"
} else {
principal.AWS == "*"
} else = false

allow_if_excluded(allowed, r) {
data.params != null

tag := data.params.tag_exceptions[_]
elements := split(tag, "=")

tag_key := elements[0]
tag_value := concat("=", array.slice(elements, 1, count(elements)))

t := r.tags[_]
t.key == tag_key
t.value == tag_value
} else := allowed
Loading