Skip to content

Commit

Permalink
Merge pull request #5 from truefoundry/restrict-gcp-sa-permissions
Browse files Browse the repository at this point in the history
Reduced GCP SA permission scope
  • Loading branch information
dunefro authored May 10, 2024
2 parents e594daa + 2fe01dc commit 1952838
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 30 deletions.
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,31 @@ Truefoundry Google Cloud platform features module

## Providers

No providers.
| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | 4.81.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_blob_storage"></a> [blob\_storage](#module\_blob\_storage) | terraform-google-modules/cloud-storage/google//modules/simple_bucket | 4.0.1 |
| <a name="module_service_accounts"></a> [service\_accounts](#module\_service\_accounts) | terraform-google-modules/service-accounts/google | 4.2.1 |

## Resources

No resources.
| Name | Type |
|------|------|
| [google_project_iam_custom_role.truefoundry_platform_feature_gcs_bucket_role](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_custom_role) | resource |
| [google_project_iam_custom_role.truefoundry_platform_feature_secret_manager_role](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_custom_role) | resource |
| [google_project_iam_member.truefoundry_platform_feature_artifact_registry_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.truefoundry_platform_feature_container_cluster_viewer_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.truefoundry_platform_feature_container_viewer_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.truefoundry_platform_feature_gcs_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.truefoundry_platform_feature_secret_manager_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.truefoundry_platform_feature_token_creator_role_binding](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/project_iam_member) | resource |
| [google_service_account.truefoundry_platform_feature_service_account](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/service_account) | resource |
| [google_service_account_key.truefoundry_platform_feature_service_account_key](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/resources/service_account_key) | resource |
| [google_project.truefoundry_platform_feature_project](https://registry.terraform.io/providers/hashicorp/google/4.81.0/docs/data-sources/project) | data source |

## Inputs

Expand All @@ -48,7 +61,6 @@ No resources.
| <a name="output_artifact_registry_url"></a> [artifact\_registry\_url](#output\_artifact\_registry\_url) | Artifact registry URL to connect |
| <a name="output_bucket_name"></a> [bucket\_name](#output\_bucket\_name) | Name of the bucket |
| <a name="output_bucket_url"></a> [bucket\_url](#output\_bucket\_url) | URL of the bucket |
| <a name="output_serviceaccount_keys"></a> [serviceaccount\_keys](#output\_serviceaccount\_keys) | Service account keys |
| <a name="output_serviceaccount_key"></a> [serviceaccount\_key](#output\_serviceaccount\_key) | Service account keys |
| <a name="output_serviceaccount_name"></a> [serviceaccount\_name](#output\_serviceaccount\_name) | Name of the service account |
| <a name="output_serviceaccount_roles"></a> [serviceaccount\_roles](#output\_serviceaccount\_roles) | Roles assigned to the TrueFoundry paltform GCP service account |
<!-- END_TF_DOCS -->
1 change: 1 addition & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data "google_project" "truefoundry_platform_feature_project" {}
132 changes: 122 additions & 10 deletions iam.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,122 @@
module "service_accounts" {
source = "terraform-google-modules/service-accounts/google"
version = "4.2.1"
project_id = var.project
names = [local.serviceaccount_name]
descriptions = ["Truefoundry platform user with access to artifact registry, blob storage and secrets manager"]
display_name = "Terraform-managed truefoundry platform service account"
generate_keys = true
project_roles = local.serviceaccount_roles
}
// service account for truefoundry platform feature
resource "google_service_account" "truefoundry_platform_feature_service_account" {
account_id = local.serviceaccount_name
project = var.project
display_name = "Terraform-managed truefoundry platform service account"
description = "Truefoundry platform user with access to artifact registry, blob storage and secrets manager"
}

// custom role for secret manager
resource "google_project_iam_custom_role" "truefoundry_platform_feature_secret_manager_role" {
count = var.feature_secrets_enabled ? 1 : 0

role_id = replace("${local.trufoundry_platform_resources}_bucket_secret_manager_tfy_role", "-", "_")
title = replace("${local.trufoundry_platform_resources}_bucket_secret_manager_tfy_role", "-", "_")
description = "TrueFoundry platform feature role to manage secrets in GSM"
permissions = [
"secretmanager.secrets.get",
"secretmanager.secrets.list",
"secretmanager.secrets.create",
"secretmanager.secrets.delete",
"secretmanager.secrets.update",
"secretmanager.versions.access",
"resourcemanager.projects.get",
]
}

// custom role for GCS
resource "google_project_iam_custom_role" "truefoundry_platform_feature_gcs_bucket_role" {
count = var.feature_blob_storage_enabled ? 1 : 0

role_id = replace("${local.trufoundry_platform_resources}_bucket_gcs_tfy_role", "-", "_")
title = replace("${local.trufoundry_platform_resources}_bucket_gcs_tfy_role", "-", "_")
description = "TrueFoundry platform feature role to manage GCS bucket"
permissions = [
"storage.objects.create",
"storage.objects.delete",
"storage.objects.get",
"storage.objects.list",
"storage.objects.update",
"storage.buckets.create",
"storage.buckets.get",
"storage.buckets.list",
"storage.buckets.create",
"storage.buckets.update",
"storage.multipartUploads.create",
"storage.multipartUploads.list",
"storage.multipartUploads.listParts",
"storage.multipartUploads.abort",
"resourcemanager.projects.get"
]
}

// custom role binding with condition for secret manager role
resource "google_project_iam_member" "truefoundry_platform_feature_secret_manager_role_binding" {
count = var.feature_secrets_enabled ? 1 : 0

project = var.project
role = google_project_iam_custom_role.truefoundry_platform_feature_secret_manager_role[count.index].id
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"

condition {
title = "Condition to allow access to secrets starting with 'tfy'"
description = "TrueFoundry platform feature role to allows access to secrets that start with 'tfy'"
expression = "resource.name.startsWith('projects/${data.google_project.truefoundry_platform_feature_project.number}/secrets/tfy')"
}
}

// custom role binding with condition for GCS role
resource "google_project_iam_member" "truefoundry_platform_feature_gcs_role_binding" {
count = var.feature_blob_storage_enabled ? 1 : 0

project = var.project
role = google_project_iam_custom_role.truefoundry_platform_feature_gcs_bucket_role[count.index].id
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"

condition {
title = "Condition to allow access to truefoundry bucket"
description = "TrueFoundry platform feature role to allows access to buckets that start with 'tfy'"
expression = "resource.name.startsWith('projects/_/buckets/${module.blob_storage[0].name}')"
}
}

// role binding token creator role to service account
resource "google_project_iam_member" "truefoundry_platform_feature_token_creator_role_binding" {
count = var.feature_blob_storage_enabled ? 1 : 0

project = var.project
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"
}

// role binding artifact registry role to service account
resource "google_project_iam_member" "truefoundry_platform_feature_artifact_registry_role_binding" {
count = var.feature_docker_registry_enabled ? 1 : 0

project = var.project
role = "roles/artifactregistry.admin"
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"
}

// role binding container cluster viewer role to service account
resource "google_project_iam_member" "truefoundry_platform_feature_container_cluster_viewer_role_binding" {
count = var.feature_cloud_integration_enabled ? 1 : 0

project = var.project
role = "roles/container.clusterViewer"
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"
}

// role binding container viewer role to service account
resource "google_project_iam_member" "truefoundry_platform_feature_container_viewer_role_binding" {
count = var.feature_cloud_integration_enabled ? 1 : 0

project = var.project
role = "roles/container.viewer"
member = "serviceAccount:${google_service_account.truefoundry_platform_feature_service_account.email}"
}

// service account key
resource "google_service_account_key" "truefoundry_platform_feature_service_account_key" {
service_account_id = google_service_account.truefoundry_platform_feature_service_account.id
}
9 changes: 1 addition & 8 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,4 @@ locals {
trufoundry_platform_resources = "${var.cluster_name}-platform"
truefoundry_blob_storage_name = var.blob_storage_enable_override ? var.blob_storage_override_name : "${local.trufoundry_platform_resources}-bucket"
serviceaccount_name = trimsuffix(substr("${local.trufoundry_platform_resources}-user", 0, 30), "-")
serviceaccount_roles = concat(
var.feature_docker_registry_enabled ? ["${var.project}=>roles/artifactregistry.admin"] : [],
var.feature_secrets_enabled ? ["${var.project}=>roles/secretmanager.admin"] : [],
var.feature_blob_storage_enabled ? ["${var.project}=>roles/iam.serviceAccountTokenCreator"] : [],
var.feature_blob_storage_enabled ? ["${var.project}=>roles/storage.admin"] : [],
var.feature_cloud_integration_enabled ? ["${var.project}=>roles/container.clusterViewer", "${var.project}=>roles/container.viewer"] : []
)
}
}
10 changes: 3 additions & 7 deletions output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@ output "artifact_registry_url" {
################################################################################

output "serviceaccount_name" {
value = module.service_accounts.service_accounts_map
value = local.serviceaccount_name
description = "Name of the service account"
}
output "serviceaccount_keys" {
value = module.service_accounts.keys
output "serviceaccount_key" {
value = google_service_account_key.truefoundry_platform_feature_service_account_key.private_key
sensitive = true
description = "Service account keys"
}

output "serviceaccount_roles" {
value = local.serviceaccount_roles
description = "Roles assigned to the TrueFoundry paltform GCP service account"
}

0 comments on commit 1952838

Please sign in to comment.