Skip to content

Commit 94ecbe5

Browse files
committed
Add policy pack - Validate GCP > Service Account for any unapproved role association. Closes #886
1 parent 266a97a commit 94ecbe5

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resource "turbot_policy_pack" "main" {
2+
title = "Enforce GCP IAM Service Accounts have Permitted Roles assigned"
3+
description = "Ensures that service accounts do not have disallowed roles assigned. This reduces the risk of over-privileged access and enhances security by enforcing least privilege principles for service accounts."
4+
akas = ["gcp_iam_enforce_service_accounts_have_permitted_roles_assigned"]
5+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# GCP > IAM > Service Account > Approved
2+
resource "turbot_policy_setting" "gcp_iam_service_account_approved" {
3+
resource = turbot_policy_pack.main.id
4+
type = "tmod:@turbot/gcp-iam#/policy/types/serviceAccountApproved"
5+
value = "Check: Approved"
6+
# value = "Enforce: Delete unapproved if new"
7+
# value = "Enforce: Disable unapproved"
8+
}
9+
10+
# GCP > IAM > Service Account > Approved > Custom
11+
resource "turbot_policy_setting" "gcp_iam_service_account_approved_custom" {
12+
resource = turbot_policy_pack.main.id
13+
type = "tmod:@turbot/gcp-iam#/policy/types/serviceAccountApprovedCustom"
14+
template_input = <<-EOT
15+
{
16+
resources(
17+
filter: "resourceTypeId:tmod:@turbot/gcp-iam#/resource/types/projectIamPolicy resourceId:{{ $.resource.parent.turbot.id }}"
18+
) {
19+
items {
20+
projectBindings: get(path: "bindings")
21+
}
22+
}
23+
resource {
24+
email: get(path:"email")
25+
disabled: get(path:"disabled")
26+
}
27+
}
28+
EOT
29+
template = <<-EOT
30+
{%- set disallowedRoles = [
31+
"roles/editor",
32+
"roles/owner",
33+
"roles/viewer",
34+
"roles/resourcemanager.tagUser",
35+
"roles/resourcemanager.tagAdmin",
36+
"roles/iam.serviceAccountTokenCreator",
37+
"roles/iam.serviceAccountUser"
38+
] -%}
39+
40+
{%- set email = $.resource.email -%}
41+
{%- set isDisabled = $.resource.disabled == true -%}
42+
{%- set assignedDisallowedRoles = [] -%}
43+
44+
{%- if not isDisabled -%} {# If the service account is not disabled, check for disallowed roles #}
45+
{%- for binding in $.resources.items[0].projectBindings -%}
46+
{%- if binding.role in disallowedRoles -%}
47+
{%- for member in binding.members -%}
48+
{%- if member == "serviceAccount:" + email -%}
49+
{%- set assignedDisallowedRoles = assignedDisallowedRoles.concat([binding.role]) -%}
50+
{%- endif -%}
51+
{%- endfor -%}
52+
{%- endif -%}
53+
{%- endfor -%}
54+
{%- endif -%}
55+
56+
{%- if isDisabled -%}
57+
- "title": "Role Bindings"
58+
"result": "Approved"
59+
"message": "The service account is disabled."
60+
{%- elif assignedDisallowedRoles | length > 0 -%}
61+
- "title": "Role Bindings"
62+
"result": "Not approved"
63+
"message": "The service account has disallowed role(s): {{ assignedDisallowedRoles | join(", ") }} assigned."
64+
{%- else -%}
65+
- "title": "Role Bindings"
66+
"result": "Approved"
67+
"message": "The service account does not have any disallowed roles assigned."
68+
{%- endif -%}
69+
EOT
70+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
terraform {
2+
required_providers {
3+
turbot = {
4+
source = "turbot/turbot"
5+
version = ">= 1.11.0"
6+
}
7+
}
8+
}
9+
10+
provider "turbot" {
11+
}

0 commit comments

Comments
 (0)