Review and apply role recommendations for Cloud Storage buckets

This page explains how to view, understand, and apply Cloud Storage role recommendations for Cloud Storage buckets. Role recommendations help you enforce the principle of least privilege by ensuring that principals have only the permissions that they actually need.

Before you begin

Required IAM roles

This section describes the IAM roles and permissions that you need in order to work with bucket-level role recommendations.

View recommendations

To get the permissions that you need to view bucket-level role recommendations, ask your administrator to grant you the following IAM roles on the project:

  • Role Viewer (roles/iam.roleViewer)
  • IAM Recommender Viewer (roles/recommender.iamViewer)
  • Storage Admin (roles/storage.admin)

For more information about granting roles, see Manage access.

These predefined roles contain the permissions required to view bucket-level role recommendations. To see the exact permissions that are required, expand the Required permissions section:

Required permissions

  • iam.roles.get
  • iam.roles.list
  • recommender.iamPolicyRecommendations.get
  • recommender.iamPolicyRecommendations.list
  • recommender.iamPolicyInsights.get
  • recommender.iamPolicyInsights.list
  • storage.buckets.getIamPolicy

You might also be able to get these permissions with custom roles or other predefined roles.

Apply and dismiss recommendations

To get the permissions that you need to view, apply, and dismiss bucket-level role recommendations, ask your administrator to grant you the following IAM roles on the project:

  • Role Viewer (roles/iam.roleViewer)
  • IAM Recommender Admin (roles/recommender.iamAdmin)
  • Storage Admin (roles/storage.admin)

For more information about granting roles, see Manage access.

These predefined roles contain the permissions required to view, apply, and dismiss bucket-level role recommendations. To see the exact permissions that are required, expand the Required permissions section:

Required permissions

  • iam.roles.get
  • iam.roles.list
  • recommender.iamPolicyRecommendations.get
  • recommender.iamPolicyRecommendations.list
  • recommender.iamPolicyInsights.get
  • recommender.iamPolicyInsights.list
  • recommender.iamPolicyLateralMovementInsights.get
  • recommender.iamPolicyLateralMovementInsights.list
  • recommender.iamPolicyRecommendations.update
  • storage.buckets.getIamPolicy
  • storage.buckets.setIamPolicy

You might also be able to get these permissions with custom roles or other predefined roles.

Review and apply recommendations

You can review and apply bucket-level role recommendations with the Google Cloud CLI and the Recommender API.

gcloud

Review your recommendations:

To list your bucket-level recommendations, run the gcloud recommender recommendations list command, filtering for only Cloud Storage bucket recommendations:

gcloud recommender recommendations list \
    --location=LOCATION \
    --recommender=google.iam.policy.Recommender \
    --project=PROJECT_ID \
    --format=FORMAT \
    --filter="recommenderSubtype:REMOVE_ROLE_STORAGE_BUCKET OR recommenderSubtype:REPLACE_ROLE_STORAGE_BUCKET"

Replace the following values:

  • LOCATION: The region where your Cloud Storage buckets are located—for example, us or us-central1.
  • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
  • FORMAT: The format of the response. Use json or yaml.

The response is similar to the following example. In this example, all authenticated users (allAuthenticatedUsers) have the Storage Legacy Object Reader role (roles/storage.legacyObjectReader) on the bucket mybucket. However, this role hasn't been used in the past 90 days. As a result, the role recommendation suggests that you revoke the role:

[
  {
    "associatedInsights": [
      {
        "insight": "projects/123456789012/locations/us/insightTypes/google.iam.policy.Insight/insights/7849add9-73c0-419e-b169-42b3671173fb"
      }
    ],
    "associatedResourceNames": [
      "//storage.googleapis.com/my-bucket"
    ],
    "content": {
      "operationGroups": [
        {
          "operations": [
            {
              "action": "remove",
              "path": "/iamPolicy/bindings/*/members/*",
              "pathFilters": {
                "/iamPolicy/bindings/*/condition/expression": "",
                "/iamPolicy/bindings/*/members/*": "allAuthenticatedUsers",
                "/iamPolicy/bindings/*/role": "roles/storage.legacyObjectReader"
              },
              "resource": "//storage.googleapis.com/my-bucket",
              "resourceType": "storage.googleapis.com/Bucket"
            }
          ]
        }
      ]
    },
    "description": "This role has not been used during the observation window.",
    "etag": "\"7caf4103d7669e12\"",
    "lastRefreshTime": "2022-05-24T07:00:00Z",
    "name": "projects/123456789012/locations/us/recommenders/google.iam.policy.Recommender/recommendations/fbc885b7-f0a8-47e6-90fe-6141aa2c4257",
    "primaryImpact": {
      "category": "SECURITY",
      "securityProjection": {
        "details": {
          "revokedIamPermissionsCount": 1
        }
      }
    },
    "priority": "P1",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    "stateInfo": {
      "state": "ACTIVE"
    }
  }
]

