Using IAM with Cloud KMS

KeyRings and CryptoKeys are resources in Google Cloud Platform, and can have IAM policies set on them like any other resource. IAM policies cannot be set on individual CryptoKeyVersions. KMS actions have a corresponding permission to determine who has access. See Permissions and Roles for a complete list of actions and permissions.

Modifying IAM permissions

Changing IAM permissions requires a user to have the permission to Set IAM Policy. As per the chart in Permissions and Roles, currently that is only possible for users or service accounts with the owner or cloudkms.admin role.

Command-line

Add a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects add-iam-policy-binding PROJECT_NAME \
    --member user:USER_EMAIL --role roles/ROLE_NAME

Windows cmd.exe

Add a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects add-iam-policy-binding PROJECT_NAME ^
    --member user:USER_EMAIL --role roles/ROLE_NAME

Powershell

Add a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects add-iam-policy-binding PROJECT_NAME `
    --member user:USER_EMAIL --role roles/ROLE_NAME

Command-line

Remove a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects remove-iam-policy-binding PROJECT_NAME \
    --member user:USER_EMAIL --role roles/ROLE_NAME

Windows cmd.exe

Remove a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects remove-iam-policy-binding PROJECT_NAME ^
    --member user:USER_EMAIL --role roles/ROLE_NAME

Powershell

Remove a user "USER_EMAIL" to the role "ROLE_NAME" for the project "PROJECT_NAME"

gcloud projects remove-iam-policy-binding PROJECT_NAME `
    --member user:USER_EMAIL --role roles/ROLE_NAME

Further instructions on using gcloud for IAM policies is available in our IAM documentation.

Hierarchy and inheritance

Policy bindings can be specified at the project level, as demonstrated above, but they can also be specified on KeyRings and CryptoKeys. Members follow the format user:USER_EMAIL for users and serviceAccount:SERVICE_ACCOUNT_EMAIL for service accounts. Roles follow the format roles/ROLE_NAME. The following example adds a member to a CryptoKey for a given role:

Command-line

gcloud kms keys add-iam-policy-binding CRYPTOKEY --location LOCATION --keyring KEYRING --member user:USER_EMAIL --role roles/ROLE_NAME

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object AddMemberToCryptoKeyPolicy(string projectId, string location,
          string keyRing, string cryptoKey, string role, string member)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for updating the crypto key IAM policy.
          var parent = $"projects/{projectId}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}";
          SetIamPolicyRequest setIamPolicyRequest = new SetIamPolicyRequest();
          var result = cloudKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(parent).Execute();
          if (result.Bindings != null)
          {
              // Policy already exists, so add a new Binding to it.
              Binding bindingToAdd = new Binding();
              bindingToAdd.Role = role;
              string[] testMembers = { member };
              bindingToAdd.Members = testMembers;
              result.Bindings.Add(bindingToAdd);
              setIamPolicyRequest.Policy = result;
          }
          else
          {
              // Policy does not yet exist, so create a new one.
              Policy newPolicy = new Policy();
              newPolicy.Bindings = new List<Binding>();
              Binding bindingToAdd = new Binding();
              bindingToAdd.Role = role;
              string[] testMembers = { member };
              bindingToAdd.Members = testMembers;
              newPolicy.Bindings.Add(bindingToAdd);
              setIamPolicyRequest.Policy = newPolicy;
          }
          var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .SetIamPolicyRequest(cloudKms, setIamPolicyRequest, parent);
          var setIamPolicyResult = request.Execute();
          var updateResult = cloudKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(parent).Execute();
          updateResult.Bindings.ToList().ForEach(response =>
          {
              Console.WriteLine($"Role: {response.Role}");
              response.Members.ToList().ForEach(memberFound =>
              {
                  Console.WriteLine($"  Member: {memberFound}");
              });
          });
          return 0;
      }

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Adds the given member to the given key, with the given role.
 *
 * @param ringId The id of the keyring.
 * @param keyId The id of the crypto key.
 * @param member The member to add. Must be in the proper format, eg:
 *
 *        allUsers
 *        user:$userEmail
 *        serviceAccount:$serviceAccountEmail
 *
 *        See https://g.co/cloud/kms/docs/reference/rest/v1/Policy#binding
 *        for more details.
 *
 * @param role Must be in one of the following formats:
 *        roles/[role]
 *        organizations/[organizationId]/roles/[role]
 *        projects/[projectId]/roles/[role]
 *
 *        See https://g.co/cloud/iam/docs/understanding-roles
 *        for available values for [role].
 */
