Using IAM with Cloud KMS

Key rings and keys 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 key versions. Cloud 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 the gcloud command-line tool 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 key rings and keys. 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 key for a given role:

Command-line

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

C#

      public static void AddMemberToCryptoKeyPolicy(string projectId, string locationId,
          string keyRingId, string cryptoKeyId, string role, string member)
      {
          KeyManagementServiceClient client = KeyManagementServiceClient.Create();
          CryptoKeyName cryptoKeyName =
              new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);

          Policy policy = client.GetIamPolicy(KeyNameOneof.From(cryptoKeyName));
          policy.Bindings.Add(new Binding
          {
              Role = role,
              Members = { member }
          });

          Policy updateResult = client.SetIamPolicy(KeyNameOneof.From(cryptoKeyName), policy);

          foreach (Binding bindingResult in updateResult.Bindings)
          {
              Console.WriteLine($"Role: {bindingResult.Role}");
              foreach (string memberResult in bindingResult.Members)
              {
                  Console.WriteLine($"  Member: {memberResult}");
              }
          }
      }

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/iam"
	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// addMemberCryptoKeyPolicy adds a new member to a specified IAM role for the key.
func addMemberCryptoKeyPolicy(w io.Writer, keyName, member string, role iam.RoleName) error {
	// keyName := "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID"
	// member := "user@gmail.com"
	// role := iam.Viewer
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}

	// Get the desired CryptoKey.
	keyObj, err := client.GetCryptoKey(ctx, &kmspb.GetCryptoKeyRequest{Name: keyName})
	if err != nil {
		return fmt.Errorf("GetCryptoKey: %v", err)
	}
	// Get IAM Policy.
	handle := client.CryptoKeyIAM(keyObj)
	policy, err := handle.Policy(ctx)
	if err != nil {
		return fmt.Errorf("Policy: %v", err)
	}
	// Add Member.
	policy.Add(member, role)
	if err = handle.SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("SetPolicy: %v", err)
	}
	fmt.Fprintf(w, "Added member %s to cryptokey policy.", member)
	return nil
}

Java