Review each recommendation carefully, and consider how it will change the principal's access to Google Cloud resources. To learn how to review recommendations from the gcloud CLI, see Review recommendations on this page.

To apply a recommendation:

  1. Use the gcloud recommender recommendations mark-claimed command to change the recommendation's state to CLAIMED, which prevents the recommendation from changing while you apply it:

    gcloud recommender recommendations mark-claimed \
        RECOMMENDATION_ID \
        --location=LOCATION \
        --recommender=google.iam.policy.Recommender \
        --project=PROJECT_ID \
        --format=FORMAT \
        --etag=ETAG \
        --state-metadata=STATE_METADATA
    

    Replace the following values:

    • RECOMMENDATION_ID: The unique identifier for the recommendation. This value appears at the end of the name field in the recommendation. For example, if the name field is projects/example-project/locations/global/recommenders/google.iam.policy.Recommender/recommendations/fb927dc1-9695-4436-0000-f0f285007c0f, the recommendation ID is fb927dc1-9695-4436-0000-f0f285007c0f.
    • LOCATION: The region where your Cloud Storage bucket is located—for example, us or us-central1.
    • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
    • FORMAT: The format of the response. Use json or yaml.
    • ETAG: The value of the etag field in the recommendation, such as "dd0686e7136a4cbb". Note that this value can include quotes.
    • STATE_METADATA: Optional. Comma-separated key-value pairs that contain your choice of metadata about the recommendation. For example, --state-metadata=reviewedBy=alice,priority=high. The metadata replaces the stateInfo.stateMetadata field in the recommendation.

    If the command succeeds, the response shows the recommendation in a CLAIMED state, as shown in the following example. For clarity, the example omits most fields:

    ...
    "priority": "P1",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    "stateInfo": {
      "state": "CLAIMED"
    }
    ...
    
  2. Get the allow policy for the bucket, then modify and set the allow policy so that it reflects the recommendation.

  3. Update the recommendation's state to SUCCEEDED, if you were able to apply the recommendation, or FAILED, if you could not apply the recommendation:

    gcloud recommender recommendations COMMAND \
        RECOMMENDATION_ID \
        --location=LOCATION \
        --recommender=google.iam.policy.Recommender \
        --project=PROJECT_ID \
        --format=FORMAT \
        --etag=ETAG \
        --state-metadata=STATE_METADATA
    

    Replace the following values:

    • COMMAND: Use mark-succeeded, if you were able to apply the recommendation, or mark-failed, if you could not apply the recommendation.
    • RECOMMENDATION_ID: The unique identifier for the recommendation. This value appears at the end of the name field in the recommendation. For example, if the name field is projects/example-project/locations/global/recommenders/google.iam.policy.Recommender/recommendations/fb927dc1-9695-4436-0000-f0f285007c0f, the recommendation ID is fb927dc1-9695-4436-0000-f0f285007c0f.
    • LOCATION: The region where your Cloud Storage bucket is located—for example, us or us-central1.
    • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
    • FORMAT: The format of the response. Use json or yaml.
    • ETAG: The value of the etag field in the recommendation, such as "dd0686e7136a4cbb". Note that this value can include quotes.
    • STATE_METADATA: Optional. Comma-separated key-value pairs that contain your choice of metadata about the recommendation. For example, --state-metadata=reviewedBy=alice,priority=high. The metadata replaces the stateInfo.stateMetadata field in the recommendation.

    For example, if you marked the recommendation as having succeeded, the response shows the recommendation in a SUCCEEDED state. For clarity, this example omits most fields:

    ...
    "priority": "P1",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    "stateInfo": {
      "state": "SUCCEEDED"
    }
    ...
    

REST

These instructions assume that you have authenticated and set the GOOGLE_APPLICATION_CREDENTIALS environment variable.

Review your recommendations:

To list all available recommendations for your Cloud Storage buckets, use the Recommender API's recommendations.list method.

