Creating and managing custom roles

This page describes how to create and manage a custom role.

Before you begin

  • Read Understanding IAM Custom Roles, which contains information about the permissions required to create custom roles and best practices.
  • If you are using the gcloud command-line utility, make sure that you're using version 188.0.0 or later. To update gcloud to version 188.0.0, run the following command: gcloud components update --version 188.0.0

Viewing the available permissions for a resource

Before you create a custom role, you might want to know what permissions can be applied to a resource. You can get all permissions that can be applied to a resource, and the resources below that in the hierarchy, using the gcloud command-line tool, the Cloud Console, or the IAM API. For example, you can get all permissions that you can apply on an organization and on projects in that organization.

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Select your project from the drop-down at the top of the page.

  3. Select the checkbox for a resource's admin role to view all the permissions that you can apply on that resource. For example, when you select the Compute Instance Admin role, the right side panel displays all the permissions that you can apply on a Compute Engine instance.

gcloud command

Use the gcloud iam list-testable-permissions command to get a list of permissions that can be applied on a target resource. The returned permissions are the permissions that can be used to create a custom role at this resource and any resource below in the hierarchy.

The following example demonstrates how to list testable permissions for a project resource:

gcloud iam list-testable-permissions project-id

project-id is the ID of the project in the form of a full resource name: //cloudresourcemanager.googleapis.com/projects/project-id, such as //cloudresourcemanager.googleapis.com/projects/my-project-id.

The list-testable-permissions command may return hundreds of results. To limit the results, you can also specify a filter expression. A truncated example of possible results is shown below:

---
name: appengine.applications.create
stage: GA
---
customRolesSupportLevel: TESTING
name: appengine.applications.disable
stage: GA
---
name: appengine.applications.get
stage: GA
---
customRolesSupportLevel: NOT_SUPPORTED
name: appengine.applications.list
onlyInPredefinedRoles: true
stage: GA
---
name: appengine.applications.update
stage: GA
---
name: appengine.instances.delete
stage: GA
---
name: appengine.instances.get
stage: GA
---

Note that each permission indicates whether it is supported in a custom role. For a complete list of supported and unsupported permissions, see Custom Roles Permissions Support.

REST API

The permissions.queryTestablePermissions method lists every permission that you can test on a resource.

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

  • full-resource-name: A URI consisting of the service name and the path to the resource. For examples, see Full resource names.
  • page-size: Optional. The number of permissions to include in the response. The default value is 100, and the maximum value is 1,000. If the number of permissions is greater than the page size, the response contains a pagination token that you can use to retrieve the next page of results.
  • next-page-token: Optional. The pagination token returned in an earlier response from this method. If specified, the list of testable permissions will start where the previous response ended.

HTTP method and URL:

POST https://iam.googleapis.com/v1/permissions:queryTestablePermissions

Request JSON body:

{
  "fullResourceName": "full-resource-name"
  "pageSize": page-size,
  "pageToken": "next-page-token"
}

To send your request, expand one of these options:

You should receive a JSON response similar to the following:

