Skip to content

GCP Identity and Access Management (IAM)

What is IAM?

IAM stands for Identity and Access Management. IAM is a service that allows you to manage access control and permissions for resources within GCP.

Roles in IAM

There are three types of IAM roles in GCP:

  1. Primitive roles: These are predefined roles that grant basic access to GCP resources, such as Owner, Editor, and Viewer. These roles have broad permissions, and they are not recommended for production environments.
  2. Predefined roles: These roles provide more granular access to specific GCP services and resources. Predefined roles are designed to cover common use cases, such as read-only access to GCE instances or management of Cloud Storage buckets. These roles cannot be modified but can be used in conjunction with custom roles.
  3. Custom roles: These roles are created by the user and provide fine-grained access control to GCP resources. Custom roles are built by selecting specific permissions from a set of predefined permissions in GCP. They are more flexible than predefined roles and can be tailored to fit specific use cases.

You can read all roles here: documentation

Lets check IAM misconfigurations:

Check for IAM Members with Service Roles at the Project Level

To follow Google Cloud security best practices, Google Cloud Platform (GCP) IAM users should not have assigned the Service Account User or Service Account Token Creator roles at the GCP project level. Instead, these roles should be allocated to a user associated with a specific service account, providing that user access to the service account only.

To determine if there are IAM users/members associated with Service Account User and/or Service Account Token Creator roles at the GCP project level, perform the following actions:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list  --format="table(projectId)"

2. The command output should return the requested project IDs:

PROJECT_ID
cc-project5-123123
cc-internal-111222
cc-web-prod-123456

3. Run projects get-iam-policy command which gets the IAM policy for a project, given a project ID.

gcloud projects get-iam-policy cc-project5-123123 --format=json

4. The command output should return the requested project IAM policy:

{
  "bindings": [
    {
      "members": [
        "user:cloud.realisation@gmail.com"
      ],
      "role": "roles/editor"
    },
    {
      "members": [
        "user:cloud.conformity@gmail.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "serviceAccount:cc-project5-service-account@cc-project5-123123.iam.gserviceaccount.com"
      ],
      "role": "roles/iam.serviceAccountTokenCreator"
    },
    {
      "members": [
        "serviceAccount:cc-project5-service-account@cc-project5-123123.iam.gserviceaccount.com"
      ],
      "role": "roles/iam.serviceAccountUser"
    }
  ],
  "etag": "abcdabcdabcd",
  "version": 1
}

Check the name of each member role (i.e. "role" attribute) returned by the projects get-iam-policy command output. If one or more members have the "role" set to "roles/iam.serviceAccountUser" or "roles/iam.serviceAccountTokenCreator", as shown in the example above, there are IAM members associated with Service Account User and/or Service Account Token Creator roles at the selected GCP project level.

Delete Google Cloud API Keys

Because only a limited number of Google Cloud services allow access using just API keys, without requiring another type of credential, Google recommends using a standard authentication flow instead of API keys for most applications. Deleting GCP API keys should enforce the use of secure authentication methods only and minimize the exposure to attacks.

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list  --format="table(projectId)"

2. The command output should return the requested GCP project IDs:

PROJECT_ID
  cc-project5-112233
  cc-web-prod-111222
  cc-internal-123123

3. Run services api-keys list which lists the API keys of a given project.

gcloud alpha services api-keys list  --project=cc-project5-112233  --format="table(uid)"

4. The command output should return the ID(s) of the active GCP API key(s):

UID:
  abcd1234-abcd-1234-abcd-1234abcd1234
  1234abcd-1234-abcd-1234-abcd1234abcd

If the services api-keys list command output returns one or more API key IDs, as shown in the example above, the selected Google Cloud Platform (GCP) project is using API keys as credentials for authentication.

Delete User-Managed Service Account Keys

Anyone who has access to your user-managed keys will be able to access GCP resources through their associated service accounts. Deleting unwanted user-managed service account keys will significantly reduce the chances that a compromised set of keys can be used without your knowledge to access certain Google Cloud components and resources.

To determine if your GCP service accounts are using user-managed keys, perform the following operations:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list  --format="table(projectId)"

