Rego VS. Really
We built Really to make it easier to write policy-as-code
Rego is hard to write, and even harder to read. Really is policy-as-code, for humans.
GCP Database Network Config
Rego/OPA
checkRequireSSLEnabled[db_instance.id] {
db_instance := input.google_sql_database_instance[_]
setting := db_instance.config.settings[_]
not setting.ip_configuration
} {
db_instance := input.google_sql_database_instance[_]
setting := db_instance.config.settings[_]
ip_configuration = setting.ip_configuration[_]
not ip_configuration.require_ssl
} {
db_instance := input.google_sql_database_instance[_]
setting := db_instance.config.settings[_]
ip_configuration = setting.ip_configuration[_]
ip_configuration.require_ssl == false
}
checkNoPublicAccess[db_instance.id] {
db_instance := input.google_sql_database_instance[_]
setting := db_instance.config.settings[_]
count(setting.ip_configuration) > 0
ip_configuration = setting.ip_configuration[_]
count(ip_configuration.authorized_networks) > 0
authorized_network = ip_configuration.authorized_networks[_]
authorized_network.value == "0.0.0.0"
}
Really
GUARDRAIL "GCP database network config"
WHEN google_sql_database_instance
REQUIRE settings.ip_configuration HAS
require_ssl = true
NO authorized_networks.value = "0.0.0.0"
Detailed Monitoring for AWS EC2
Rego/OPA
package accurics
{{.prefix}}detailedMonitoringEnabledInstance[instance.id] {
instance := input.aws_instance[_]
object.get(instance.config, "monitoring", "undefined") == "undefined"
}
{{.prefix}}detailedMonitoringEnabledInstance[instance.id] {
instance := input.aws_instance[_]
instance.config.monitoring != true
}
Really
GUARDRAIL "EC2 instance has detailed monitoring enabled"
WHEN aws_instance
REQUIRE detailed_monitoring_enabled = true
Disallow ACLs for AWS S3
Rego/OPA
package terraform
import input.tfplan as tfplan
allowed_acls = ["private"]
allowed_sse_algorithms = ["aws:kms", "AES256"]
s3_buckets[r] {
r := tfplan.resource_changes[_]
r.type == "aws_s3_bucket"
}
array_contains(arr, elem) {
arr[_] = elem
}
# Rule to restrict S3 bucket ACLs
deny[reason] {
r := s3_buckets[_]
not array_contains(allowed_acls, r.change.after.acl)
reason := sprintf(
"%s: ACL %q is not allowed",
[r.address, r.change.after.acl]
)
}
Really
GUARDRAIL "Require private acl"
WHEN aws_s3_bucket
REQUIRE acl = "private"
Require encryption for GCP compute instance disks
Rego/OPA
package rules.tf_google_compute_disk_encryption
import data.fugue
resource_type := "MULTIPLE"
compute_instances = fugue.resources("google_compute_instance")
base_message = "The following disks attached to this instance are not encrypted with a CSEK: %s"
encrypted(disk) {
is_string(disk.disk_encryption_key_sha256)
disk.disk_encryption_key_sha256 != ""
} {
is_string(disk.disk_encryption_key_raw)
disk.disk_encryption_key_raw != ""
}
extract_unencrypted_disks(compute_instance) = ret {
boot = object.get(compute_instance, "boot_disk", [])
attached = object.get(compute_instance, "attached_disk", [])
scratch = object.get(compute_instance, "scratch_disk", [])
ret = [d |
d = array.concat(boot, array.concat(attached, scratch))[_];
not encrypted(d)
]
}
policy[j] {
instance = compute_instances[_]
unencrypted_disks = extract_unencrypted_disks(instance)
count(unencrypted_disks) < 1
j = fugue.allow_resource(instance)
} {
instance = compute_instances[_]
unencrypted_disks = extract_unencrypted_disks(instance)
count(unencrypted_disks) > 0
disk_names = [d.device_name | d = unencrypted_disks[_]]
message = sprintf(base_message, [concat(", ", disk_names)])
j = fugue.deny_resource_with_message(instance, message)
}
Really
GUARDRAIL "Compute instance disks should be encrypted with customer-supplied encryption keys"
WHEN google_compute_instance
REQUIRE EVERY boot_disk.disk_encryption_key_raw EXISTS
REQUIRE EVERY attached_disk.disk_encryption_key_raw EXISTS
REQUIRE EVERY scratch_disk.disk_encryption_key_raw EXISTS
Resourcely helps keep developers shipping fast in a secure fashion, reducing guess work and avoiding incidents that stem from misconfiguration.
Spencer Kimball
CEO/Angel Investor, Cockroach Labs