Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:51:02 +08:00
commit ff1f4bd119
252 changed files with 72682 additions and 0 deletions

View File

@@ -0,0 +1,223 @@
package terraform.security
import future.keywords.if
# AWS S3 Bucket Security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not has_encryption(resource)
msg := {
"resource": resource.name,
"type": "aws_s3_bucket",
"severity": "high",
"violation": "S3 bucket must have encryption enabled",
"remediation": "Add server_side_encryption_configuration block",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not has_versioning(resource)
msg := {
"resource": resource.name,
"type": "aws_s3_bucket",
"severity": "medium",
"violation": "S3 bucket should have versioning enabled",
"remediation": "Add versioning configuration with enabled = true",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket_public_access_block"
resource.change.after.block_public_acls == false
msg := {
"resource": resource.name,
"type": "aws_s3_bucket_public_access_block",
"severity": "high",
"violation": "S3 bucket must block public ACLs",
"remediation": "Set block_public_acls = true",
}
}
has_encryption(resource) {
resource.change.after.server_side_encryption_configuration
}
has_versioning(resource) {
resource.change.after.versioning[_].enabled == true
}
# AWS EC2 Security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_instance"
not resource.change.after.metadata_options.http_tokens == "required"
msg := {
"resource": resource.name,
"type": "aws_instance",
"severity": "high",
"violation": "EC2 instance must use IMDSv2",
"remediation": "Set metadata_options.http_tokens = required",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_instance"
resource.change.after.associate_public_ip_address == true
is_production
msg := {
"resource": resource.name,
"type": "aws_instance",
"severity": "high",
"violation": "Production EC2 instances cannot have public IPs",
"remediation": "Set associate_public_ip_address = false",
}
}
is_production {
input.variables.environment == "production"
}
# AWS RDS Security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_db_instance"
not resource.change.after.storage_encrypted
msg := {
"resource": resource.name,
"type": "aws_db_instance",
"severity": "high",
"violation": "RDS instance must have encryption enabled",
"remediation": "Set storage_encrypted = true",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_db_instance"
resource.change.after.publicly_accessible == true
msg := {
"resource": resource.name,
"type": "aws_db_instance",
"severity": "critical",
"violation": "RDS instance cannot be publicly accessible",
"remediation": "Set publicly_accessible = false",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_db_instance"
backup_retention := resource.change.after.backup_retention_period
backup_retention < 7
msg := {
"resource": resource.name,
"type": "aws_db_instance",
"severity": "medium",
"violation": "RDS instance must have at least 7 days backup retention",
"remediation": "Set backup_retention_period >= 7",
}
}
# AWS IAM Security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_iam_policy"
statement := resource.change.after.policy.Statement[_]
statement.Action[_] == "*"
msg := {
"resource": resource.name,
"type": "aws_iam_policy",
"severity": "high",
"violation": "IAM policy cannot use wildcard actions",
"remediation": "Specify explicit actions instead of *",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_iam_policy"
statement := resource.change.after.policy.Statement[_]
statement.Resource[_] == "*"
statement.Effect == "Allow"
msg := {
"resource": resource.name,
"type": "aws_iam_policy",
"severity": "high",
"violation": "IAM policy cannot use wildcard resources with Allow",
"remediation": "Specify explicit resource ARNs",
}
}
# AWS Security Group Rules
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_security_group_rule"
resource.change.after.type == "ingress"
resource.change.after.from_port == 22
is_open_to_internet(resource.change.after.cidr_blocks)
msg := {
"resource": resource.name,
"type": "aws_security_group_rule",
"severity": "critical",
"violation": "Security group allows SSH from internet",
"remediation": "Restrict SSH access to specific IP ranges",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_security_group_rule"
resource.change.after.type == "ingress"
resource.change.after.from_port == 3389
is_open_to_internet(resource.change.after.cidr_blocks)
msg := {
"resource": resource.name,
"type": "aws_security_group_rule",
"severity": "critical",
"violation": "Security group allows RDP from internet",
"remediation": "Restrict RDP access to specific IP ranges",
}
}
is_open_to_internet(cidr_blocks) {
cidr_blocks[_] == "0.0.0.0/0"
}
# AWS KMS Security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_kms_key"
not resource.change.after.enable_key_rotation
msg := {
"resource": resource.name,
"type": "aws_kms_key",
"severity": "medium",
"violation": "KMS key must have automatic rotation enabled",
"remediation": "Set enable_key_rotation = true",
}
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_kms_key"
deletion_window := resource.change.after.deletion_window_in_days
deletion_window < 30
msg := {
"resource": resource.name,
"type": "aws_kms_key",
"severity": "medium",
"violation": "KMS key deletion window must be at least 30 days",
"remediation": "Set deletion_window_in_days >= 30",
}
}