diff --git a/docs/howto/features/buckets.md b/docs/howto/features/buckets.md index b888f4614a..a404ebfeaa 100644 --- a/docs/howto/features/buckets.md +++ b/docs/howto/features/buckets.md @@ -233,9 +233,14 @@ primarily for large data transfer from on-premise systems. Since [Google Groups](https://groups.google.com) can be used to control access to GCS buckets, it can be used to allow arbitrary users to write to the bucket! -1. With your `2i2c.org` google account, go to [Google Groups](https://groups.google.com) and create a new Google Group with the name - "{bucket-name}-writers", where "{bucket-name}" is the name of the bucket - we are going to grant write access to. +1. With your `2i2c.org` google account, go to [Google Groups](https://groups.google.com) + and create a new Google Group with the name "{bucket-name}-writers" and email + "{bucket-name}-writers@googlegroups.com", where "{bucket-name}" is the name + of the bucket we are going to grant write access to. + + Use of `@googlegroups.com` instead of `@2i2c.org` is suitable as this group + will include non-2i2c members, who otherwise could get control of a 2i2c.org + email which isn't a necessary security compromise. 2. Grant "Group Owner" access to the community champion requesting this feature. They will be able to add / remove users from the group as necessary, and diff --git a/terraform/gcp/buckets.tf b/terraform/gcp/buckets.tf index 00e985343a..a45b831ca9 100644 --- a/terraform/gcp/buckets.tf +++ b/terraform/gcp/buckets.tf @@ -122,6 +122,21 @@ resource "google_storage_bucket_iam_member" "extra_admin_members" { member = each.value.member } +// Being storage admin isn't sufficient to do work against a bucket, they need +// "service usage consumer" as well. The service usage consumer part can be +// restricted to a specific bucket, which this IAM member accomplishes. +resource "google_project_iam_member" "extra_admin_members" { + for_each = { for bm in local.bucket_extra_admin_members : "${bm.bucket_name}.${bm.member}" => bm } + project = var.project_id + role = "roles/serviceusage.serviceUsageConsumer" + member = each.value.member + + condition { + title = "Allow work against bucket ${google_storage_bucket.user_buckets[each.value.bucket_name].name}" + expression = "resource.type == \"storage.googleapis.com/Bucket\" && resource.name.startsWith(\"projects/_/buckets/${google_storage_bucket.user_buckets[each.value.bucket_name].name}\")" + } +} + resource "google_storage_bucket_iam_member" "public_access" { for_each = { for k, v in var.user_buckets : k => v if v.public_access } bucket = google_storage_bucket.user_buckets[each.key].name