/**
 * Adds the given member to the given key, with the given role.
 *
 * @param projectId The id of the project.
 * @param locationId The location id of the key.
 * @param keyRingId The id of the keyring.
 * @param cryptoKeyId 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 locationId, String keyRingId, String cryptoKeyId, String member,
    String role)
    throws IOException {

  // Create the Cloud KMS client.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey version
    String keyName = CryptoKeyName.format(projectId, locationId, keyRingId, cryptoKeyId);

    // Get the current IAM policy
    Policy iamPolicy = client.getIamPolicy(keyName);

    // Create a new binding with the selected role and member
    Binding newBinding = Binding.newBuilder()
        .setRole(role)
        .addMembers(member)
        .build();

    // Create a new IAM policy containing the existing settings plus the new binding.
    Policy newPolicy = Policy.newBuilder()
        .mergeFrom(iamPolicy)
        .addBindings(newBinding)
        .build();

    // Set the new IAM Policy.
    Policy policyResult = client.setIamPolicy(keyName, newPolicy);

    return policyResult;
  }
}

Node.js

async function addMemberToCryptoKeyPolicy(
  projectId = 'your-project-id', // Your GCP Project Id
  keyRingId = 'my-key-ring', // Name of the crypto key's key ring
  cryptoKeyId = 'my-key', // Name of the crypto key
  member = 'user:dev@example.com', // Member to add to the crypto key
  role = 'roles/viewer' // Role to give the member
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

  // The location of the crypto key's key ring
  const locationId = 'global';

  // Get the full path to the crypto key
  const resource = client.cryptoKeyPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId
  );

  // Gets the IAM policy of a crypto key
  const [result] = await client.getIamPolicy({resource});
  let policy = Object.assign({bindings: []}, result);
  const index = policy.bindings.findIndex(binding => binding.role === role);

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

  // Adds the member/role combo to the policy of the crypto key
  [policy] = await client.setIamPolicy({resource, policy});
  console.log(
    `${member}/${role} combo added to policy for crypto key ${cryptoKeyId}.`
  );
  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 ${cryptoKeyId} is empty.`);
  }
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;
use Google\Cloud\Iam\V1\Binding;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';
// $cryptoKeyId = 'The KMS key ID';
// $member = 'Must be in the format "user:$userEmail" or "serviceAccount:$serviceAccountEmail"';
// $role = 'Must be in the format "roles/$role", "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"';

$kms = new KeyManagementServiceClient();

// The resource name of the CryptoKey.
$cryptoKeyName = $kms->cryptoKeyName($projectId, $locationId, $keyRingId, $cryptoKeyId);

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

// Set the new IAM Policy.
$kms->setIamPolicy($cryptoKeyName, $policy);

printf('Member %s added to policy for cryptoKey %s in keyRing %s' . PHP_EOL, $member, $cryptoKeyId, $keyRingId);

Python

def add_member_to_crypto_key_policy(
        project_id, location_id, key_ring_id, crypto_key_id, 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."""

    from google.cloud import kms_v1

    # Creates an API client for the KMS API.
    client = kms_v1.KeyManagementServiceClient()

    # The resource name of the CryptoKey.
    resource = client.crypto_key_path_path(project_id, location_id,
                                           key_ring_id, crypto_key_id)
    # Get the current IAM policy.
    policy = client.get_iam_policy(resource)

    # Add member
    policy.bindings.add(
        role=role,
        members=[member])

    # Update the IAM Policy.
    client.set_iam_policy(resource, policy)

    # Print results
    print('Member {} added with role {} to policy for CryptoKey {} \
           in KeyRing {}'.format(member, role, crypto_key_id, key_ring_id))

Ruby

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

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The CryptoKey to use
crypto_key = CloudKMS::KeyManagementServiceClient.crypto_key_path(
  project_id, location_id, key_ring_id, crypto_key_id
)

# Get the current IAM policy
policy = client.get_iam_policy crypto_key

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

# Update IAM policy
client.set_iam_policy crypto_key, policy

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

To add a policy binding at the key ring level:

Command-line

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

C#

      public static void AddMemberToKeyRingPolicy(string projectId, string locationId,
          string keyRingId, string role, string member)
      {
          KeyManagementServiceClient client = KeyManagementServiceClient.Create();
          KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);

          Policy policy = client.GetIamPolicy(KeyNameOneof.From(keyRingName));
          policy.Bindings.Add(new Binding
          {
              Role = role,
              Members = { member }
          });

          Policy updateResult = client.SetIamPolicy(KeyNameOneof.From(keyRingName), policy);

          foreach (Binding bindingResult in updateResult.Bindings)
          {
              Console.WriteLine($"Role: {bindingResult.Role}");
              foreach (string memberResult in bindingResult.Members)
              {
                  Console.WriteLine($"  Member: {memberResult}");
              }
          }
      }

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/iam"
	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// addMemberRingPolicy adds a new member to a specified IAM role for the key ring.
func addMemberRingPolicy(w io.Writer, keyRingName, member string, role iam.RoleName) error {
	// keyRingName := "projects/PROJECT_ID/locations/global/keyRings/RING_ID"
	// member := "user@gmail.com"
	// role := iam.Viewer
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}

	// Get the KeyRing.
	keyRingObj, err := client.GetKeyRing(ctx, &kmspb.GetKeyRingRequest{Name: keyRingName})
	if err != nil {
		return fmt.Errorf("GetKeyRing: %v", err)
	}
	// Get IAM Policy.
	handle := client.KeyRingIAM(keyRingObj)
	policy, err := handle.Policy(ctx)
	if err != nil {
		return fmt.Errorf("Policy: %v", err)
	}
	// Add Member.
	policy.Add(member, role)
	if err = handle.SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("SetPolicy: %v", err)
	}
	fmt.Fprintf(w, "Added member %s to keyring policy.", member)
	return nil
}

Java


/**
 * Adds the given member to the given keyring, with the given role.
 *
 * @param projectId The id of the project.
 * @param locationId The location id of the key.
 * @param keyRingId 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 locationId, String keyRingId, String member, String role)
    throws IOException {

  // Create the Cloud KMS client.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey version
    String keyRingName = KeyRingName.format(projectId, locationId, keyRingId);

    // Get the current IAM policy
    Policy iamPolicy = client.getIamPolicy(keyRingName);

    // Create a new binding with the selected role and member
    Binding newBinding = Binding.newBuilder()
        .setRole(role)
        .addMembers(member)
        .build();

    // Create a new IAM policy containing the existing settings plus the new binding.
    Policy newPolicy = Policy.newBuilder()
        .mergeFrom(iamPolicy)
        .addBindings(newBinding)
        .build();

    // Set the new IAM Policy.
    Policy policyResult = client.setIamPolicy(keyRingName, newPolicy);

    return policyResult;
  }
}

Node.js

async function addMemberToKeyRingPolicy(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key's key ring
  member = 'user:dev@example.com', // Member to add to the crypto key
  role = 'roles/viewer' // Role to give the member
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

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

  // Get the full path to the keyring
  const resource = client.keyRingPath(projectId, locationId, keyRingId);

  // Gets the IAM policy of a key ring
  let [policy] = await client.getIamPolicy({resource});
  policy.bindings = policy.bindings || [];

  // find the index of the binding matching the requested role
  const index = policy.bindings.findIndex(binding => binding.role === role);

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

  // Adds the member/role combo to the policy of the key ring
  [policy] = await client.setIamPolicy({resource, policy});
  console.log(
    `${member}/${role} combo added to policy for key ring ${keyRingId}.`
  );
  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 ${keyRingId} is empty.`);
  }
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;
use Google\Cloud\Iam\V1\Binding;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';
// $member = 'Must be in the format "user:$userEmail" or "serviceAccount:$serviceAccountEmail"';
// $role = 'Must be in the format "roles/$role", "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"';

$kms = new KeyManagementServiceClient();

// The resource name of the CryptoKey.
$keyRingName = $kms->keyRingName($projectId, $locationId, $keyRingId);

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

// Set the new IAM Policy.
$kms->setIamPolicy($keyRingName, $policy);

printf('Member %s added to policy for keyRing %s' . PHP_EOL, $member, $keyRingId);

Ruby

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

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The key ring to use
key_ring =
  CloudKMS::KeyManagementServiceClient.key_ring_path project_id, location_id, key_ring_id

# Get the current IAM policy
policy = client.get_iam_policy key_ring

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

# Update IAM policy
client.set_iam_policy key_ring, policy

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

Since keys belong to key rings, and key rings 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 key rings and keys in that project. Similarly, if a user is granted the cloudkms.admin role on a key ring, they have the associated permissions on the keys in that key ring.

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

If necessary, a member and role can be removed from a key ring or key policy:

Command-line

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

C#

      public static void RemoveMemberFromCryptoKeyPolicy(string projectId, string locationId,
          string keyRingId, string cryptoKeyId, string role, string member)
      {
          KeyManagementServiceClient client = KeyManagementServiceClient.Create();
          CryptoKeyName cryptoKeyName =
              new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);

          Policy policy = client.GetIamPolicy(KeyNameOneof.From(cryptoKeyName));

          foreach (Binding binding in policy.Bindings.Where(b => b.Role == role))
          {
              binding.Members.Remove(member);
          }

          Policy updateResult = client.SetIamPolicy(KeyNameOneof.From(cryptoKeyName), policy);

          foreach (Binding bindingResult in updateResult.Bindings)
          {
              Console.WriteLine($"Role: {bindingResult.Role}");
              foreach (string memberResult in bindingResult.Members)
              {
                  Console.WriteLine($"  Member: {memberResult}");
              }
          }
      }

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/iam"
	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// removeMemberCryptoKeyPolicy removes a specified member from an IAM role for the key.
func removeMemberCryptoKeyPolicy(w io.Writer, name, member string, role iam.RoleName) error {
	// name: "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID"
	// member := "user@gmail.com"
	// role := iam.Viewer
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}
	// Get the desired CryptoKey.
	keyObj, err := client.GetCryptoKey(ctx, &kmspb.GetCryptoKeyRequest{Name: name})
	if err != nil {
		return fmt.Errorf("GetCryptoKey: %v", err)
	}
	// Get IAM Policy.
	handle := client.CryptoKeyIAM(keyObj)
	policy, err := handle.Policy(ctx)
	if err != nil {
		return fmt.Errorf("Policy: %v", err)
	}
	// Remove Member.
	policy.Remove(member, role)
	if err = handle.SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("SetPolicy: %v", err)
	}
	fmt.Fprintf(w, "Removed member %s from cryptokey policy.", member)
	return nil
}

Java


/**
 * Removes the given member from the given policy.
 */
