diff --git a/google_project/README.md b/google_project/README.md index e99323e7..71b0ff50 100644 --- a/google_project/README.md +++ b/google_project/README.md @@ -23,7 +23,8 @@ Sets up a single GCP project linked to a billing account plus management metadat | [project\_name](#input\_project\_name) | Name of project e.g., autopush | `string` | n/a | yes | | [project\_services](#input\_project\_services) | List of google\_project\_service APIs to enable. | `list(string)` | `[]` | no | | [realm](#input\_realm) | Realm is a grouping of environments being one of: global, nonprod, prod | `string` | `""` | no | -| [risk\_level](#input\_risk\_level) | Level of risk the project poses, usually obtained from an RRA | `string` | `""` | no | +| [risk\_level](#input\_risk\_level) | DEPRECATED - Level of risk the project poses, usually obtained from an RRA | `string` | `""` | no | +| [risk\_profile](#input\_risk\_profile) | Risk profile of the project, used by the Wiz security platform |
object({
has_authentication = string
has_exposed_api = string
is_actively_developed = string
is_customer_facing = string
is_internet_facing = string
is_regulated = string
regulatory_standards = list(string)
sensitive_data_types = list(string)
stores_data = string
}) | {
"has_authentication": "UNKNOWN",
"has_exposed_api": "UNKNOWN",
"is_actively_developed": "UNKNOWN",
"is_customer_facing": "UNKNOWN",
"is_internet_facing": "UNKNOWN",
"is_regulated": "UNKNOWN",
"regulatory_standards": [],
"sensitive_data_types": [],
"stores_data": "UNKNOWN"
} | no |
## Outputs
diff --git a/google_project/locals.tf b/google_project/locals.tf
index 21b69f48..8647616d 100644
--- a/google_project/locals.tf
+++ b/google_project/locals.tf
@@ -7,6 +7,22 @@ locals {
app_code = coalesce(var.app_code, var.project_name)
component_code = coalesce(var.component_code, "${local.app_code}-uncat")
+ # Helper locals for truncation of risk profile lists to 63 characters
+ regulatory_standards_joined = join(",", var.risk_profile.regulatory_standards)
+ sensitive_data_types_joined = join(",", var.risk_profile.sensitive_data_types)
+
+ normalized_risk_profile = {
+ has_authentication = upper(var.risk_profile.has_authentication)
+ has_exposed_api = upper(var.risk_profile.has_exposed_api)
+ is_actively_developed = upper(var.risk_profile.is_actively_developed)
+ is_customer_facing = upper(var.risk_profile.is_customer_facing)
+ is_internet_facing = upper(var.risk_profile.is_internet_facing)
+ is_regulated = upper(var.risk_profile.is_regulated)
+ stores_data = upper(var.risk_profile.stores_data)
+ regulatory_standards = length(local.regulatory_standards_joined) > 63 ? substr(local.regulatory_standards_joined, 0, 63) : local.regulatory_standards_joined
+ sensitive_data_types = length(local.sensitive_data_types_joined) > 63 ? substr(local.sensitive_data_types_joined, 0, 63) : local.sensitive_data_types_joined
+ }
+
default_project_labels = {
app = var.project_name
app_code = local.app_code
@@ -17,7 +33,7 @@ locals {
realm = var.realm
risk_level = var.risk_level
}
- all_project_labels = merge(local.default_project_labels, var.extra_project_labels)
+ all_project_labels = merge(local.default_project_labels, var.extra_project_labels, local.normalized_risk_profile)
default_project_services = [
"cloudasset.googleapis.com",
@@ -38,3 +54,18 @@ locals {
default_data_access_logs = ["iam.googleapis.com", "secretmanager.googleapis.com", "sts.googleapis.com", "privilegedaccessmanager.googleapis.com"]
data_access_logs_filter = join("\n", toset([for v in concat(local.default_data_access_logs, var.additional_data_access_logs) : "AND NOT protoPayload.serviceName=\"${v}\""]))
}
+
+# we want to emit a warning when we truncate the lists in the risk profile
+check "risk_profile_truncation" {
+ assert {
+ condition = length(local.regulatory_standards_joined) <= 63
+ error_message = "Warning: regulatory_standards list '${local.regulatory_standards_joined}' exceeds 63 characters and will be truncated to '${substr(local.regulatory_standards_joined, 0, 63)}'"
+ }
+}
+
+check "sensitive_data_truncation" {
+ assert {
+ condition = length(local.sensitive_data_types_joined) <= 63
+ error_message = "Warning: sensitive_data_types list '${local.sensitive_data_types_joined}' exceeds 63 characters and will be truncated to '${substr(local.sensitive_data_types_joined, 0, 63)}'"
+ }
+}
\ No newline at end of file
diff --git a/google_project/variables.tf b/google_project/variables.tf
index 513f2666..907e7bb6 100644
--- a/google_project/variables.tf
+++ b/google_project/variables.tf
@@ -63,10 +63,49 @@ variable "extra_project_labels" {
variable "risk_level" {
default = ""
- description = "Level of risk the project poses, usually obtained from an RRA"
+ description = "DEPRECATED - Level of risk the project poses, usually obtained from an RRA"
type = string
}
+variable "risk_profile" {
+ description = "Risk profile of the project, used by the Wiz security platform"
+ type = object({
+ has_authentication = string
+ has_exposed_api = string
+ is_actively_developed = string
+ is_customer_facing = string
+ is_internet_facing = string
+ is_regulated = string
+ regulatory_standards = list(string)
+ sensitive_data_types = list(string)
+ stores_data = string
+ })
+
+ default = {
+ has_authentication = "UNKNOWN"
+ has_exposed_api = "UNKNOWN"
+ is_actively_developed = "UNKNOWN"
+ is_customer_facing = "UNKNOWN"
+ is_internet_facing = "UNKNOWN"
+ is_regulated = "UNKNOWN"
+ regulatory_standards = []
+ sensitive_data_types = []
+ stores_data = "UNKNOWN"
+ }
+
+ // need this so we use default values when not set or set to null
+ nullable = false
+
+ validation {
+ condition = alltrue([
+ for key, value in var.risk_profile :
+ key == "regulatory_standards" || key == "sensitive_data_types" ? true :
+ contains(["UNKNOWN", "YES", "NO"], upper(value))
+ ])
+ error_message = "String values must be one of: UNKNOWN, YES, NO. Lists (regulatory_standards, sensitive_data_types) can contain any strings."
+ }
+}
+
#
# Variables to possibly Archive?
#