2. The command output should return the requested project identifiers (IDs):

PROJECT_ID
cc-project5-app-123123
cc-web-app-prod-123123
cc-internal-app-123123

3. Run iam service-accounts list command using the ID of the GCP project that you want to examine as identifier parameter and custom query filters to list the email address of each service account available for the selected project:

gcloud iam service-accounts list    --project=cc-project5-app-123123    --format="table(email)"

4. The command output should return the requested email addresses:

EMAIL
cc-dev-service-account@cc-project5-app-123123.iam.gserviceaccount.com
cc-int-service-account@cc-project5-app-123123.iam.gserviceaccount.com

5. Run iam service-accounts keys list command using the email address of the service account that you want to examine as identifier parameter, to list the user-managed keys created for the selected GCP service account:

gcloud iam service-accounts keys list   --iam-account=cc-dev-service-account@cc-project5-app-123123.iam.gserviceaccount.com --managed-by=user

6. The command output should return the requested user-managed keys:

KEY_ID                                CREATED_AT          EXPIRES_AT
abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd   2020-04-07T17:05:05Z   9999-12-31T23:59:59Z
abcd1234abcd1234abcd1234abcd1234abcd1234   2020-04-07T17:08:51Z   9999-12-31T23:59:59Z

If the iam service-accounts keys list command output returns one or more associated keys, as shown in the output example above, the selected Google Cloud Platform service account is using user-managed keys.

Enable Access Approval

Controlling access to your Google Cloud data is crucial when working with business-critical and sensitive data. With Access Approval, you can be certain that your cloud information is accessed by approved Google personnel only. The Access Approval feature ensures that a cryptographically-signed approval is available for Google Cloud support and engineering teams when they need to access your cloud data . By default, Access Approval and its dependency of Access Transparency are not enabled.

To determine if Access Approval is enabled for your Google Cloud account, perform the following operations:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list  --format="table(projectId)"

2. The command output should return the requested GCP project identifiers:

PROJECT_ID
cc-web-project-112233
cc-mobile-project-123123

3. Run access-approval settings get command which get the Access Approval settings associated with a project, a folder, or organization.

gcloud access-approval settings get --project cc-web-project-112233

The command output should return the Access Approval feature status. If the access-approval settings get command output does not return the requested status, Access Approval is not enabled for the selected GCP project.

The principle of separation of duties can be enforced in order to eliminate the need for the IAM user/identity that has all the permissions needed to perform unwanted actions, such as using a cryptographic key to access and decrypt data which the user should not normally have access to.

To determine if there are any IAM users that have KMS-related roles assigned at the same time, perform the following actions:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list  --format="table(projectId)"

2. The command output should return the requested GCP project IDs:

PROJECT_ID
cc-big-data-app-123123
cc-internal-app-112233
cc-frontend-app-123456

3. Run projects get-iam-policy command using the ID of the GCP project that you want to examine as the identifier parameter and custom query filters to describe the Identity and Access Management (IAM) policy created for the selected GCP project, in JSON format:

gcloud projects get-iam-policy cc-big-data-app-123123  --format=json

4. The command output should return the requested IAM policy document:

{
  "bindings": [
    {
      "members": [
        "user:cloud.conformity@gmail.com"
      ],
      "role": "roles/cloudkms.admin"
    },
    {
      "members": [
        "user:cloud.conformity@gmail.com"
      ],
      "role": "roles/cloudkms.cryptoKeyEncrypterDecrypter"
    },
    {
      "members": [
        "user:cloud.realisation@gmail.com"
      ],
      "role": "roles/editor"
    }
  ],
  "etag": "123412341234",
  "version": 1
}

Check the name of each member role (i.e. "role" attribute) returned by the projects get-iam-policy command output. If one or more members are associated with the following set of roles: "roles/cloudkms.admin" role and one of the encrypter/decrypter roles (i.e. "roles/cloudkms.cryptoKeyEncrypterDecrypter", "roles/cloudkms.cryptoKeyEncrypter" or "roles/cloudkms.cryptoKeyDecrypter"), as shown in the output example above, there are users/identities that have both the KMS administrator and KMS encrypter/decrypter roles assigned at the same, therefore the principle of separation of duties was not enforced while assigning KMS-related roles to IAM users.

