Managing access to custom images

To let users create, delete, use, or share your custom images, you must grant them the appropriate Identity and Access Management (IAM) roles. Use IAM to:

For general information about granting access to Compute Engine resources, see Managing access to Compute Engine resources. For information about IAM, read the IAM documentation.

Before you begin

Limitations

You can't grant a user the role of allUsers on images.

Granting permission to create custom images

You can grant users the ability to create custom images in your organization or project.

Compute Engine offers the predefined Storage Admin role that you can assign to users so they can create, delete, and manage storage related resources, including images, disks, and snapshots. If you need a role that only allows image creation, you must create a custom role. In your custom role, include the following permissions as necessary:

  • compute.images.create to create new images
  • compute.images.list to list images in the project
  • compute.disks.use if the image will be created from a disk
  • compute.disks.list if you want to grant users the ability to see a list of disks in the project

If you grant a user the ability to create custom images on the organization, the user can create custom images for any project within the organization.

Console

  1. In the Google Cloud Console, go to the IAM & admin page for the project or organization.

    Go to the IAM & Admin page

  2. Click the Add button to add a new member.

  3. In the New members field, enter the email address of the identity you want to grant access to.

  4. In the Select a role list, select Compute Engine> Compute Storage Admin, or select a custom role if you created one.

  5. Save your changes.

gcloud

To grant the roles/compute.storageAdmin role on an organization level:

gcloud organizations add-iam-policy-binding organization-id \
    --member='member' \
    --role='roles/compute.storageAdmin'

To grant the roles/compute.storageAdmin role on a project level:

gcloud projects add-iam-policy-binding project-id \
    --member='member' \
    --role='roles/compute.storageAdmin'

Replace the following:

  • organization-id or project-id: The organization ID or the project ID, for example, my-organization-1 or my-project-1.
  • member: A valid identity to which you want to grant the role. Must be of the form user|group|serviceAccount:email or domain:domain. For example:
    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com

API