public static Policy removeMemberFromCryptoKeyPolicy(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, String member,
    String role)
    throws IOException {

  // Create the Cloud KMS client.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey version
    String keyName = CryptoKeyName.format(projectId, locationId, keyRingId, cryptoKeyId);

    // Get the current IAM policy
    Policy iamPolicy = client.getIamPolicy(keyName);

    // Create a bindings list that filters out the provided member
    List<Binding> newBindings = new ArrayList<>();
    for (Binding binding : iamPolicy.getBindingsList()) {
      if (!binding.getRole().equals(role)) {
        newBindings.add(binding);
        continue;
      }

      Binding.Builder builder = Binding.newBuilder().setRole(binding.getRole());
      for (String bindingMember : binding.getMembersList()) {
        if (!member.equals(bindingMember)) {
          builder.addMembers(bindingMember);
        }
      }
      newBindings.add(builder.build());
    }

    Policy newIamPolicy = Policy.newBuilder()
        .addAllBindings(newBindings)
        .build();

    // Set the new IAM Policy.
    Policy result = client.setIamPolicy(keyName, newIamPolicy);

    return result;
  }
}

Node.js

async function removeMemberFromCryptoKeyPolicy(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key's key ring
  cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key"
  member = 'user:dev@example.com', // Member to add to the crypto key
  role = 'roles/viewer' // Role to give the member
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

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

  // Get the full path to the crypto key
  const resource = client.cryptoKeyPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId
  );

  // Gets the IAM policy of a crypto key
  const [result] = await client.getIamPolicy({resource});
  let policy = Object.assign({bindings: []}, result);
  const index = policy.bindings.findIndex(binding => binding.role === role);
  const members = [];
  const binding = Object.assign({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);

  const request = {resource, policy};
  console.log(JSON.stringify(request, null, 2));

  // Removes the member/role combo from the policy of the crypto key
  [policy] = await client.setIamPolicy(request);
  console.log(
    `${member}/${role} combo removed from policy for crypto key ${cryptoKeyId}.`
  );
  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 ${cryptoKeyId} is empty.`);
  }
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';
// $cryptoKeyId = 'The KMS key ID';
// $member = 'Must be in the format "user:$userEmail" or "serviceAccount:$serviceAccountEmail"';
// $role = 'Must be in the format "roles/$role", "organizations/$organizationId/roles/$role", or "projects/$projectId/roles/$role"';

$kms = new KeyManagementServiceClient();

// The resource name of the CryptoKey.
$cryptoKeyName = $kms->keyRingName($projectId, $locationId, $keyRingId, $cryptoKeyId);

// Get the current IAM policy and remove the account to it.
$policy = $kms->getIamPolicy($cryptoKeyName);
foreach ($policy->getBindings() as $binding) {
    if ($binding->getRole() == $role) {
        $members = $binding->getMembers();
        foreach ($members as $i => $existingMember) {
            if ($member == $existingMember) {
                unset($members[$i]);
                $binding->setMembers($members);
                break;
            }
        }
    }
}

// Set the new IAM Policy.
$kms->setIamPolicy($cryptoKeyName, $policy);

printf('Member %s removed from policy for cryptoKey %s in keyRing %s' . PHP_EOL,
    $member,
    $cryptoKeyId,
    $keyRingId);

Ruby

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

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The CryptoKey to use
crypto_key = CloudKMS::KeyManagementServiceClient.crypto_key_path(
  project_id, location_id, key_ring_id, crypto_key_id
)

# Get the current IAM policy
policy = client.get_iam_policy crypto_key

# Remove a member from current bindings
policy.bindings.each do |binding|
  if binding.role == role
    binding.members.delete member
  end
end

# Update IAM policy
client.set_iam_policy crypto_key, policy

puts "Member #{member} removed from policy for " +
     "crypto key #{crypto_key_id} 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 key, 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 Cloud Platform 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 key golden-egg in the key ring golden-goose from the global location:

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 Cloud Platform 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 key golden-egg in the key ring golden-goose from the global location:

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 Cloud Platform 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 key golden-egg in the key ring golden-goose from the global location:
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 key. 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 keys, they need at least the editor role, as per the chart above. The cloudkms.admin role also allows them to destroy keys and set IAM policies. The owner role can do all this, and further encrypt or decrypt using a key.

Command-line

The following example gives a user sillygoose@gmail.com the cloudkms.admin role for the key golden-egg in the key ring 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 key golden-egg in the key ring 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 key golden-egg in the key ring 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 key.

Command-line

For example, to get the IAM policy for key bird in key ring hand:

gcloud kms keys get-iam-policy bird --location global \
  --keyring hand

C#

      public static void GetKeyRingIamPolicy(string projectId, string locationId, string keyRingId)
      {
          KeyManagementServiceClient client = KeyManagementServiceClient.Create();
          KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);

          Policy result = client.GetIamPolicy(KeyNameOneof.From(keyRingName));

          foreach (Binding binding in result.Bindings)
          {
              Console.WriteLine($"Role: {binding.Role}");
              foreach (String member in binding.Members)
              {
                  Console.WriteLine($"  Member: {member}");
              }
          }
      }

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/iam"
	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// getRingPolicy retrieves and prints the IAM policy associated with the key ring.
func getRingPolicy(w io.Writer, name string) (*iam.Policy, error) {
	// name: "projects/PROJECT_ID/locations/global/keyRings/RING_ID"
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}
	// Get the KeyRing.
	keyRingObj, err := client.GetKeyRing(ctx, &kmspb.GetKeyRingRequest{Name: name})
	if err != nil {
		return nil, fmt.Errorf("GetKeyRing: %v", err)
	}
	// Get IAM Policy.
	handle := client.KeyRingIAM(keyRingObj)
	policy, err := handle.Policy(ctx)
	if err != nil {
		return nil, fmt.Errorf("Policy: %v", err)
	}
	for _, role := range policy.Roles() {
		for _, member := range policy.Members(role) {
			fmt.Fprintf(w, "Role: %s Member: %s\n", role, member)
		}
	}
	return policy, nil
}

Java


/**
 * Retrieves the IAM policy for the given crypto key.
 */
public static Policy getKeyRingPolicy(String projectId, String locationId, String keyRingId)
    throws IOException {
  // Create the Cloud KMS client.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey version
    String keyRingName = KeyRingName.format(projectId, locationId, keyRingId);

    // Get the current IAM policy and add the new account to it.
    Policy iamPolicy = client.getIamPolicy(keyRingName);

    return iamPolicy;
  }
}

Node.js

async function getKeyRingIamPolicy(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring' // Name of the crypto key's key ring
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

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

  // Get the full path to the keyring
  const resource = client.keyRingPath(projectId, locationId, keyRingId);

  // Gets the IAM policy of a key ring
  const [policy] = await client.getIamPolicy({resource});
  if (policy.bindings && policy.bindings.length > 0) {
    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 ${keyRingId} is empty.`);
  }
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';