Before using any of the request data, make the following replacements:

  • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
  • LOCATION: The region where your Cloud Storage buckets are located—for example, us or us-central1.
  • PAGE_SIZE: Optional. The maximum number of results to return from this request. If not specified, the server will determine the number of results to return. If the number of recommendations is greater than the page size, the response contains a pagination token that you can use to retrieve the next page of results.
  • PAGE_TOKEN: Optional. The pagination token returned in an earlier response from this method. If specified, the list of recommendations will start where the previous request ended.

HTTP method and URL:

GET https://recommender.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/recommenders/google.iam.policy.Recommender/recommendations?filter=recommenderSubtype%20%3D%20REMOVE_ROLE_STORAGE_BUCKET%20OR%20recommenderSubtype%20%3D%20REPLACE_ROLE_STORAGE_BUCKET&pageSize=PAGE_SIZE&pageToken=PAGE_TOKEN

To send your request, expand one of these options:

The response is similar to the following example. In this example, all authenticated users (allAuthenticatedUsers) have the Storage Legacy Object Reader role (roles/storage.legacyObjectReader) on the bucket mybucket. However, this role hasn't been used in the past 90 days. As a result, the role recommendation suggests that you revoke the role:

{
  "recommendations": [
    "name": "projects/123456789012/locations/us/recommenders/google.iam.policy.Recommender/recommendations/fbc885b7-f0a8-47e6-90fe-6141aa2c4257",
    "description": "This role has not been used during the observation window.",
    "lastRefreshTime": "2022-05-24T07:00:00Z",
    "primaryImpact": {
      "category": "SECURITY",
      "securityProjection": {
        "details": {
          "revokedIamPermissionsCount": 1
        }
      }
    },
    "content": {
      "operationGroups": [
        {
          "operations": [
            {
              "action": "remove",
              "resourceType": "storage.googleapis.com/Bucket",
              "resource": "//storage.googleapis.com/my-bucket",
              "path": "/iamPolicy/bindings/*/members/*",
              "pathFilters": {
                "/iamPolicy/bindings/*/condition/expression": "",
                "/iamPolicy/bindings/*/members/*": "allAuthenticatedUsers",
                "/iamPolicy/bindings/*/role": "roles/storage.legacyObjectReader"
              }
            }
          ]
        }
      ]
    },
    "stateInfo": {
      "state": "ACTIVE"
    },
    "etag": "\"7caf4103d7669e12\"",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    "associatedInsights": [
      {
        "insight": "projects/123456789012/locations/us/insightTypes/google.iam.policy.Insight/insights/7849add9-73c0-419e-b169-42b3671173fb"
      }
    ],
    "priority": "P1"
  ]
}

Review each recommendation carefully, and consider how it will change the principal's access to Google Cloud resources. To learn how to review recommendations from the REST API, see Review recommendations on this page.

