diff --git a/policies/templates/gcp_iam_restrict_service_account_key_age_v1.yaml b/policies/templates/gcp_iam_restrict_service_account_key_age_v1.yaml index 1b803f66..8135355c 100644 --- a/policies/templates/gcp_iam_restrict_service_account_key_age_v1.yaml +++ b/policies/templates/gcp_iam_restrict_service_account_key_age_v1.yaml @@ -69,16 +69,23 @@ spec: metadata := {"resource": asset.name, "ancestry_path": ancestry_path} } - check_key_not_expired(key) = check_key_not_expired { + check_key_not_expired(key) { expiry_time := time.parse_rfc3339_ns(lib.get_default(key, "validBeforeTime", "1900-01-01T01:00:006Z")) + expiry_time >= 0 now := time.now_ns() - check_key_not_expired := now < expiry_time + now < expiry_time } - check_key_age(key, max_age) = check_key_age { + # Workaround for dates in the far future - https://github.com/open-policy-agent/opa/issues/4098 + check_key_not_expired(key) { + expiry_time := time.parse_rfc3339_ns(lib.get_default(key, "validBeforeTime", "1900-01-01T01:00:006Z")) + expiry_time < 0 + } + + check_key_age(key, max_age) { created_time := time.parse_rfc3339_ns(lib.get_default(key, "validAfterTime", "2200-01-01T01:00:006Z")) max_age_parsed := time.parse_duration_ns(max_age) key_age := time.now_ns() - created_time - check_key_age := key_age > max_age_parsed + key_age > max_age_parsed } #ENDINLINE diff --git a/validator/gcp_iam_restrict_service_account_key_age.rego b/validator/gcp_iam_restrict_service_account_key_age.rego index a8bbd213..3d158a5a 100644 --- a/validator/gcp_iam_restrict_service_account_key_age.rego +++ b/validator/gcp_iam_restrict_service_account_key_age.rego @@ -37,15 +37,22 @@ deny[{ metadata := {"resource": asset.name, "ancestry_path": ancestry_path} } -check_key_not_expired(key) = check_key_not_expired { +check_key_not_expired(key) { expiry_time := time.parse_rfc3339_ns(lib.get_default(key, "validBeforeTime", "1900-01-01T01:00:006Z")) + expiry_time >= 0 now := time.now_ns() - check_key_not_expired := now < expiry_time + now < expiry_time } -check_key_age(key, max_age) = check_key_age { +# Workaround for dates in the far future - https://github.com/open-policy-agent/opa/issues/4098 +check_key_not_expired(key) { + expiry_time := time.parse_rfc3339_ns(lib.get_default(key, "validBeforeTime", "1900-01-01T01:00:006Z")) + expiry_time < 0 +} + +check_key_age(key, max_age) { created_time := time.parse_rfc3339_ns(lib.get_default(key, "validAfterTime", "2200-01-01T01:00:006Z")) max_age_parsed := time.parse_duration_ns(max_age) key_age := time.now_ns() - created_time - check_key_age := key_age > max_age_parsed + key_age > max_age_parsed } diff --git a/validator/gcp_iam_restrict_service_account_key_age_test.rego b/validator/gcp_iam_restrict_service_account_key_age_test.rego index f5f25159..ac1c4e20 100644 --- a/validator/gcp_iam_restrict_service_account_key_age_test.rego +++ b/validator/gcp_iam_restrict_service_account_key_age_test.rego @@ -24,20 +24,30 @@ import data.test.fixtures.gcp_iam_restrict_service_account_key_age.constraints a # Confirm total violations count test_service_account_key_age_ninety_days_violations_count { - test_utils.check_test_violations_count(fixture_assets, [fixture_constraints.ninety_days], template_name, 2) + test_utils.check_test_violations_count(fixture_assets, [fixture_constraints.ninety_days], template_name, 3) } test_service_account_key_age_one_hundred_days_violations_count { - test_utils.check_test_violations_count(fixture_assets, [fixture_constraints.one_hundred_days], template_name, 2) + test_utils.check_test_violations_count(fixture_assets, [fixture_constraints.one_hundred_days], template_name, 3) } # Confirm violation resources test_service_account_key_age_ninety_days_resources { - resource_names := {"//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover90days", "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100days"} + resource_names := { + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover90days", + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100days", + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100000days", + } + test_utils.check_test_violations(fixture_assets, [fixture_constraints.ninety_days], template_name, resource_names) } test_service_account_key_age_one_hundred_days_resources { - resource_names := {"//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover90days", "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100days"} + resource_names := { + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover90days", + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100days", + "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100000days", + } + test_utils.check_test_violations(fixture_assets, [fixture_constraints.one_hundred_days], template_name, resource_names) } diff --git a/validator/test/fixtures/gcp_iam_restrict_service_account_key_age/assets/data.json b/validator/test/fixtures/gcp_iam_restrict_service_account_key_age/assets/data.json index 15e71148..4fe1a983 100644 --- a/validator/test/fixtures/gcp_iam_restrict_service_account_key_age/assets/data.json +++ b/validator/test/fixtures/gcp_iam_restrict_service_account_key_age/assets/data.json @@ -21,6 +21,17 @@ } } }, + { + "asset_type": "iam.googleapis.com/ServiceAccountKey", + "name": "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyageover100000days", + "resource": { + "data": { + "validAfterTime": "2018-03-24T10:00:00Z", + "validBeforeTime": "2999-08-22T19:55:36Z", + "keyAlgorithm": "KEY_ALG_RSA_2048" + } + } + }, { "asset_type": "iam.googleapis.com/ServiceAccountKey", "name": "//iam.googleapis.com/projects/forseti-system-test/serviceAccounts/111111-compute@developer.gserviceaccount.com/keys/testkeyagefuture",