public static Policy addMemberToCryptoKeyPolicy(
    String projectId, String ringId, String keyId, String member, String role)
    throws IOException {
  String location = "global";
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey version
  String cryptoKey = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
      projectId, location, ringId, keyId);

  // Get the current IAM policy
  Policy iamPolicy = getCryptoKeyPolicy(projectId, ringId, keyId);

  // Add the new account to it.
  Binding newBinding = new Binding()
      .setRole(role)
      .setMembers(Collections.singletonList(member));
  List<Binding> bindings = iamPolicy.getBindings();
  if (null == bindings) {
    bindings = Collections.singletonList(newBinding);
  } else {
    bindings.add(newBinding);
  }
  iamPolicy.setBindings(bindings);

  // Set the new IAM Policy.
  Policy newIamPolicy = kms.projects().locations().keyRings()
      .cryptoKeys()
      .setIamPolicy(cryptoKey, new SetIamPolicyRequest().setPolicy(iamPolicy))
      .execute();

  System.out.println("Response: " + newIamPolicy);
  return newIamPolicy;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key's key ring, e.g. "global"
// const location = 'global';

// The name of the crypto key's key ring, e.g. "my-key-ring"
// const keyRingName = 'my-key-ring';

// The name of the crypto key, e.g. "my-key"
// const keyName = 'my-key';

// The member to add to the crypto key, e.g. "user:developer@company.com"
// const member = 'user:developer@company.com';