{
  "permissions": [
    {
      "name": "iam.serviceAccountKeys.create",
      "stage": "GA"
    },
    {
      "name": "iam.serviceAccountKeys.delete",
      "stage": "GA"
    },
    {
      "name": "iam.serviceAccountKeys.get",
      "stage": "GA"
    }
  ],
  "nextPageToken": "CgoHBajEfjUDQyABEPaIv5vIiMDTVhgDIhtpYW0uc2VydmljZUFjY291bnRLZXlzLmxpc3Q"
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using System.Collections.Generic;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static IList<Permission> QueryTestablePermissions(
        string fullResourceName)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        var request = new QueryTestablePermissionsRequest
        {
            FullResourceName = fullResourceName
        };
        var response = service.Permissions.QueryTestablePermissions(request)
            .Execute();
        foreach (var p in response.Permissions)
        {
            Console.WriteLine(p.Name);
        }
        return response.Permissions;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// queryTestablePermissions lists testable permissions on a resource.
func queryTestablePermissions(w io.Writer, fullResourceName string) ([]*iam.Permission, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	request := &iam.QueryTestablePermissionsRequest{
		FullResourceName: fullResourceName,
	}
	response, err := service.Permissions.QueryTestablePermissions(request).Do()
	if err != nil {
		return nil, fmt.Errorf("Permissions.QueryTestablePermissions: %v", err)
	}
	for _, p := range response.Permissions {
		fmt.Fprintf(w, "Found permissions: %v", p.Name)
	}
	return response.Permissions, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def query_testable_permissions(resource):
    """Lists valid permissions for a resource."""

    # pylint: disable=no-member
    permissions = service.permissions().queryTestablePermissions(body={
        'fullResourceName': resource
    }).execute()['permissions']
    for p in permissions:
        print(p['name'])

Getting the role metadata

Before you create a custom role, you might want to get the metadata for both predefined and custom roles. Role metadata includes the role ID and permissions contained in the role. You can view the metadata using the Google Cloud Platform Console or the IAM API.

To view the role metadata, use one of the methods below:

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Select your organization or project from the drop-down list at the top of the page.

  3. Select the checkbox for one or more roles to view the role permissions. The right side panel displays the permissions contained in the role(s), if any.

The icons in the Type column indicate if it's a custom role or a predefined role

If you want to find all the roles that include a specific permission, type the permission name in the Filter box at the top of the Roles list.

gcloud command

Use the gcloud iam roles describe command to view metadata for predefined roles and custom roles.

To view the metadata for a predefined role, execute the following gcloud command:

gcloud iam roles describe role-id

role-id is the ID of the role. Predefined roles include the role prefix in their IDs, for example, roles/iam.roleViewer.

The following example demonstrates the output of the describe command when executed on the predefined role roles/iam.roleViewer:

gcloud iam roles describe roles/iam.roleViewer

description: Read access to all custom roles in the project.
etag: AA==
includedPermissions:
- iam.roles.get
- iam.roles.list
- resourcemanager.projects.get
- resourcemanager.projects.getIamPolicy
name: roles/iam.roleViewer
stage: GA
title: Role Viewer

To view the metadata for a custom role, execute one of the following gcloud commands:

  • To view the metadata for a custom role created at the organization level, execute the following command:

    gcloud iam roles describe --organization=organization-id role-id
    
  • To view the metadata for a custom role created at the project level, execute the following command:

    gcloud iam roles describe --project=project-id role-id
    

Each placeholder value is described below:

  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.
  • role-id is the ID of the role, excluding any prefixes like projects/, organizations/, or roles/. For example, myCompanyAdmin.

For more information, see the reference documentation for gcloud iam roles describe.

REST API

The roles.get method gets the definition of a role.

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

  • full-role-id: The full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.

HTTP method and URL:

GET https://iam.googleapis.com/v1/full-role-id

To send your request, expand one of these options:

The response contains the role definition.

{
  "name": "projects/my-project/roles/customRole",
  "title": "My Custom Role",
  "description": "My custom role description.",
  "includedPermissions": [
    "storage.buckets.get",
    "storage.buckets.list"
  ],
  "etag": "BwWiPg2fmDE="
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static Role GetRole(string name)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        var role = service.Roles.Get(name).Execute();
        Console.WriteLine(role.Name);
        Console.WriteLine(String.Join(", ", role.IncludedPermissions));
        return role;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// getRole gets role metadata.
func getRole(w io.Writer, name string) (*iam.Role, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	role, err := service.Roles.Get(name).Do()
	if err != nil {
		return nil, fmt.Errorf("Roles.Get: %v", err)
	}
	fmt.Fprintf(w, "Got role: %v\n", role.Name)
	for _, permission := range role.IncludedPermissions {
		fmt.Fprintf(w, "Got permission: %v\n", permission)
	}
	return role, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def get_role(name):
    """Gets a role."""

    # pylint: disable=no-member
    role = service.roles().get(name=name).execute()
    print(role['name'])
    for permission in role['includedPermissions']:
        print(permission)

Creating a custom role

You can create a custom role at the project or organization level.

To create a custom role, a caller must possess iam.roles.create permission. By default, the owner of a project or an organization has this permission and can create and manage custom roles.

Users who are not owners, including organization admins, must be assigned either the Organization Role Administrator role, or the IAM Role Administrator role.

The total size of the title, description, and permission names for a custom role is limited to 64 KB. If you need to create a larger custom role, you can split the permissions across multiple custom roles. Choose role titles that show the relationship between the custom roles, such as Custom Admin (1 of 2) and Custom Admin (2 of 2).

Console

To create a new custom role from scratch:

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Using the drop-down list at the top of the page, select the organization or project in which you want to create a role.

  3. Click Create Role.

  4. Enter a Name, a Title, and Description for the role.

  5. Click Add Permissions.

  6. Select the permissions you want to include in the role and click Add Permissions. Use the All Services and All Types drop-downs to filter and select permissions by services and types.

Creating a custom role based on an existing curated role:

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Select the organization or project in which you want to create a role.
  3. Select the roles on which you want to base the new custom role.
  4. Click Create Role from Selection.
  5. Enter a Name, a Title, and Description for the role.
  6. Uncheck the permissions you want to exclude from the role.
  7. Click Add Permissions to include any permissions.
  8. Click Create.

gcloud command

Use the gcloud iam roles create command to create new custom roles. You can use this command in two ways:

  • By providing a YAML file that contains the role definition
  • By using flags to specify the role definition

When creating a custom role, you must specify whether it applies to the organization level or project level by using the --organization=organization-id or --project=project-id flags. Each example below creates a custom role at the project level.

To create a custom role using a YAML file:

Create a YAML file that contains the definition for your custom role. The file must be structured in the following way:

title: role-title
description: role-description
stage: launch-stage
includedPermissions:
- permission-1
- permission-2

Each placeholder value is described below:

  • role-title is a friendly title for the role, such as "My Company Admin".
  • role-description is a short description of the role, such as "My custom role description".
  • launch-stage indicates the stage of a role in the launch lifecycle, such as ALPHA, BETA, or GA.
  • permission-1 and permission-2 are permissions to include in the custom role, such as iam.roles.get.

Save the YAML file, and then execute one of the following commands:

  • To create a custom role at the organization level, execute the following command:

    gcloud iam roles create role-id --organization=organization-id \
      --file=yaml-file-path
    
  • To create a custom role at the project level, execute the following command:

    gcloud iam roles create role-id --project=project-id \
      --file=yaml-file-path
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.
  • yaml-file-path is the path to the location of your YAML file that contains the custom role definition.

Examples

The following example YAML file demonstrates how to create a role definition:

title: "My Company Admin"
description: "My custom role description."
stage: "ALPHA"
includedPermissions:
- iam.roles.get
- iam.roles.list

The following example demonstrates how to create a role at the organization level using the YAML file:

gcloud iam roles create myCompanyAdmin --organization=123456789012 \
  --file=my-role-definition.yaml

If the role was created successfully, the command's output is similar to the following:

Created role [myCompanyAdmin].
description: My custom role description.
etag: BwVkBX0sQD0=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: organizations/123456789012/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

The following example demonstrates how to create a role at the project level using the YAML file:

gcloud iam roles create myCompanyAdmin --project=my-project-id \
  --file=my-role-definition.yaml

If the role was created successfully, the command's output is similar to the following:

Created role [myCompanyAdmin].
description: My custom role description.
etag: BwVkBX0sQD0=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

To create a custom role using flags:

Execute one of the following commands:

  • To create a custom role at the organization level, execute the following command:

    gcloud iam roles create role-id --organization=organization-id \
      --title=role-title --description=role-description \
      --permissions=permissions-list --stage=launch-stage
    
  • To create a custom role at the project level, execute the following command:

    gcloud iam roles create role-id --project=project-id \
      --title=role-title --description=role-description \
      --permissions=permissions-list --stage=launch-stage
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.
  • role-title is a friendly title for the role, such as "My Company Admin".
  • role-description is a short description of the role, such as "My custom role description.".
  • permissions-list contains a comma-separated list of permissions you want to include in the custom role. For example: iam.roles.get,iam.roles.list.
  • launch-stage indicates the stage of a role in the launch lifecycle, such as ALPHA, BETA, or GA.

Examples

The following example demonstrates how to create a role at the organization level using flags:

gcloud iam roles create myCompanyAdmin --organization=123456789012\
  --title="My Company Admin" --description="My custom role description." \
  --permissions=iam.roles.get,iam.roles.list --stage=ALPHA

If the role was created successfully, the command's output is similar to the following:

Created role [myCompanyAdmin].
description: My custom role description.
etag: BwVkBX0sQD0=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: organizations/123456789012/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

The following example demonstrates how to create a role at the project level using flags:

gcloud iam roles create myCompanyAdmin --project=my-project-id \
  --title="My Company Admin" --description="My custom role description." \
  --permissions=iam.roles.get,iam.roles.list --stage=ALPHA

If the role was created successfully, the command's output is similar to the following:

Created role [myCompanyAdmin].
description: My custom role description.
etag: BwVkBX0sQD0=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

REST API

The roles.create method creates a custom role in a project or organization.

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

  • resource-type: The resource type whose custom roles you want to list. Use the value projects or organizations.
  • resource-id: The project ID or organization ID whose custom roles you want to list.
  • role-id: The name of the role, such as myCompanyAdmin.
  • role-title: The human-readable title for the role. For example, My Company Admin.
  • role-description: A description for the role. For example, "The company admin role allows company admins to access important resources".
  • permission-1 and permission-2: The permissions that you want to include in the role. For example, storage.objects.update.
  • launch-stage: The current launch stage of the role. This field can contain one of the following values: EAP, ALPHA, BETA, GA, DEPRECATED, or DISABLED.

HTTP method and URL:

POST https://iam.googleapis.com/v1/resource-type/resource-id/roles

Request JSON body:

{
  "roleId": "role-id",
  "role": {
    "title": "role-title",
    "description": "role-description",
    "includedPermissions": [
      "permission-1",
      "permission-2"
    ],
    "stage": launch-stage
  }
}

To send your request, expand one of these options:

The response contains the role you created.

{
  "name": "projects/myProject/roles/myCompanyAdmin",
  "title": "My Company Admin",
  "description": "My custom role description.",
  "includedPermissions": [
    "iam.roles.get",
    "iam.roles.list"
  ],
  "etag": "BwWox/JbaZw="
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using System.Collections.Generic;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static Role CreateRole(string name, string projectId, string title,
        string description, IList<string> permissions, string stage)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        var role = new Role
        {
            Title = title,
            Description = description,
            IncludedPermissions = permissions,
            Stage = stage
        };
        var request = new CreateRoleRequest
        {
            Role = role,
            RoleId = name
        };
        role = service.Projects.Roles.Create(request,
            "projects/" + projectId).Execute();
        Console.WriteLine("Created role: " + role.Name);
        return role;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// createRole creates a custom role.
func createRole(w io.Writer, projectID, name, title, description, stage string, permissions []string) (*iam.Role, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	request := &iam.CreateRoleRequest{
		Role: &iam.Role{
			Title:               title,
			Description:         description,
			IncludedPermissions: permissions,
			Stage:               stage,
		},
		RoleId: name,
	}
	role, err := service.Projects.Roles.Create("projects/"+projectID, request).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.Roles.Create: %v", err)
	}
	fmt.Fprintf(w, "Created role: %v", role.Name)
	return role, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def create_role(name, project, title, description, permissions, stage):
    """Creates a role."""

    # pylint: disable=no-member
    role = service.projects().roles().create(
        parent='projects/' + project,
        body={
            'roleId': name,
            'role': {
                'title': title,
                'description': description,
                'includedPermissions': permissions,
                'stage': stage
            }
        }).execute()

    print('Created role: ' + role['name'])
    return role

Editing an existing custom role

Read-Modify-Write

A common pattern for updating a resource's metadata, such as a custom role, is to read its current state, update the data locally, and then send the modified data for writing. This pattern could cause a conflict if two or more independent processes attempt the sequence simultaneously. For example, if two owners for a project try to make conflicting changes to a role at the same time, some changes could fail. Cloud IAM solves this problem using an etag property in custom roles. This property is used to verify if the custom role has changed since the last request. When you make a request to Cloud IAM with an etag value, Cloud IAM compares the etag value in the request with the existing etag value associated with the custom role. It writes the change only if the etag values match.

When you update a role, first get the role using roles.get(), update the role, and then write the updated role using roles.patch(). Use the etag value when setting the role only if the corresponding role in roles.get() contains an etag value.

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Using the drop-down list at the top of the page, select the project or organization that contains the role that you want to edit.

  3. Click on a custom role.

  4. Click Edit Role.

  5. Click Add Permissions to add new permissions to the role.

  6. Uncheck permissions to remove permissions from the role.

  7. Click Update to save the edited role.

gcloud command

Use the gcloud iam roles update command to update custom roles. You can use this command in two ways:

  • By providing a YAML file that contains the updated role definition
  • By using flags to specify the updated role definition

When updating a custom role, you must specify whether it applies to the organization level or project level by using the --organization=organization-id or --project=project-id flags. Each example below creates a custom role at the project level.

To update a custom role using a YAML file:

Get the current definition for the role by executing one of the following commands:

  • To get the role definition of an organization-level custom role, execute the following command:

    gcloud iam roles describe role-id --organization=organization-id
    
  • To get the role definition of a project-level custom role, execute the following command:

    gcloud iam roles describe role-id --project=project-id
    

Each placeholder value is described below:

  • role-id is the name of the role to update, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.

The describe command returns the role's definition and includes an etag value that uniquely identifies the current version of the role. The etag value should be provided in the updated role definition to ensure that any concurrent role changes are not overwritten.

The describe command returns the following output:

description: role-description
etag: etag-value
includedPermissions:
- permission-1
- permission-2
name: full-role-id
stage: launch-stage
title: role-title

Each placeholder value is described below:

  • role-description is a short description of the role, such as "My custom role description".
  • etag-value is the unique identifier for the current version of the role, such as BwVkBkbfr70=.
  • permission-1 and permission-2 are permissions to include in the custom role, such as iam.roles.get.
  • full-role-id is the full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.
  • launch-stage indicates the stage of a role in the launch lifecycle, such as ALPHA, BETA, or GA.
  • role-title is a friendly title for the role, such as "My Company Admin".

To update the role, either include the outputted role definition to a YAML file or update the original YAML file with the outputted etag value.

Consider the following example YAML file, which contains the output from the describe command for a project-level role and adds two Cloud Storage permissions:

description: My custom role description.
etag: BwVkBkbfr70=
includedPermissions:
- iam.roles.get
- iam.roles.list
- storage.buckets.get
- storage.buckets.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

Save the YAML file, and then execute one of the following commands:

  • To update an organization-level role, execute the following command:

    gcloud iam roles update role-id --organization=organization-id \
      --file=yaml-file-path
    
  • To update a project-level role, execute the following command:

    gcloud iam roles update role-id --project=project-id \
      --file=yaml-file-path
    

Each placeholder value is described below:

  • role-id is the name of the role to update, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.
  • yaml-file-path is the path to the location of your YAML file that contains the updated custom role definition.

Examples

The following example demonstrates how to update an organization-level role using a YAML file:

gcloud iam roles update myCompanyAdmin --organization=123456789012 \
  --file=my-role-definition.yaml

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkBwDN0lg=
includedPermissions:
- iam.roles.get
- iam.roles.list
- storage.buckets.get
- storage.buckets.list
name: organizations/123456789012/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

The following example demonstrates how to update a project-level role using a YAML file:

gcloud iam roles update myCompanyAdmin --project=my-project-id \
  --file=my-role-definition.yaml

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkBwDN0lg=
includedPermissions:
- iam.roles.get
- iam.roles.list
- storage.buckets.get
- storage.buckets.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

To update a custom role using flags:

Each part of a role definition can be updated using a corresponding flag. See the gcloud iam roles update topic for a list of all possible flags.

You can use the following flags to add or remove permissions:

  • --add-permissions=permissions: Adds one or more comma-separated permissions to the role.
  • --remove-permissions=permissions: Removes one or more comma-separated permissions from the role.

Alternatively, you can simply specify the new permissions using the --permissions=permissions flag and providing a comma-separated list of permissions to replace the existing permissions list.

To update other parts of the role definition, execute one of the following commands:

  • To update an organization-level role, execute the following command:

    gcloud iam roles update role-id --organization=organization-id \
      --title=role-title --description=role-description \
      --stage=launch-stage
    
  • To update a project-level role, execute the following command:

    gcloud iam roles update role-id --project=project-id \
      --title=role-title --description=role-description \
      --stage=launch-stage
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.
  • role-title is a friendly title for the role, such as "My Company Admin".
  • role-description is a short description of the role, such as "My custom role description.".
  • launch-stage indicates the stage of a role in the launch lifecycle, such as ALPHA, BETA, or GA.

Examples

The following example demonstrates how to add permissions to an organization-level role using flags:

gcloud iam roles update myCompanyAdmin --organization=123456789012 \
  --add-permissions=storage.buckets.get,storage.buckets.list

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkBwDN0lg=
includedPermissions:
- iam.roles.get
- iam.roles.list
- storage.buckets.get
- storage.buckets.list
name: organization/123456789012/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

The following example demonstrates how to add permissions to a project-level role using flags:

gcloud iam roles update myCompanyAdmin --project=my-project-id \
  --add-permissions=storage.buckets.get,storage.buckets.list

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkBwDN0lg=
includedPermissions:
- iam.roles.get
- iam.roles.list
- storage.buckets.get
- storage.buckets.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

REST API

The roles.patch method updates a custom role in a project or organization.

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

Required:

  • resource-type: The resource type whose custom roles you want to list. Use the value projects or organizations.
  • resource-id: The project ID or organization ID whose custom roles you want to list.
  • full-role-id: The full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.

Recommended:

  • etag: An identifier for a version of the role. Include this field to prevent concurrent changes to the role.

Optional (define one or more of the following values):

  • role-title: The human-readable title for the role. For example, My Company Admin.
  • role-description: A description for the role. For example, "The company admin role allows company admins to access important resources".
  • permission-1 and permission-2: The permissions that you want to include in the role. For example, storage.objects.update.
  • launch-stage: The current launch stage of the role. This field can contain one of the following values: EAP, ALPHA, BETA, GA, DEPRECATED, or DISABLED.

HTTP method and URL:

PATCH https://iam.googleapis.com/v1/resource-type/resource-id/roles

Request JSON body:

{
  "roleId": "full-role-id",
  "title": "role-title",
  "description": "role-description",
  "includedPermissions": [
    "permission-1",
    "permission-2"
  ],
  "stage": launch-stage,
  "etag": "etag"
}

To send your request, expand one of these options:

The response contains an abbreviated role definition that includes the role name, the fields that you updated, and an etag that identifies the current version of the role.

{
  "name": "projects/test-project-1000092/roles/myCompanyAdmin",
  "title": "My Updated Company Admin",
  "includedPermissions": [
    "storage.buckets.get",
    "storage.buckets.list"
  ],
  "stage": "BETA",
  "etag": "BwWoyDpAxBc="
}

Some predefined roles contain deprecated permissions or permissions that are otherwise not permitted in custom roles. Creating a custom role based on a predefined role that contains any deprecated or restricted permissions will fail.

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using System.Collections.Generic;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static Role EditRole(string name, string projectId, string newTitle,
        string newDescription, IList<string> newPermissions, string newStage)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });
        // First, get a Role using List() or Get().
        string resource = $"projects/{projectId}/roles/{name}";
        var role = service.Projects.Roles.Get(resource).Execute();
        // Then you can update its fields.
        role.Title = newTitle;
        role.Description = newDescription;
        role.IncludedPermissions = newPermissions;
        role.Stage = newStage;
        role = service.Projects.Roles.Patch(role, resource).Execute();
        Console.WriteLine("Updated role: " + role.Name);
        return role;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// editRole modifies a custom role.
func editRole(w io.Writer, projectID, name, newTitle, newDescription, newStage string, newPermissions []string) (*iam.Role, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	resource := "projects/" + projectID + "/roles/" + name
	role, err := service.Projects.Roles.Get(resource).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.Roles.Get: %v", err)
	}
	role.Title = newTitle
	role.Description = newDescription
	role.IncludedPermissions = newPermissions
	role.Stage = newStage
	role, err = service.Projects.Roles.Patch(resource, role).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.Roles.Patch: %v", err)
	}
	fmt.Fprintf(w, "Updated role: %v", role.Name)
	return role, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def edit_role(name, project, title, description, permissions, stage):
    """Creates a role."""

    # pylint: disable=no-member
    role = service.projects().roles().patch(
        name='projects/' + project + '/roles/' + name,
        body={
            'title': title,
            'description': description,
            'includedPermissions': permissions,
            'stage': stage
        }).execute()

    print('Updated role: ' + role['name'])
    return role

Disabling a custom role

You can disable a custom role. When a role is disabled, any policy bindings related to the role are inactivated, meaning that the permissions in the role will not be granted, even if you grant the role to a user.

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Click on "Select a project" drop-down at the top of the page.

  3. Select your organization or project.

  4. Select a custom role and click Disable.

gcloud command

Use the gcloud iam roles update command to disable a custom role by setting its launch stage to DISABLED. As described in the gcloud tab of the Editing an existing custom role section, you can update an existing custom role in the following two ways:

  • By providing a YAML file that contains the updated role definition
  • By using flags to specify the updated role definition

The easiest way to disable an existing custom role is to use the --stage flag and set it to DISABLED. Execute one of the following commands:

  • To disable an organization-level role, execute the following command:

    gcloud iam roles update role-id --organization=organization-id \
      --stage=DISABLED
    
  • To disable a project-level role, execute the following command:

    gcloud iam roles update role-id --project=project-id \
      --stage=DISABLED
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.

Examples

The following example demonstrates how to disable an organization-level role:

gcloud iam roles update myCompanyAdmin --organization=123456789012 \
  --stage=DISABLED

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkB5NLIQw=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: organization/123456789012/roles/myCompanyAdmin
stage: DISABLED
title: My Company Admin

The following example demonstrates how to disable a project-level role:

gcloud iam roles update myCompanyAdmin --project=my-project-id \
  --stage=DISABLED

If the role was updated successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkB5NLIQw=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: DISABLED
title: My Company Admin

REST API

The roles.patch method lets you change a custom role's launch stage to DISABLED, which disables the role.

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

  • resource-type: The resource type whose custom roles you want to list. Use the value projects or organizations.
  • resource-id: The project ID or organization ID whose custom roles you want to list.
  • full-role-id: The full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.

  • etag: An identifier for a version of the role. Include this field to prevent concurrent changes to the role.

HTTP method and URL:

PATCH https://iam.googleapis.com/v1/resource/resource-id/roles

Request JSON body:

{
  "roleId": "full-role-id",
  "stage": DISABLED,
  "etag": "etag"
}

To send your request, expand one of these options:

You should receive a JSON response similar to the following:

{
  "name": "projects/test-project-1000092/roles/myCompanyAdmin",
  "stage": "DISABLED",
  "etag": "BwWoyDpAxBc="
}

C#

Update the stage field of the role to DISABLED.

Go

Update the stage field of the role to DISABLED.

Python

Update the stage field of the role to DISABLED.

Listing roles

You can list all custom roles created in your project or organization.

Console

In the Cloud Console, go to the Roles page.

Go to the Roles page

All the custom roles for the organization or project that you have selected are listed on the page.

gcloud command

Use the gcloud iam roles list command to list custom roles and predefined roles for a project or organization.

To list custom roles, execute one of the following commands:

  • To list organization-level custom roles, execute the following command:

    gcloud iam roles list --organization=organization-id
    
  • To list project-level custom roles, execute the following command:

    gcloud iam roles list --project=project-id
    

Each placeholder value is described below:

  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.

To list deleted roles, you can also specify the --show-deleted flag.

Execute the following gcloud command to list predefined roles:

gcloud iam roles list

REST API

The roles.list method lists all of the custom roles in a project or organization.

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

  • resource-type: The resource type whose custom roles you want to list. Use the value projects or organizations.
  • resource-id: The project ID or organization ID whose custom roles you want to list.
  • role-view: Optional. The information to include for the returned roles. To include the roles' permissions, set this field to FULL. To exclude the roles' permissions, set this field to BASIC. The default value is BASIC.
  • page-size: Optional. The number of roles to include in the response. The default value is 300, and the maximum value is 1,000. If the number of roles is greater than the page size, the response contains a pagination token that you can use to retrieve the next page of results.
  • next-page-token: Optional. The pagination token returned in an earlier response from this method. If specified, the list of roles will start where the previous request ended.

HTTP method and URL:

GET https://iam.googleapis.com/v1/resource-type/resource-id/roles?view=role-view&pageSize=page-size&pageToken=next-page-token

To send your request, expand one of these options:

You should receive a JSON response similar to the following:

{
  "roles": [
    {
      "name": "projects/my-project/roles/customRole1",
      "title": "First Custom Role",
      "description": "Created on: 2020-06-01",
      "etag": "BwWiPg2fmDE="
    },
    {
      "name": "projects/my-project/roles/customRole2",
      "title": "Second Custom Role",
      "description": "Created on: 2020-06-07",
      "etag": "BwWiuX53Wi0="
    }
  ]
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using System.Collections.Generic;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static IList<Role> ListRoles(string projectId)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        var response = service.Projects.Roles.List("projects/" + projectId)
            .Execute();
        foreach (var role in response.Roles)
        {
            Console.WriteLine(role.Name);
        }
        return response.Roles;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// listRoles lists a project's roles.
func listRoles(w io.Writer, projectID string) ([]*iam.Role, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	response, err := service.Projects.Roles.List("projects/" + projectID).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.Roles.List: %v", err)
	}
	for _, role := range response.Roles {
		fmt.Fprintf(w, "Listing role: %v\n", role.Name)
	}
	return response.Roles, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def list_roles(project_id):
    """Lists roles."""

    # pylint: disable=no-member
    roles = service.roles().list(
        parent='projects/' + project_id).execute()['roles']
    for role in roles:
        print(role['name'])

Deleting a custom role

You can delete any custom role in your project or organization.

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Select the role you wish to delete and click Delete on the top of the page.

gcloud command

Use the gcloud iam roles delete command to delete a custom role. The role is suspended and cannot be used to create new IAM policy bindings.

To delete a custom role, execute one of the following commands:

  • To delete an organization-level custom role, execute the following command:

    gcloud iam roles delete role-id --organization=organization-id
    
  • To delete a project-level custom role, execute the following command:

    gcloud iam roles delete role-id --project=project-id
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.

The role will not be included in gcloud iam roles list, unless the --show-deleted flag is included. Deleted roles are indicated by the deleted: true block in a list response, such as:

---
deleted: true
description: My custom role description.
etag: BwVkB5NLIQw=
name: projects/my-project-id/roles/myCompanyAdmin
title: My Company Admin
---

REST API

The roles.delete method deletes a custom role in a project or organization.

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

  • full-role-id: The full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.

HTTP method and URL:

DELETE https://iam.googleapis.com/v1/full-role-id

To send your request, expand one of these options:

The response contains the definition of the role that was deleted.

{
  "name": "projects/my-project/roles/myCompanyAdmin",
  "title": "My Company Admin",
  "description": "My custom role description.",
  "includedPermissions": [
    "iam.roles.get",
    "iam.roles.list"
  ],
  "etag": "BwWiPg2fmDE=",
  "deleted": true
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static void DeleteRole(string name, string projectId)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        service.Projects.Roles.Delete(
            $"projects/{projectId}/roles/{name}").Execute();
        Console.WriteLine("Deleted role: " + name);
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// deleteRole deletes a custom role.
func deleteRole(w io.Writer, projectID, name string) error {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return fmt.Errorf("iam.NewService: %v", err)
	}

	_, err = service.Projects.Roles.Delete("projects/" + projectID + "/roles/" + name).Do()
	if err != nil {
		return fmt.Errorf("Projects.Roles.Delete: %v", err)
	}
	fmt.Fprintf(w, "Deleted role: %v", name)
	return nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def delete_role(name, project):
    """Deletes a role."""

    # pylint: disable=no-member
    role = service.projects().roles().delete(
        name='projects/' + project + '/roles/' + name).execute()

    print('Deleted role: ' + name)
    return role

When a role is deleted, its bindings remain, but are inactive. You can undelete a role within 7 days. During this 7-day period, the role will show as Deleted in the Cloud Console, and will not appear in programmatic list commands (unless showDeleted is set in the request).

After 7 days, the role is scheduled for permanent deletion. At this point, the role no longer counts towards the limit of 300 custom roles per organization or 300 custom roles per project.

The permanent deletion process takes 30 days. During the 30-day window, the role and all associated bindings are permanently removed, and you cannot create a new role with the same role ID.

After the role has been permanently deleted, 37 days after the initial deletion request, you can create a new role using the same role ID.

Undeleting a custom role

Undeleting a role returns it to its previous state.

Roles can only be deleted within 7 days. After 7 days, the role is permanently deleted and all bindings associated with the role are removed.

Console

  1. In the Cloud Console, go to the Roles page.

    Go to the Roles page

  2. Locate the role you wish to undelete, click on the more icon at the end of the row, and click Undelete.

gcloud command

Use the gcloud iam roles undelete command to undelete a custom role.

To undelete a custom role, execute one of the following commands:

  • To undelete an organization-level custom role, execute the following command:

    gcloud iam roles undelete role-id --organization=organization-id
    
  • To undelete a project-level custom role, execute the following command:

    gcloud iam roles undelete role-id --project=project-id
    

Each placeholder value is described below:

  • role-id is the name of the role, such as myCompanyAdmin.
  • organization-id is the numeric ID of the organization, such as 123456789012.
  • project-id is the name of the project, such as my-project-id.

Examples

The following example demonstrates how to undelete an organization-level custom role:

gcloud iam roles undelete myCompanyAdmin --organization=123456789012

If the role was undeleted successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkCAx9W6w=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: organization/123456789012/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

The following example demonstrates how to undelete a project-level custom role:

gcloud iam roles undelete myCompanyAdmin --project=my-project-id

If the role was undeleted successfully, the command's output is similar to the following:

description: My custom role description.
etag: BwVkCAx9W6w=
includedPermissions:
- iam.roles.get
- iam.roles.list
name: projects/my-project-id/roles/myCompanyAdmin
stage: ALPHA
title: My Company Admin

REST API

The roles.undelete method undeletes a custom role in a project or organization.

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

  • full-role-id: The full role ID, including any organizations/, projects/, or roles/ prefixes. For example, organizations/123456789012/roles/myCompanyAdmin.

  • etag: An identifier for a version of the role. Include this field to prevent concurrent changes to the role.

HTTP method and URL:

POST https://iam.googleapis.com/v1/full-role-id:undelete

Request JSON body:

{
  "etag": "etag"
}

To send your request, expand one of these options:

The response contains the definition of the role that was undeleted.

{
  "name": "projects/my-project/roles/myCompanyAdmin",
  "title": "My Company Admin",
  "description": "My custom role description.",
  "includedPermissions": [
    "iam.roles.get",
    "iam.roles.list"
  ],
  "etag": "BwWiPg2fmDE="
}

C#

Before trying this sample, follow the C# setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM C# API reference documentation.


using System;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class CustomRoles
{
    public static Role UndeleteRole(string name, string projectId)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        string resource = $"projects/{projectId}/roles/{name}";
        var role = service.Projects.Roles.Undelete(
            new UndeleteRoleRequest(), resource).Execute();
        Console.WriteLine("Undeleted role: " + role.Name);
        return role;
    }
}

Go

Before trying this sample, follow the Go setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Go API reference documentation.

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// undeleteRole restores a deleted custom role.
func undeleteRole(w io.Writer, projectID, name string) (*iam.Role, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %v", err)
	}

	resource := "projects/" + projectID + "/roles/" + name
	request := &iam.UndeleteRoleRequest{}
	role, err := service.Projects.Roles.Undelete(resource, request).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.Roles.Undelete: %v", err)
	}
	fmt.Fprintf(w, "Undeleted role: %v", role.Name)
	return role, nil
}

Python

Before trying this sample, follow the Python setup instructions in the Cloud IAM Quickstart Using Client Libraries. For more information, see the Cloud IAM Python API reference documentation.

def undelete_role(name, project):
    """Undeletes a role."""

    # pylint: disable=no-member
    role = service.projects().roles().patch(
        name='projects/' + project + '/roles/' + name,
        body={
            'stage': 'DISABLED'
        }).execute()

    print('Disabled role: ' + role['name'])
    return role

What's next