Google Cloud Granting a service account just enough access to manage a Cloud Identity group

To implement role-based access control to Google Cloud resources, it’s often useful to create a set of groups, where each group represents a role for a certain set of resources. For example, we might create groups such as database reader and database admin that grant access to a set of database-related resources. How can we automate the management of these groups, without granting our automation too much access?

Option 1: Using a delegated admin service account

Groups are a Cloud Identity or Workspace resource, and to manage them, we typically have to be a Super Admin or Groups Admin.

In the old days, it wasn’t possible to assign admin roles such as Groups Admin to service accounts. To let a service account manage groups, we had to allow the service account to use domain-wide delegation to impersonate a user account with the Groups Admin role.

Fortunately, things have become easier and we can now assign (most) admin roles directly to service accounts. So the first, and most obvious way to automate the management of groups is to:

  1. Create a service account for the automation
  2. Assign the Groups Admin role to the service account
  3. Let the service account use either the Directory API or Cloud Identity API to create and manage groups.

That approach works, but isn’t ideal: The service account now has access to all groups, not only the ones it’s supposed to manage.

Option 2: Service account as group owner

For each member of a group, we can decide whether they should be a member, manager, or owner. Owner is the most powerful role and it entitles a user to:

  • delete the group
  • add or remove members
  • make somebody else an owner
  • change the group’s settings

Instead of making a service account a (global) Groups Admin, an alternative approach is therefore to:

  1. Create a service account for the automation
  2. Create a set of groups for the service account to manage
  3. Make the service account Owner for these groups

Compared to the first option, this is a safer approach as the service account’s access is constrained to a select set of groups.

But a drawback of this approach is that we now have to manually create the groups (step 2) before we can delegate their management to the service account.

Option 3: Delegate creation and management

Both of the previous options aren’t ideal. But what if we combine them?

  1. We make the service account a delegated admin – but instead of assigning it the predefined Groups Admin role, we assign it a custom role that only allows creating new groups.
  2. We let the service account assign itself as owner at group creation so that it can then manage the groups it created.

With this configuration, a service account can…

  • create new groups,
  • manage the groups it created, but
  • can’t access any other groups.

Let’s see how we can implement that:

  1. In the Admin Console, create a custom role named Group Creator that only includes a single Admin API privilege:

    Group creator role

  2. Create a service account and assign it the Group Creator role:

    Members

With that setup in place, let’s create a Terraform module that

  1. Impersonates the service account (group-creator-dasa@)
  2. Creates a new group ([email protected]) by using the Cloud Identity Groups API
  3. Makes the service account the initial owner of the group
  4. Adds a member ([email protected]) to the group

In code, this looks like:

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.0.0"
    }
  }
}

provider "google" {
    impersonate_service_account = "group-creator-dasa@PROJECT_ID.iam.gserviceaccount.com"
}

resource "google_cloud_identity_group" "test-group" {
  display_name         = "group-creator-test-1"
  initial_group_config = "WITH_INITIAL_OWNER"
  parent = "customers/C00xxxxx"
  group_key {
      id = "[email protected]"
  }

  labels = {
    "cloudidentity.googleapis.com/groups.discussion_forum" = ""
    "cloudidentity.googleapis.com/groups.security" = ""
  }
}

resource "google_cloud_identity_group_membership" "cloud_identity_group_membership_basic" {
  group    = google_cloud_identity_group.test-group.id
  preferred_member_key {
    id = "[email protected]"
  }

  roles {
      name = "MEMBER"
  }
}

External sharing

If we delegate the management of a group, we also need to think about external members: Somebody might use the automation to add an external member (i.e., a user from a different Cloud Identity or Workspace account, or even a consumer account) to the group.

By default, groups created using the Directory API or Cloud Identity API don’t allow external members. However, we can’t rely on that default if we’ve enabled Groups for Business, because Groups for Business provides separate controls for managing external members. To be on the safe side with Groups for Business, we also need to make sure that the Group owners can allow external members setting is off.

Any opinions expressed on this blog are Johannes' own. Refer to the respective vendor’s product documentation for authoritative information.
« Back to home