Minimize the Use of Primitive Roles

For production and security-critical cloud environments, limit the use of primitive roles such as "Owner", "Editor", and "Viewer" for Cloud IAM members. Instead, grant predefined roles to these IAM members to allow the least-permissive access required to perform their tasks.

To determine if there are any IAM identities that make use of Cloud IAM primitive roles, perform the following operations:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list    --format="table(projectId)"

2. The command output should return the requested project identifiers (IDs):

PROJECT_ID
cc-prod-app-123123
cc-project5-123456

3. Run projects get-iam-policy command using the ID of the Google Cloud project that you want to examine as identifier parameter and custom query filters to describe the Identity and Access Management (IAM) policy available for the selected project, in JSON format:

gcloud projects get-iam-policy cc-prod-app-123123   --format=json

4. The command output should return the requested IAM policy (JSON format):

{
  "bindings": [
    {
      "members": [
        "user:admin@cloudconformity.com"
      ],
      "role": "roles/editor"
    },
    {
      "members": [
        "user:admin@cloudrealisation.com"
      ],
      "role": "roles/viewer"
    },
    {
      "members": [
        "user:admin@cloudrealisation.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "serviceAccount:123456789012-compute@developer.gserviceaccount.com"
      ],
      "role": "roles/cloudkms.cryptoKeyEncrypterDecrypter"
    }
  ],
  "etag": "abcdabcdabcd",
  "version": 1
}

Check the name of each associated role (i.e. "role" property value) returned by the projects get-iam-policy command output. If one or more IAM members have the "role" property set to "roles/owner", "roles/editor" or "roles/viewer", as shown in the output example above, there are Google Cloud identities that make use of Cloud IAM primitive roles, available within the selected project.

Restrict Administrator Access for Service Accounts

When your Google Cloud Platform (GCP) service accounts have administrator privileges (i.e. are using Owner and Editor roles, as well as roles containing *Admin or *admin in their names), these service accounts can access, create, and manage VM instances and other resources. To adhere to the principle of least privilege, give your GCP service accounts the minimal set of actions required to perform successfully their tasks and remove any administrator-based roles that allows them overly permissive access.

To determine if your GCP user-managed service accounts have administrator privileges, perform the following actions:

1. Run projects list command with custom query filters to list the ID of each project available in your Google Cloud account:

gcloud projects list    --format="table(projectId)"

2. The command output should return the requested project IDs:

PROJECT_ID
cc-internal-app-123123
cc-web-app-prod-123123
cc-project5-app-123123

3. Run projects get-iam-policy command using the ID of the GCP project that you want to examine as identifier parameter and custom query filters to describe the Access Management (IAM) policy created for the selected GCP project, in JSON format:

gcloud projects get-iam-policy cc-internal-app-123123   --format=json

4. The command output should return the requested IAM policy:

{
  "bindings": [
    {
      "members": [
        "serviceAccount:cc-app-dev-account@cc-internal-app-123123.iam.gserviceaccount.com"
      ],
      "role": "roles/appengine.codeViewer"
    },
    {
      "members": [
        "serviceAccount:cc-app-dev-account@cc-internal-app-123123.iam.gserviceaccount.com"
      ],
      "role": "roles/editor"
    },
    {
      "members": [
        "user:cloud.conformity@gmail.com",
        "user:cloud.realisation@gmail.com"
      ],
      "role": "roles/owner"
    }
  ],
  "etag": "abcdabcdabcd",
  "version": 1
}

The IAM policy returned by the projects get-iam-policy command output should contain the member accounts available for the selected GCP project. Choose the user-managed service account that you want to examine. A user-managed service account has the following format: \@\.iam.gserviceaccount.com (e.g. cc-app-dev-account@cc-internal-app-123123.iam.gserviceaccount.com). Once the service account is selected, check the associated role(s) available as value for the "role" property (highlighted). If the account has one or more roles containing *Admin or *admin, as well as the role matching Editor (i.e. "roles/editor") or role matching Owner (i.e. "roles/owner"), the selected GCP user-managed service account has administrator privileges.