$kms = new KeyManagementServiceClient();

// The resource name of the Key Ring.
$keyRingName = $kms->keyRingName($projectId, $locationId, $keyRingId);

// Get the Key Ring Policy and print it.
$keyRingPolicy = $kms->getIamPolicy($keyRingName);

foreach ($keyRingPolicy->getBindings() as $binding) {
    printf("Role: %s\nMembers:\n", $binding->getRole());

    foreach ($binding->getMembers() as $member) {
        printf("  %s\n", $member);
    }
    print("\n");
}

Python

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

    from google.cloud import kms_v1

    # Creates an API client for the KMS API.
    client = kms_v1.KeyManagementServiceClient()

    # The resource name of the KeyRing.
    resource = client.key_ring_path(project_id, location_id, key_ring_id)

    # Get the current IAM policy.
    policy = client.get_iam_policy(resource)

    # Print results
    print('Printing IAM policy for resource {}:'.format(resource))
    for b in policy.bindings:
        for m in b.members:
            print('Role: {} Member: {}'.format(b.role, m))
    return policy

Ruby

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

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The key ring to use
key_ring =
  CloudKMS::KeyManagementServiceClient.key_ring_path project_id, location_id, key_ring_id

# Get the current IAM policy
policy = client.get_iam_policy key_ring

# 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

Was this page helpful? Let us know how we did:

Send feedback about...