To apply a recommendation:

  1. Mark the recommendation as CLAIMED:

    To mark a recommendation as CLAIMED, which prevents the recommendation from changing while you apply it, use the Recommender API's recommendations.markClaimed method.

    Before using any of the request data, make the following replacements:

    • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
    • LOCATION: The region where your Cloud Storage bucket is located—for example, us or us-central1.
    • RECOMMENDATION_ID: The unique identifier for the recommendation. This value appears at the end of the name field in the recommendation. For example, if the name field is projects/example-project/locations/global/recommenders/google.iam.policy.Recommender/recommendations/fb927dc1-9695-4436-0000-f0f285007c0f, the recommendation ID is fb927dc1-9695-4436-0000-f0f285007c0f.
    • ETAG: The value of the etag field in the recommendation, such as "dd0686e7136a4cbb". Use backslashes to escape quotes, for example, "\"df7308cca9719dcc\"".
    • STATE_METADATA: Optional. An object that contains key-value pairs with your choice of metadata about the recommendation. For example, {"reviewedBy": "alice", "priority": "high"}. The metadata replaces the stateInfo.stateMetadata field in the recommendation.

    HTTP method and URL:

    POST https://recommender.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/recommenders/google.iam.policy.Recommender/recommendations/RECOMMENDATION_ID:markClaimed

    Request JSON body:

    {
      "etag": "ETAG",
      "stateMetadata": {
        "STATE_METADATA"
      }
    }
    

    To send your request, expand one of these options:

    The response shows the recommendation in a CLAIMED state, as shown in the following example. For clarity, this example omits most fields:

    ...
    "stateInfo": {
      "state": "CLAIMED"
    },
    "etag": "\"7caf4103d7669e12\"",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    ...
    

  2. Get the allow policy for the project, then modify the allow policy so that it reflects the recommendation.

  3. Update the recommendation's state to SUCCEEDED, if you were able to apply the recommendation, or FAILED, if you could not apply the recommendation:

    SUCCEEDED

    To mark a recommendation as SUCCEEDED, indicating that you were able to apply it, use the Recommender API's recommendations.markSucceeded method.

    Before using any of the request data, make the following replacements:

    • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
    • LOCATION: The region where your Cloud Storage bucket is located—for example, us or us-central1.
    • RECOMMENDATION_ID: The unique identifier for the recommendation. This value appears at the end of the name field in the recommendation. For example, if the name field is projects/example-project/locations/global/recommenders/google.iam.policy.Recommender/recommendations/fb927dc1-9695-4436-0000-f0f285007c0f, the recommendation ID is fb927dc1-9695-4436-0000-f0f285007c0f.
    • ETAG: The value of the etag field in the recommendation, such as "dd0686e7136a4cbb". Use backslashes to escape quotes, for example, "\"df7308cca9719dcc\"".
    • STATE_METADATA: Optional. An object that contains key-value pairs with your choice of metadata about the recommendation. For example, {"reviewedBy": "alice", "priority": "high"}. The metadata replaces the stateInfo.stateMetadata field in the recommendation.

    HTTP method and URL:

    POST https://recommender.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/recommenders/google.iam.policy.Recommender/recommendations/RECOMMENDATION_ID:markSucceeded

    Request JSON body:

    {
      "etag": "ETAG",
      "stateMetadata": {
        "STATE_METADATA"
      }
    }
    

    To send your request, expand one of these options:

    The response shows the recommendation in a SUCCEEDED state, as shown in the following example. For clarity, this example omits most fields:

    ...
    "stateInfo": {
      "state": "SUCCEEDED"
    },
    "etag": "\"7caf4103d7669e12\"",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    ...
    

    FAILED

    To mark a recommendation as FAILED, indicating that you were not able to apply it, use the Recommender API's recommendations.markFailed method.

    Before using any of the request data, make the following replacements:

    • PROJECT_ID: The ID of the Google Cloud project that contains your Cloud Storage buckets. Project IDs are alphanumeric strings, like my-project.
    • LOCATION: The region where your Cloud Storage bucket is located—for example, us or us-central1.
    • RECOMMENDATION_ID: The unique identifier for the recommendation. This value appears at the end of the name field in the recommendation. For example, if the name field is projects/example-project/locations/global/recommenders/google.iam.policy.Recommender/recommendations/fb927dc1-9695-4436-0000-f0f285007c0f, the recommendation ID is fb927dc1-9695-4436-0000-f0f285007c0f.
    • ETAG: The value of the etag field in the recommendation, such as "dd0686e7136a4cbb". Use backslashes to escape quotes, for example, "\"df7308cca9719dcc\"".
    • STATE_METADATA: Optional. An object that contains key-value pairs with your choice of metadata about the recommendation. For example, {"reviewedBy": "alice", "priority": "high"}. The metadata replaces the stateInfo.stateMetadata field in the recommendation.

    HTTP method and URL:

    POST https://recommender.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/recommenders/google.iam.policy.Recommender/recommendations/RECOMMENDATION_ID:markFailed

    Request JSON body:

    {
      "etag": "ETAG",
      "stateMetadata": {
        "STATE_METADATA"
      }
    }
    

    To send your request, expand one of these options:

    The response shows the recommendation in a FAILED state, as shown in the following example. For clarity, this example omits most fields:

    ...
    "stateInfo": {
      "state": "FAILED"
    },
    "etag": "\"7caf4103d7669e12\"",
    "recommenderSubtype": "REMOVE_ROLE_STORAGE_BUCKET",
    ...
    

Understand recommendations

Each recommendation includes information to help you understand why the recommendation was made.

For details on the fields of a recommendation, see the Recommendation reference.

To see the permission usage that this recommendation is based on, view the policy insights that are associated with the recommendation. These insights are listed in the associatedInsights field. To view a policy insight that is associated with the recommendation, do the following:

  1. Copy the associated insight's ID. The ID is everything after insights/ in the insight field. For example, if the insight field reads projects/123456789012/locations/us/insightTypes/google.iam.policy.Insight/insights/7849add9-73c0-419e-b169-42b3671173fb, the insight ID is 7849add9-73c0-419e-b169-42b3671173fb.
  2. Follow the instructions to get a policy insight, using the insight ID you copied.

What's next