To modify an IAM policy directly through the API, do the following:

  1. Read the existing policy with the getIamPolicy method. For projects, use the following URL, replacing project-id with the project ID. For example, my-project-1.

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

    For organizations, use the following URL, replacing organization-id with the 12-digit numeric organization ID. For example, 123456578920.

    POST https://cloudresourcemanager.googleapis.com/v1/organizations/organization-id:getIamPolicy

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to add or remove members and their associated roles. For example, to grant the roles/compute.storageAdmin role to 1email@example.com`, add the following new binding to the policy:

    {
      "members": [
        "group:admins@example.com"
      ],
      "role":"roles/compute.storageAdmin"
    }
    
  3. Write the updated policy with setIamPolicy():

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

    Replace the project-id with the project ID. In the body of the request, provide the updated IAM policy from the previous step.

Granting permissions to delete custom images

Depending on your needs, you can grant users permission to:

  • Delete a specific image
  • Delete images owned by a specific project
  • Delete images for any project within an organization

Granting permission on the project level lets users delete all images owned by that project. Granting permission on the organization level lets the user delete any images owned by that organization, regardless of the project.

Compute Engine offers the predefined Storage Admin role that you can assign to users so that they can create, delete, and manage storage related resources, including images, disks, and snapshots. If you need a role that only allows image deletion, you must create a custom role. In your custom role, include the following permissions as necessary:

  • compute.images.delete to delete images
  • compute.images.list to list images in the project or organization, if necessary
  • compute.images.get to get the images

Console

To grant permission to delete specific images:

  1. In the Google Cloud Console, go to the Images page.

    Go to the Images page

  2. Select the images that you want to grant permissions to.

  3. On the right, in the Permissions panel, click Add members.

  4. Enter the email address of the identity you want to share the image with. Must be of the form user|group|serviceAccount:email or domain:domain. For example:

    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  5. In the Role list, point to Compute Engine and select Storage Admin, or select a custom role from the Custom list.

  6. Save your changes.

To grant permission to delete images for a project or organization:

  1. Go to the IAM & admin page for the project or organization.

    Go to the IAM & Admin page

  2. At the top of the page, click the Add button.

  3. In the New members field, enter the email address of the identity you want to grant access to. Must be of the form user|group|serviceAccount:email or domain:domain. For example:

    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  4. In the Role list, point to Compute Engine and select Storage Admin, or select a custom role from the Custom list.

  5. Save your changes.

gcloud

To grant users permissions to delete images at the organization level:

gcloud organizations add-iam-policy-binding organization-id \
    --member='member' \
    --role='role'

To grant permissions to delete images on a project level:

gcloud projects add-iam-policy-binding project-id \
    --member='member' \
    --role='role'

To grant permissions to delete a specific image:

gcloud images add-iam-policy-binding image-name \
    --member='member' \
    --role='role'

Replace the following:

  • organization-id or project-id or image-name: The 12-digit numeric organization ID, the project ID, or the image name, for example, 123456578920 or my-project-1 or my-custom-image.
  • member: A valid identity for which you want to grant the role. Must be of the form user|group|serviceAccount:email or domain:domain. For example:
    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  • role: The role to assign to this identity, for example roles/compute.storageAdmin or a custom role, such as roles/customImageDeletionRole.

API

To grant permissions to delete images through the API:

  1. Read the existing policy with the resource's respective getIamPolicy method. For projects, use the following URL:

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

    Replace project-id with the project ID.

    For organizations, use:

    POST https://cloudresourcemanager.googleapis.com/v1/organizations/organization-id:getIamPolicy

    Replace organization-id with the 12-digit numeric organization ID.

    For a specific image, use:

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace project-id with the project ID and image-name with the name of the image.

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to add or remove members and their associated roles. For example, to grant the roles/compute.storageAdmin role to email@example.com, add the following new binding to the policy:

    {
      "members": [
        "user:email@example.com"
      ],
      "role":"roles/compute.storageAdmin"
    }
    
  3. Write the updated policy with setIamPolicy(). For example:

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

    Replace project-id with the project ID. In the body of the request, provide the updated IAM policy from the previous step.

Sharing custom images within an organization

If your project belongs to an organization, the organization can have several other projects with varying levels of access to other projects. When you create custom images, you can share these images with other users from other projects within the organization.

Compute Engine predefines the following curated IAM roles that you can use for image management:

  • roles/compute.imageUser: Permission to list, read, and use images in your requests, without having other permissions on the image.
  • roles/compute.storageAdmin: Permissions to create, modify, and delete disks, images, and snapshots.

Alternatively, you can also create your own custom IAM role.

As a best practice, Google recommends keeping all your custom images in a single project dedicated to hosting these images and nothing else. This improves the management of those images, and lets you grant specific teams access to only the images that they need. You can also grant teams access to the entire image project, but because team access to the entire image project violates the principle of least privilege, we do not recommend it.

The example below shows how to add a group so that users of that group have access to the image.

Console

  1. In the Google Cloud Console, go to the Images page.

    Go to the Images page

  2. Select the image that you want to share with other users.

  3. On the right, in the Permissions panel, click Add members.

  4. Enter the email address of the identity you want to share the image with. Must be of the form user|group|serviceAccount:email or domain:domain. For example:

    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  5. In the Role list, point to Compute Engine and select Image User or Storage Admin, or select a custom role.

  6. Save your changes.

To let users launch shared custom images from the Cloud Console, you must also add users as a project viewer to the image project. This ensures that these shared images appear in the image selection list.

  1. In the Google Cloud Console, go to the IAM & admin page.

    Go to the IAM & Admin page

  2. At the top of the page, click the ADD button.

  3. In the New members field, enter the email address of the identity you want to share the image with.

  4. In the Role list, point to Project and select Viewer.

  5. Save your changes.

gcloud

Using the gcloud command-line tool, update the IAM policy for a specific image.

gcloud compute images add-iam-policy-binding image-name \
    --member='member' \
    --role='role'

Replace the following:

  • image-name: The name of the image. For example, custom-centos-8.
  • member: A valid identity for which you want to grant the role. Must be of the form user|group|serviceAccount:email or domain:domain. For example:
    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  • role is the role to assign this identity, such as roles/compute.imageUser, roles/compute.storageAdmin, or a custom role.

Optionally, to let users see these shared images in their images.list requests, add users as project viewers to the image project. If you don't need your users to be able to view the list of shared images, you can skip this step.

gcloud compute projects add-iam-policy-binding project-id \
    --member='member' \
    --role='roles/viewer'

API

To modify an IAM policy directly through the API, do the following:

  1. Read the existing policy with the resource's respective getIamPolicy method.

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to add or remove users and their associated roles. Add users using the form user|group|serviceAccount:email or domain:domain. For example, user:test-user@gmail.com, group:admins@example.com, serviceAccount:test123@example.domain.com, or domain:example.domain.com. For example, to grant the roles/compute.imageUser role to email@example.com, add the following:

    {
      "members": [
        "user:email@example.com"
      ],
      "role":"roles/compute.imageUser"
    }
    
  3. Write the updated policy with setIamPolicy():

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:setIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    In the body of the request, provide the updated IAM policy from the previous step.

Optionally, to let users see these shared images in their images.list requests, add users as project viewers to the image project. If you don't need your users to be able to view the list of shared images, you can skip this step.

POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

Sharing custom images between organizations

Creating a catalog of custom images can be useful for sharing images with partners, users, or contractors that are outside of your organization. Follow these instructions to share your images with users outside of the organization by adding them as Image Users to your project.

Console

  1. In the Google Cloud Console, go to the Images page.

    Go to the Images page

  2. Select the image that you want to share with other users.

  3. On the right, in the Permissions panel, click Add members.

  4. Enter the email address of the group you want to share the image with. For example, group:admins@example.com.

  5. In the Role list, point to Compute Engine and select Image User.

  6. Save your changes.

To let users launch shared custom images from the Cloud Console, you must also add them as a project viewer to the image project. This ensures that these shared images appear in the image selection list.

  1. In the Google Cloud Console, go to the IAM & admin page.

    Go to the IAM & Admin page

  2. At the top of the page, click the Add button.

  3. In the New members field, enter the email address of the identity you want to share the image with.

  4. In the Role list, point to Project and select Viewer.

  5. Save your changes.

gcloud

Using the gcloud command-line tool:

gcloud compute images add-iam-policy-binding image-name \
    --member='member' \
    --role='roles/compute.imageUser'

Replace the following:

  • image-name: The name of the image. For example, custom-centos-8.
  • member: A valid identity for which you want to grant the role. For example, group:admins@example.com.

Optionally, to let users see these shared images in their images.list requests, add users as project viewers to the image project. If you don't need your users to be able to view the list of shared images, you can skip this step.

gcloud compute projects add-iam-policy-binding project-id \
    --member='member' \
    --role='roles/viewer'

API

To modify an image's IAM policy directly through the API:

  1. Read the existing policy with the resource's respective getIamPolicy method.

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to add or remove users and their associated roles. Add users using the form user|group|serviceAccount:email or domain:domain. For example, user:test-user@gmail.com, group:admins@example.com, serviceAccount:test123@example.domain.com, or domain:example.domain.com. For example, to grant the roles/compute.imageUser role to email@example.com, add the following:

    {
      "members": [
        "user:email@example.com"
      ],
      "role":"roles/compute.imageUser"
    }
    
  3. Write the updated policy with setIamPolicy():

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:setIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    In the body of the request, provide the updated IAM policy from the previous step.

    Optionally, to let users see these shared images in their images.list requests, add users as project viewers to the image project. If you don't need your users to be able to view the list of shared images, you can skip this step.

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

Sharing custom images publicly

You can share your custom images with all authenticated Compute Engine users, regardless of whether they are part of your organization or project.

You can only share resources, such as images, with all authenticated users; you cannot share projects or organizations with all authenticated users. This restriction, and the resource hierarchy, helps prevent an organization from inadvertently sharing their entire project with all authenticated Compute Engine users.

The following example shows how to grant all authenticated Compute Engine users the role of roles/compute.imageUser to a custom image.

gcloud

Replace image-name in the following command with the name of the resource, for example, my_image:

gcloud compute images add-iam-policy-binding image-name \
    --member='allAuthenticatedUsers' \
    --role='roles/compute.imageUser'

API

To modify an IAM policy directly through the API, do the following:

  1. Read the existing policy with the getIamPolicy method. For example:

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to add or remove members and their associated roles.

    {
      "members": [
        "allAuthenticatedUsers"
      ],
      "role":"roles/compute.imageUser"
    }
    
  3. Write the updated policy with setIamPolicy():

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:setIamPolicy

    Replace the following:

    • project-id: Project ID of the project this image belongs to.
    • image-name: The name of the image.

    In the body of the request, provide the updated IAM policy from the previous step.

Granting a managed instance group access to images

Compute Engine lets you create groups of instances, either as managed or unmanaged instance groups. If you create a managed instance group, Compute Engine uses the Google APIs service account to call the Compute Engine API and perform actions related to the group, such as recreating unhealthy instances and updating instances.

If you want to create a managed instance group using an image from another project, grant the roles/compute.imageUser role to the APIs service account belonging to the project that will be creating the managed instance group. For example:

  1. Project A wants to create a managed instance group using images owned by Project B.
  2. Project B grants Project A's service account the role of roles/compute.imageUser.
  3. Project A can now use images from Project B to create managed instance groups.

After granting the roles/compute.imageUser role, you can access the image from the other projects by using the console or the image's URL when you create the instance template for the managed group.

Getting the email address of the service account

Take the following steps to get the email address of a service account:

  1. In the Cloud Console, go to the IAM page of the project whose service account you want to grant access to.

    Go to the IAM page

  2. If prompted, select your project from the list.
  3. Look for the Google APIs service account, which has the email address in the following format:

    project-number@cloudservices.gserviceaccount.com
    
  4. Make note of the email address above.

After retrieving the email address of the service account, follow one of the links:

Granting a managed instance group access to all images in a project

Now that you have the email address of a service account, you can add the address to another project and grant it the role of roles/compute.imageUser.

Console

  1. In the Google Cloud Console, go to the IAM & Admin page of the image project.

    Go to the IAM & Admin page

  2. To add a new member, click Add.

  3. In the New members field, add the service account email address.

  4. In the Role list, point to Compute and select Compute Image User.

  5. Click Save.

  6. Switch back to the service account's project.

You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

gcloud

Add a service account from image project:

gcloud projects add-iam-policy-binding project-id \
  --member 'serviceAccount:service-account-email' --role 'roles/compute.imageUser'

Replace the following:

  • project-id: The ID of the project containing images you want to share.
  • service-account-email: The email of the service account.

You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

API

  1. Get the IAM policy of the image project, replacing project-id with the project ID of the image project.

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

  2. Edit the policy with a text editor to grant the role of roles/compute.imageUser to the service account. For example:

    {
      "bindings": [
         {
          "role": "roles/compute.imageUser",
          "members": [
            "serviceAccount:service-account-email"
          ]
        }
      ]
    }
    

    Replace the service-account-email with the service account email.

  3. Write the updated policy:

    POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

    Replace project-id with the product ID of the image project. In the body of the request, provide the updated IAM policy from the previous step.

    You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

Granting a managed instance group access to specific images in a project

Now that you have the email address of a service account, you can add the address to another project and grant it the role of roles/compute.imageUser for certain images.

Console

  1. In the Google Cloud Console, go to the Images page of the image project.

    Go to the Images page

  2. Select the image that you want to share.

  3. In the Permissions panel, click Add members.

  4. Enter the service account email.

  5. In the Role list, choose Compute and select Compute Image User.

  6. Click Save.

  7. Switch back to the service account's project.

You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

gcloud

To grant a service account access to a specific image:

gcloud images add-iam-policy-binding image-name \
  --member 'serviceAccount:service-account-email' \
  --role 'roles/compute.imageUser'

Replace the following:

  • image-name: The image name you want to share.
  • service-account-email: The email of the service account.

You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

API

  1. Get the IAM policy of an image.

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace the following:

    • project-id: The project ID of the image project.
    • image-name: The name of the image you want to share.
  2. Edit the policy with a text editor to grant the role of roles/compute.imageUser to the service account. For example:

    {
      "bindings": [
         {
          "role": "roles/compute.imageUser",
          "members": [
            "serviceAccount:service-account-email"
          ]
        }
      ]
    }
    

    Replace the service-account-email with the service account email.

  3. Write the updated policy:

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:setIamPolicy

    Replace the following:

    • project-id: The project ID of the image project.
    • image-name: The name of the image you want to share.

    In the body of the request, provide the updated IAM policy from the previous step.

    You can now create an instance template based on an image from the image project and create a managed instance group based on the instance template.

Restricting use of your shared images and snapshots

After sharing your images with other users, you can control where those users employ those resources within your organization. Set the constraints/compute.storageResourceUseRestrictions constraint to define the projects where users are permitted to use your storage resources.

You must have permission to modify your organization's policies to set these constraints. For example, the resourcemanager.organizationAdmin role has permission to set these constraints.

  1. Find the organization ID for your organization.

    gcloud organizations list
    
  2. Get the existing policy settings for your organization. Replace organization-id with your 12-digit numeric organization ID.

    gcloud beta resource-manager org-policies describe \
        compute.storageResourceUseRestrictions \
        --organization organization-id > org-policy.yaml
    
  3. Open the org-policy.yaml file in a text editor and modify the compute.storageResourceUseRestrictions constraint. Add the restrictions that you need, or remove the restrictions that you no longer require. When you have finished editing the file, save your changes. For example, you might set the following constraint entry in your policy file:

    constraint: compute.storageResourceUseRestrictions
    listPolicy:
      allowedValues:
        - under:organization/organization-id
    
  4. Apply the policy.yaml file to your organization. Replace organization-id with your 12-digit numeric organization ID.

    gcloud beta resource-manager org-policies set-policy \
        --organization organization-id org-policy.yaml
    

When you have finished configuring the constraints in your organization policy, test those constraints to ensure that they create the restrictions that you need.

Using images from another project

If someone has granted you access to one or more images in another project, you can access these images in the project by specifying the image project in your requests.

To learn how to use an image to create new resources, such as creating an instance, read Creating and starting an instance.

For example, the following command creates an instance using an image called database-image-a from project database-images:

gcloud compute instances create test-instance \
    --image database-image-a --image-project database-images

You can also create boot persistent disks based off of images in another project. For information about creating a boot disk from an image, see Creating a standalone boot persistent disk.

Revoking access to shared images

After a user no longer needs access to your Compute Engine resources, revoke their access by using the Google Cloud Console, gcloud command-line tool, or the Compute Engine API.

Console

  1. In the Google Cloud Console, go to the Images page of the image project.

    Go to the Images page

  2. Select the checkboxes next to the images you want to update.

  3. Click Show info panel to expand the permissions column.

  4. Expand the role for which you want to remove users.

  5. Click Delete to remove a user from that role.

gcloud

To remove a user from a role on an image, use the remove-iam-policy-binding subcommand with the --member and --role flags.

gcloud compute images remove-iam-policy-binding image-name \
    --member='member' \
    --role='role'

Replace the following:

  • image-name: The name of the image. For example, my_image.
  • member: The identity you want to remove. Must be of the form user|group|serviceAccount:email or domain:domain. For example:
    • user:test-user@gmail.com
    • group:admins@example.com
    • serviceAccount:test123@example.domain.com
    • domain:example.domain.com
  • role: The role from which you want to remove the identity.

If you are revoking access to a resource that is currently in beta, use a gcloud beta compute command instead.

API

To modify an IAM policy directly through the API, do the following:

  1. Read the existing policy with the resource's respective getIamPolicy method.

    POST https://compute.googleapis.com/compute/v1/projects/project-id/global/images/image-name:getIamPolicy

    Replace the following:

    • project-id: The project ID this image belongs to.
    • image-name: The name of the image.

    Compute Engine returns the current policy in the response.

  2. Edit the policy with a text editor to remove members from the associated roles.

  3. Write the updated policy with setIamPolicy():

    POST https://compute.googleapis.com/compute/v1/projects/project-id/zones/global/images/image-name:setIamPolicy

    Replace the following:

    • project-id: The project ID this image belongs to.
    • image-name: The name of the image.

      In the body of the request, provide the updated IAM policy from the previous step.

What's next