// The role to give the member, e.g. "roles/viewer"
// const role = 'roles/viewer';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  let request = {
    // This will be a path parameter in the request URL
    resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}/cryptoKeys/${keyName}`
  };

  // Gets the IAM policy of a crypto key
  cloudkms.projects.locations.keyRings.cryptoKeys.getIamPolicy(request, (err, policy) => {
    if (err) {
      console.log(err);
      return;
    }

    policy = Object.assign({ bindings: [] }, policy);

    const index = policy.bindings.findIndex((binding) => binding.role === role);

    // Add the role/member combo to the policy
    const binding = Object.assign({
      role: role,
      members: []
    }, policy.bindings[index]);
    if (index === -1) {
      policy.bindings.push(binding);
    }
    if (!binding.members.includes(member)) {
      binding.members.push(member);
    }

    request = {
      // This will be a path parameter in the request URL
      resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}/cryptoKeys/${keyName}`,
      // This will be the request body
      resource: {
        policy: policy
      }
    };

    // Adds the member/role combo to the policy of the crypto key
    cloudkms.projects.locations.keyRings.cryptoKeys.setIamPolicy(request, (err, policy) => {
      if (err) {
        console.log(err);
        return;
      }

      console.log(`${member}/${role} combo added to policy for crypto key ${keyName}.`);
      if (policy.bindings) {
        policy.bindings.forEach((binding) => {
          if (binding.members && binding.members.length) {
            console.log(`${binding.role}:`);
            binding.members.forEach((member) => {
              console.log(`  ${member}`);
            });
          }
        });
      } else {
        console.log(`Policy for crypto key ${keyName} is empty.`);
      }
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Add a member to a CryptoKey IAM policy.
 *
 * @param string $projectId
 * @param string $ring
 * @param string $key
 * @param string $member Must be in the format "user:$userEmail" or
 *        "serviceAccount:$serviceAccountEmail"
 * @param string $role Must be in the format "roles/$role",
 *        "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"
 * @param string $location [optional]
 * @return null
 */
function add_member_to_cryptokey_policy($projectId, $ring, $key, $member, $role, $location = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the CryptoKey.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s',
        $projectId,
        $location,
        $ring,
        $key
    );

    // Get the current IAM policy and add the new account to it.
    $policy = $kms->projects_locations_keyRings_cryptoKeys->getIamPolicy($parent);
    $bindings = $policy->getBindings();
    $bindings[] = new Google_Service_CloudKMS_Binding([
        'members' => [$member],
        'role' => $role,
    ]);
    $policy->setBindings($bindings);

    // Set the new IAM Policy.
    $request = new Google_Service_CloudKMS_SetIamPolicyRequest(['policy' => $policy]);
    $kms->projects_locations_keyRings_cryptoKeys->setIamPolicy(
        $parent,
        $request
    );

    printf('Member %s added to policy for key %s in keyring %s' . PHP_EOL, $member, $key, $ring);
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def add_member_to_cryptokey_policy(
        project_id, location, keyring, cryptokey, member, role):
    """Adds a member with a given role to the Identity and Access Management
    (IAM) policy for a given CryptoKey associated with a KeyRing."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # The resource name of the CryptoKey.
    parent = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
        project_id, location, keyring, cryptokey)

    # Get the current IAM policy and add the new member to it.
    cryptokeys = kms_client.projects().locations().keyRings().cryptoKeys()
    policy_request = cryptokeys.getIamPolicy(resource=parent)
    policy_response = policy_request.execute()
    bindings = []
    if 'bindings' in policy_response.keys():
        bindings = policy_response['bindings']
    members = []
    members.append(member)
    new_binding = dict()
    new_binding['role'] = role
    new_binding['members'] = members
    bindings.append(new_binding)
    policy_response['bindings'] = bindings

    # Set the new IAM Policy.
    cryptokeys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = cryptokeys.setIamPolicy(
        resource=parent, body={'policy': policy_response})
    request.execute()

    print_msg = (
        'Member {} added with role {} to policy for CryptoKey {} in KeyRing {}'
        .format(member, role, cryptokey, keyring))
    print(print_msg)

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id  = "Your Google Cloud project ID"
# key_ring_id = "The ID of the key ring"
# crypto_key  = "Name of the crypto key"
# member      = "Member to add to the crypto key policy"
# role        = "Role assignment for new member"
# location    = "The location of the key ring"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the key ring crypto key
resource = "projects/#{project_id}/locations/#{location}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key}"

# Get the current IAM policy
policy = kms_client.get_project_location_key_ring_crypto_key_iam_policy resource

# Add new member to current bindings
policy.bindings ||= []
policy.bindings << Cloudkms::Binding.new(members: [member], role: role)

# Update IAM policy
policy_request = Cloudkms::SetIamPolicyRequest.new policy: policy
kms_client.set_crypto_key_iam_policy resource, policy_request

puts "Member #{member} added to policy for " +
     "crypto key #{crypto_key} in key ring #{key_ring_id}"

To add a policy binding at the KeyRing level:

Command-line

gcloud kms keyrings add-iam-policy-binding KEYRING --location LOCATION --member user:USER_EMAIL --role roles/ROLE_NAME

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object AddMemberToKeyRingPolicy(string projectId, string location,
          string keyRing, string role, string member)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for updating the key ring IAM policy.
          var parent = $"projects/{projectId}/locations/{location}/keyRings/{keyRing}";
          SetIamPolicyRequest setIamPolicyRequest = new SetIamPolicyRequest();
          var result = cloudKms.Projects.Locations.KeyRings.GetIamPolicy(parent).Execute();
          if (result.Bindings != null)
          {
              // Policy already exists, so add a new Binding to it.
              Binding bindingToAdd = new Binding();
              bindingToAdd.Role = role;
              string[] testMembers = { member };
              bindingToAdd.Members = testMembers;
              result.Bindings.Add(bindingToAdd);
              setIamPolicyRequest.Policy = result;
          }
          else
          {
              // Policy does not yet exist, so create a new one
              Policy newPolicy = new Policy();
              newPolicy.Bindings = new List<Binding>();
              Binding bindingToAdd = new Binding();
              bindingToAdd.Role = role;
              string[] testMembers = { member };
              bindingToAdd.Members = testMembers;
              newPolicy.Bindings.Add(bindingToAdd);
              setIamPolicyRequest.Policy = newPolicy;
          }
          var request = new ProjectsResource.LocationsResource.KeyRingsResource
              .SetIamPolicyRequest(cloudKms, setIamPolicyRequest, parent);
          var setIamPolicyResult = request.Execute();
          var updateResult = cloudKms.Projects.Locations.KeyRings.GetIamPolicy(parent).Execute();
          updateResult.Bindings.ToList().ForEach(response =>
          {
              Console.WriteLine($"Role: {response.Role}");
              response.Members.ToList().ForEach(memberFound =>
              {
                  Console.WriteLine($"  Member: {memberFound}");
              });
          });
          return 0;
      }

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Adds the given member to the given keyring, with the given role.
 *
 * @param ringId The id of the keyring.
 * @param member The member to add. Must be in the proper format, eg:
 *
 *        allUsers
 *        user:$userEmail
 *        serviceAccount:$serviceAccountEmail
 *
 *        See https://g.co/cloud/kms/docs/reference/rest/v1/Policy#binding
 *        for more details.
 *
 * @param role Must be in one of the following formats:
 *        roles/[role]
 *        organizations/[organizationId]/roles/[role]
 *        projects/[projectId]/roles/[role]
 *
 *        See https://g.co/cloud/iam/docs/understanding-roles
 *        for available values for [role].
 */
public static Policy addMemberToKeyRingPolicy(
    String projectId, String ringId, String member, String role)
    throws IOException {
  String location = "global";
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the keyring version
  String keyring = String.format(
      "projects/%s/locations/%s/keyRings/%s",
      projectId, location, ringId);

  // Get the current IAM policy
  Policy iamPolicy = getKeyRingPolicy(projectId, ringId);

  // Add the new account to it.
  Binding newBinding = new Binding()
      .setRole(role)
      .setMembers(Collections.singletonList(member));
  List<Binding> bindings = iamPolicy.getBindings();
  if (null == bindings) {
    bindings = Collections.singletonList(newBinding);
  } else {
    bindings.add(newBinding);
  }
  iamPolicy.setBindings(bindings);

  // Set the new IAM Policy.
  Policy newIamPolicy = kms.projects().locations()
      .keyRings()
      .setIamPolicy(keyring, new SetIamPolicyRequest().setPolicy(iamPolicy))
      .execute();

  System.out.println("Response: " + newIamPolicy);
  return newIamPolicy;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the key ring, e.g. "global"
// const location = 'global';

// The name of the key ring, e.g. "my-key-ring"
// const keyRingName = 'my-key-ring';

// The member to add to the key ring, e.g. "user:developer@company.com"
// const member = 'user:developer@company.com';

// The role to give the member, e.g. "roles/viewer"
// const role = 'roles/viewer';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  let request = {
    // This will be a path parameter in the request URL
    resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}`
  };

  // Gets the IAM policy of a key ring
  cloudkms.projects.locations.keyRings.getIamPolicy(request, (err, policy) => {
    if (err) {
      console.log(err);
      return;
    }

    policy = Object.assign({ bindings: [] }, policy);

    const index = policy.bindings.findIndex((binding) => binding.role === role);

    // Add the role/member combo to the policy
    const binding = Object.assign({
      role: role,
      members: []
    }, policy.bindings[index]);
    if (index === -1) {
      policy.bindings.push(binding);
    }
    if (!binding.members.includes(member)) {
      binding.members.push(member);
    }

    request = {
      // This will be a path parameter in the request URL
      resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}`,
      // This will be the request body
      resource: {
        policy: policy
      }
    };

    // Adds the member/role combo to the policy of the key ring
    cloudkms.projects.locations.keyRings.setIamPolicy(request, (err, policy) => {
      if (err) {
        console.log(err);
        return;
      }

      console.log(`${member}/${role} combo added to policy for key ring ${keyRingName}.`);
      if (policy.bindings) {
        policy.bindings.forEach((binding) => {
          if (binding.members && binding.members.length) {
            console.log(`${binding.role}:`);
            binding.members.forEach((member) => {
              console.log(`  ${member}`);
            });
          }
        });
      } else {
        console.log(`Policy for key ring ${keyRingName} is empty.`);
      }
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Add a member to a KeyRing IAM policy.
 *
 * @param string $projectId
 * @param string $ring
 * @param string $member Must be in the format "user:$userEmail" or
 *        "serviceAccount:$serviceAccountEmail"
 * @param string $role Must be in the format "roles/$role",
 *        "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"
 * @param string $location [optional]
 * @return null
 */
function add_member_to_keyring_policy($projectId, $ring, $member, $role, $location = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the KeyRing.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s',
        $projectId,
        $location,
        $ring
    );

    // Get the current IAM policy and add the new account to it.
    $policy = $kms->projects_locations_keyRings->getIamPolicy($parent);
    $bindings = $policy->getBindings();
    $bindings[] = new Google_Service_CloudKMS_Binding([
        'members' => [$member],
        'role' => $role,
    ]);
    $policy->setBindings($bindings);

    // Set the new IAM Policy.
    $request = new Google_Service_CloudKMS_SetIamPolicyRequest(['policy' => $policy]);
    $kms->projects_locations_keyRings->setIamPolicy(
        $parent,
        $request
    );

    printf('Member %s added to policy for keyring %s' . PHP_EOL, $member, $ring);
}

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id  = "Your Google Cloud project ID"
# key_ring_id = "The ID of the key ring"
# member      = "Member to add to the key ring policy"
# role        = "Role assignment for new member"
# location    = "The location of the key ring"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the key ring
resource = "projects/#{project_id}/locations/#{location}/" +
           "keyRings/#{key_ring_id}"

# Get the current IAM policy
policy = kms_client.get_project_location_key_ring_iam_policy resource

# Add new member to current bindings
policy.bindings ||= []
policy.bindings << Cloudkms::Binding.new(members: [member], role: role)

# Update IAM policy
policy_request = Cloudkms::SetIamPolicyRequest.new policy: policy
kms_client.set_key_ring_iam_policy resource, policy_request

puts "Member #{member} added to policy for " +
     "key ring #{key_ring_id}"

Since CryptoKeys belong to KeyRings, and KeyRings belong to Projects, a user with a specific role or permission at a higher level in that hierarchy inherits the same permissions on the child resources. That is, a user who has the role of owner on a Project is also an owner on all the KeyRings and CryptoKeys in that project. Similarly, if a user is granted the cloudkms.admin role on a KeyRing, they have the associated permissions on the CryptoKeys in that KeyRing.

The inverse is not true - that is, a user with a permission on a CryptoKey who is not also granted a permission on the parent KeyRing has no permissions on that KeyRing.

If necessary, a member and role can be removed from a KeyRing or CryptoKey policy:

Command-line

gcloud kms keys remove-iam-policy-binding CRYPTOKEY --location LOCATION --keyring KEYRING --member user:USER_EMAIL --role roles/ROLE_NAME

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object RemoveMemberFromCryptoKeyPolicy(string projectId, string location,
          string keyRing, string cryptoKey, string role, string member)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for updating the crypto key IAM policy.
          var parent = $"projects/{projectId}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}";
          var result = cloudKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(parent).Execute();
          if (result.Bindings != null)
          {
              result.Bindings.ToList().ForEach(response =>
              {
                  if (response.Role == role)
                  {
                      // Remove the role/member combo from the crypto key IAM policy.
                      response.Members = response.Members.Where(m => m != member).ToList();
                  }
              });
              // Set the modified crypto key IAM policy to be the cryto key's current IAM policy.
              SetIamPolicyRequest setIamPolicyRequest = new SetIamPolicyRequest();
              setIamPolicyRequest.Policy = result;
              var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
                  .SetIamPolicyRequest(cloudKms, setIamPolicyRequest, parent);
              var setIamPolicyResult = request.Execute();
              // Get and display the modified crypto key IAM policy.
              var resultAfterUpdate = cloudKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(parent).Execute();
              if (resultAfterUpdate.Bindings != null)
              {
                  Console.WriteLine($"Policy Bindings: {resultAfterUpdate.Bindings}");
                  resultAfterUpdate.Bindings.ToList().ForEach(response =>
                  {
                      Console.WriteLine($"Role: {response.Role}");
                      response.Members.ToList().ForEach(memberAfterUpdate =>
                      {
                          Console.WriteLine($"  Member: {memberAfterUpdate}");
                      });
                  });
              }
              else
              {
                  Console.WriteLine($"Empty IAM policy found for CryptoKey: {parent}");
              }
          }
          else
          {
              Console.WriteLine($"Empty IAM policy found for CryptoKey: {parent}");
          }
          return 0;
      }

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Removes the given member from the given policy.
 */
public static Policy removeMemberFromCryptoKeyPolicy(
    String projectId, String ringId, String keyId, String member, String role)
    throws IOException {
  String location = "global";
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey
  String cryptoKey = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
      projectId, location, ringId, keyId);

  // Get the current IAM policy and add the new account to it.
  Policy iamPolicy = getCryptoKeyPolicy(projectId, ringId, keyId);

  if (null == iamPolicy.getBindings()) {
    // Nothing to remove
    return null;
  }

  // Filter out the given member
  for (Binding b : iamPolicy.getBindings()) {
    if (role.equals(b.getRole()) && b.getMembers().contains(member)) {
      b.getMembers().removeAll(Collections.singletonList(member));
      break;
    }
  }

  // Set the new IAM Policy.
  Policy newIamPolicy = kms.projects().locations().keyRings()
      .cryptoKeys()
      .setIamPolicy(cryptoKey, new SetIamPolicyRequest().setPolicy(iamPolicy))
      .execute();

  System.out.println("Response: " + newIamPolicy);
  return newIamPolicy;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key's key ring, e.g. "global"
// const location = 'global';

// The name of the crypto key's key ring, e.g. "my-key-ring"
// const keyRingName = 'my-key-ring';

// The name of the crypto key, e.g. "my-key"
// const keyName = 'my-key';

// The member to add to the crypto key, e.g. "user:developer@company.com"
// const member = 'user:developer@company.com';

// The role to give the member, e.g. "roles/viewer"
// const role = 'roles/viewer';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  let request = {
    // This will be a path parameter in the request URL
    resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}/cryptoKeys/${keyName}`
  };

  // Gets the IAM policy of a crypto key
  cloudkms.projects.locations.keyRings.cryptoKeys.getIamPolicy(request, (err, policy) => {
    if (err) {
      console.log(err);
      return;
    }

    policy = Object.assign({ bindings: [] }, policy);

    let index = policy.bindings.findIndex((binding) => binding.role === role);

    const binding = Object.assign({
      role: role,
      members: []
    }, policy.bindings[index]);
    if (index === -1) {
      return;
    }
    if (!binding.members.includes(member)) {
      return;
    }

    // Remove the role/member combo from the policy
    binding.members.splice(binding.members.indexOf(member), 1);

    request = {
      // This will be a path parameter in the request URL
      resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}/cryptoKeys/${keyName}`,
      // This will be the request body
      resource: {
        policy: policy
      }
    };

    console.log(JSON.stringify(request, null, 2));

    // Removes the member/role combo from the policy of the crypto key
    cloudkms.projects.locations.keyRings.cryptoKeys.setIamPolicy(request, (err, policy) => {
      if (err) {
        console.log(err);
        return;
      }

      console.log(`${member}/${role} combo removed from policy for crypto key ${keyName}.`);
      if (policy.bindings) {
        policy.bindings.forEach((binding) => {
          if (binding.members && binding.members.length) {
            console.log(`${binding.role}:`);
            binding.members.forEach((member) => {
              console.log(`  ${member}`);
            });
          }
        });
      } else {
        console.log(`Policy for crypto key ${keyName} is empty.`);
      }
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Remove a member from a CryptoKey IAM policy.
 *
 * @param string $projectId
 * @param string $ring
 * @param string $key
 * @param string $member Must be in the format "user:$userEmail" or
 *        "serviceAccount:$serviceAccountEmail"
 * @param string $role Must be in the format "roles/$role",
 *        "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"
 * @param string $location [optional]
 * @return null
 */
function remove_member_from_cryptokey_policy($projectId, $ring, $key, $member, $role, $location = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the KeyRing associated with the CryptoKey.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s',
        $projectId,
        $location,
        $ring,
        $key
    );

    // Get the current IAM policy and remove the member from it.
    $policy = $kms->projects_locations_keyRings_cryptoKeys->getIamPolicy($parent);
    foreach ($policy->getBindings() as $binding) {
        if ($binding->getRole() == $role) {
            $members = $binding->getMembers();
            if (false !== $i = array_search($member, $members)) {
                unset($members[$i]);
                $binding->setMembers($members);
                break;
            }
        }
    }

    // Set the new IAM Policy.
    $request = new Google_Service_CloudKMS_SetIamPolicyRequest(['policy' => $policy]);
    $kms->projects_locations_keyRings_cryptoKeys->setIamPolicy(
        $parent,
        $request
    );

    printf('Member %s removed from policy for key %s in keyring %s' . PHP_EOL,
        $member,
        $key,
        $ring);
}

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id  = "Your Google Cloud project ID"
# key_ring_id = "The ID of the key ring"
# crypto_key  = "Name of the crypto key"
# member      = "Member to remove to the crypto key policy"
# role        = "Role assignment for the member"
# location    = "The location of the key ring"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the key ring crypto key
resource = "projects/#{project_id}/locations/#{location}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key}"

# Get the current IAM policy
policy = kms_client.get_project_location_key_ring_crypto_key_iam_policy resource

# Remove a member to current bindings
if policy.bindings
  policy.bindings.delete_if do |binding|
    binding.role.include?(role) && binding.members.include?(member)
  end
end

# Update IAM policy
policy_request = Cloudkms::SetIamPolicyRequest.new policy: policy
kms_client.set_crypto_key_iam_policy resource, policy_request

puts "Member #{member} removed from policy for " +
     "crypto key #{crypto_key} in key ring #{key_ring_id}"

Granting permissions to use keys

To allow a user or service account to use a key to encrypt or decrypt using a particular CryptoKey, they must have the cloudkms.cryptoKeyEncrypterDecrypter, cloudkms.cryptoKeyEncrypter, cloudkms.cryptoKeyDecrypter, or owner role, as per the chart in Permissions and Roles.

With Cloud KMS, you'll likely mostly be using service accounts to perform key operations such as encrypt and decrypt. Usually, the service account's email is derived from the service account name, in the format:

SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com

Command-line

For example, if you are accessing Cloud KMS from a Google Compute Engine instance and created a service account my-service-account@my-project.iam.gserviceaccount.com, you can use the gcloud command-line tool to grant that service account permission to use the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding \
    golden-egg --location global --keyring golden-goose \
    --member serviceAccount:my-service-account@my-project.iam.gserviceaccount.com \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Windows cmd.exe

For example, if you are accessing Cloud KMS from a Google Compute Engine instance and created a service account my-service-account@my-project.iam.gserviceaccount.com, you can use the gcloud command-line tool to grant that service account permission to use the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding ^
    golden-egg --location global --keyring golden-goose ^
    --member serviceAccount:my-service-account@my-project.iam.gserviceaccount.com ^
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Powershell

For example, if you are accessing Cloud KMS from a Google Compute Engine instance and created a service account my-service-account@my-project.iam.gserviceaccount.com, you can use the gcloud command-line tool to grant that service account permission to use the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding `
    golden-egg --location global --keyring golden-goose `
    --member serviceAccount:my-service-account@my-project.iam.gserviceaccount.com `
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Users can be granted permissions to use a CryptoKey. In this case, the member is user:USER_EMAIL instead of serviceAccount:SERVICE_ACCOUNT_EMAIL:

Command-line

gcloud kms keys add-iam-policy-binding \
    golden-egg --location global --keyring golden-goose \
    --member user:sillygoose@gmail.com \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Windows cmd.exe

gcloud kms keys add-iam-policy-binding ^
    golden-egg --location global --keyring golden-goose ^
    --member user:sillygoose@gmail.com ^
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Powershell

gcloud kms keys add-iam-policy-binding `
    golden-egg --location global --keyring golden-goose `
    --member user:sillygoose@gmail.com `
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Granting permissions to manage keys

To allow a user or service account to create or update existing CryptoKeys, they need at least the editor role, as per the chart above. The cloudkms.admin role also allows them to destroy CryptoKeys and set IAM policies. The owner role can do all this, and further encrypt or decrypt using a CryptoKey.

Command-line

The following example gives a user sillygoose@gmail.com the cloudkms.admin role for the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding \
    golden-egg --location global --keyring golden-goose \
    --member user:sillygoose@gmail.com \
    --role roles/cloudkms.admin

Windows cmd.exe

The following example gives a user sillygoose@gmail.com the cloudkms.admin role for the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding ^
    golden-egg --location global --keyring golden-goose ^
    --member user:sillygoose@gmail.com ^
    --role roles/cloudkms.admin

Powershell

The following example gives a user sillygoose@gmail.com the cloudkms.admin role for the CryptoKey golden-egg in the KeyRing golden-goose:
gcloud kms keys add-iam-policy-binding `
    golden-egg --location global --keyring golden-goose `
    --member user:sillygoose@gmail.com `
    --role roles/cloudkms.admin

Getting existing permissions

A user with viewer,editor, cloudkms.admin or owner roles can view IAM policy on a CryptoKey.

Command-line

For example, to get the IAM policy for CryptoKey bird in KeyRing hand:
gcloud kms keys get-iam-policy bird --location global --keyring hand

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object GetKeyRingIamPolicy(string projectId, string location, string keyRing)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for getting the key ring IAM policy.
          var parent = $"projects/{projectId}/locations/{location}/keyRings/{keyRing}";
          var result = cloudKms.Projects.Locations.KeyRings.GetIamPolicy(parent).Execute();
          if (result.Bindings != null)
          {
              Console.WriteLine($"Policy Bindings: {result.Bindings}");
              result.Bindings.ToList().ForEach(response =>
              {
                  Console.WriteLine($"Role: {response.Role}");

                  response.Members.ToList().ForEach(member =>
                  {
                      Console.WriteLine($"  Member: {member}");
                  });
              });
          }
          else
          {
              Console.WriteLine($"Empty IAM policy found for KeyRing: {parent}");
          }
          return 0;
      }

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Retrieves the IAM policy for the given crypto key.
 */
public static Policy getKeyRingPolicy(String projectId, String ringId) throws IOException {
  String location = "global";
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the keyring
  String keyring = String.format(
      "projects/%s/locations/%s/keyRings/%s",
      projectId, location, ringId);

  // Get the current IAM policy and add the new account to it.
  Policy iamPolicy = kms.projects().locations().keyRings()
      .getIamPolicy(keyring)
      .execute();

  System.out.println(iamPolicy.getBindings());
  return iamPolicy;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the key ring, e.g. "global"
// const location = 'global';

// The name of the key ring, e.g. "my-key-ring"
// const keyRingName = 'my-key-ring';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  const request = {
    // This will be a path parameter in the request URL
    resource_: `projects/${projectId}/locations/${location}/keyRings/${keyRingName}`
  };

  // Gets the IAM policy of a key ring
  cloudkms.projects.locations.keyRings.getIamPolicy(request, (err, policy) => {
    if (err) {
      console.log(err);
      return;
    }

    if (policy.bindings) {
      policy.bindings.forEach((binding) => {
        if (binding.members && binding.members.length) {
          console.log(`${binding.role}:`);
          binding.members.forEach((member) => {
            console.log(`  ${member}`);
          });
        }
      });
    } else {
      console.log(`Policy for key ring ${keyRingName} is empty.`);
    }
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Get the IAM policy for a KeyRing.
 *
 * @param string $projectId
 * @param string $ring
 * @param string $location [optional]
 * @return null
 */
function get_keyring_policy($projectId, $ring, $location = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the location associated with the key rings.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s',
        $projectId,
        $location,
        $ring
    );

    // Get the current IAM policy and print it.
    $policy = $kms->projects_locations_keyRings->getIamPolicy($parent);
    foreach ($policy->getBindings() as $binding) {
        printf("Role: %s\nMembers:\n%s\n",
            $binding->getRole(),
            implode("\n", $binding->getMembers())
        );
    }
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def get_keyring_policy(project_id, location, keyring):
    """Gets the Identity and Access Management (IAM) policy for a given KeyRing
    and prints out roles and the members assigned to those roles."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # The resource name of the KeyRing.
    parent = 'projects/{}/locations/{}/keyRings/{}'.format(
        project_id, location, keyring)

    # Get the current IAM policy.
    request = kms_client.projects().locations().keyRings().getIamPolicy(
        resource=parent)
    response = request.execute()

    if 'bindings' in response.keys():
        print('Printing IAM policy for resource {}:'.format(parent))
        for binding in response['bindings']:
            print('')
            print('Role: {}'.format(binding['role']))
            print('Members:')
            for member in binding['members']:
                print(member)
        print('')
    else:
        print('No roles found for resource {}.'.format(parent))

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id  = "Your Google Cloud project ID"
# key_ring_id = "The ID of the key ring"
# location    = "The location of the key ring"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the key ring
resource = "projects/#{project_id}/locations/#{location}/" +
           "keyRings/#{key_ring_id}"

# Get the current IAM policy
policy = kms_client.get_project_location_key_ring_iam_policy resource

# Print role and associated members
if policy.bindings
  policy.bindings.each do |binding|
    puts "Role: #{binding.role} Members: #{binding.members}"
  end
else
  puts "No members"
end

Send feedback about...

Cloud KMS Documentation