Using Customer-Managed Encryption Keys

This page describes how to use a Cloud Key Management Service encryption key with Cloud Storage, including getting started with the feature, using default keys on buckets, and adding keys to individual objects. The Cloud KMS encryption key is a customer-managed encryption key, which is created by Cloud KMS and managed by you. For details about this feature, see Customer-Managed Encryption Keys. For other encryption options in Cloud Storage, see Data Encryption Options.

Prerequisites

Before using this feature in Cloud Storage, you should:

  1. Enable the Cloud KMS API for the project that will store your encryption keys.

    Enable the API

  2. Have sufficient permission on the project that will store your encryption keys:

    • If you own the project that will store your keys, you most likely have the necessary permission.

    • If you plan to create new encryption key rings and keys, you should have cloudkms.keyRings.create and cloudkms.cryptoKey.create permission.

    • Whether you plan to use new or existing key rings and keys, you should have cloudkms.cryptoKey.setIamPolicy permission for the keys that you will use for encryption.

      This permission allows you to give Cloud Storage service accounts access to Cloud KMS keys.

    • The above permissions are contained in the roles/cloudkms.admin role.

      See Using IAM with Cloud KMS for instructions on how to get this or other Cloud KMS roles.

  3. Have sufficient permission to work with objects in your Cloud Storage bucket:

    • If you own the project that contains the bucket, you most likely have the necessary permission.

    • If you use IAM, you should have storage.objects.create permission to write objects to the bucket and storage.objects.get permission to read objects from the bucket. See Using IAM Permissions for instructions on how to get a role, such as roles/storage.objectAdmin that has these permissions.

    • If you use ACLs, you should have bucket-scoped WRITER permission to write objects to the bucket and object-scoped READER permission to read objects from the bucket. See Setting ACLs for instructions on how to do this.

  4. Have a Cloud KMS key ring, and have at least one key within the key ring.

  5. Get the email address of the service account associated with the project that contains your Cloud Storage bucket.

Assigning a Cloud KMS key to a service account

In order to use customer-managed encryption keys, you must give your Cloud Storage service account permission to use your Cloud KMS key.

Console

  1. Open the Cloud Key Management Service Keys browser in the Google Cloud Platform Console.
    Open the Cloud KMS Keys browser
  2. Click on the name of the key ring that contains the desired key.

  3. Select the checkbox for the desired key.

    The Permissions tab in the right window pane becomes available.

  4. In the Add members dialog, specify the email address of the Cloud Storage service account you are granting access.

  5. In the Select a role drop down, select Cloud KMS CrytoKey Encrypter/Decrypter.

  6. Click Add.

gsutil

Use the gsutil kms authorize command to give the service account associated with your bucket permission to encrypt and decrypt objects using your Cloud KMS key, replacing [VALUES_IN_BRACKETS] with the appropriate values:

gsutil kms authorize -p [PROJECT_STORING_OBJECTS] -k [KEY_RESOURCE]

See Key resources for the expected format of [KEY_RESOURCE].

If you want to remove the granted permission, you need to use either the gcloud command-line tool or the Google Cloud Platform Console.

Code samples

C#

For more information, see the Cloud Storage C# API reference documentation .

public static object AddMemberToCryptoKeyPolicy(string projectId, string locationId,
    string keyRingId, string cryptoKeyId, 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/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}";
    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;
}

Go

For more information, see the Cloud Storage Go API reference documentation .

func addMemberRingPolicy(project, location, keyRing, role, member string) error {
	var client *cloudkms.Service // Boilerplate is inserted by gen.go

	parent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s",
		project, location, keyRing)

	policy, err := client.Projects.Locations.KeyRings.GetIamPolicy(parent).Do()
	if err != nil {
		return err
	}
	policy.Bindings = append(policy.Bindings, &cloudkms.Binding{
		Role:    role,
		Members: []string{member},
	})
	if err != nil {
		return err
	}

	_, err = client.Projects.Locations.KeyRings.SetIamPolicy(
		parent, &cloudkms.SetIamPolicyRequest{
			Policy: policy,
		}).Do()
	if err != nil {
		return err
	}

	return nil
}

Java

For more information, see the Cloud Storage Java API reference documentation .

/**
 * 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.
  CloudKMS kms = createAuthorizedClient();

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

  // Get the current IAM policy
  Policy iamPolicy = getCryptoKeyPolicy(projectId, locationId, keyRingId, cryptoKeyId);

  // 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 information, see the Cloud Storage Node.js API reference documentation .

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

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

// The name of the key ring, e.g. "my-key-ring"
// const keyRingId = '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/${locationId}/keyRings/${keyRingId}`
  };

  // 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.data);

    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/${locationId}/keyRings/${keyRingId}`,
      // 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 ${keyRingId}.`);
      if (policy.data.bindings) {
        policy.data.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.`);
      }
    });
  });
});

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 information, see the Cloud Storage PHP API reference documentation .

/**
 * Add a member to a CryptoKey IAM policy.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @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 $locationId
 * @return null
 */
function add_member_to_cryptokey_policy($projectId, $keyRingId, $cryptoKeyId, $member, $role, $locationId)
{
    // 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,
        $locationId,
        $keyRingId,
        $cryptoKeyId
    );

    // 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 cryptoKey %s in keyRing %s' . PHP_EOL, $member, $cryptoKeyId, $keyRingId);
}

Python

For more information, see the Cloud Storage Python API reference documentation .

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."""

    # 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_id, key_ring_id, crypto_key_id)

    # Get the current IAM policy and add the new member to it.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    policy_request = crypto_keys.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.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.setIamPolicy(
        resource=parent, body={'policy': policy_response})
    request.execute()

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

Ruby

For more information, see the Cloud Storage Ruby API reference documentation .

# 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/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 key ring
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "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}"

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .json file that contains the following information, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    {
      "policy": {
        "bindings": {
          "role": "roles/cloudkms.cryptoKeyEncrypterDecrypter",
          "members": "[SERVICE_ACCOUNT_EMAIL_ADDRESS]"
        },
      }
    }
  3. Use cURL to call the Cloud KMS API with a POST setIamPolicy request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X POST --data-binary @[JSON_FILE_NAME].json \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "Content-Type: application/json" \
    "https://cloudkms.googleapis.com/v1/[KEY_RESOURCE]:setIamPolicy"

    See Key resources for the expected format of [KEY_RESOURCE].

XML API

The XML API cannot be used to assign a Cloud KMS to a service account. Use one of the other Cloud Storage tools, such as gsutil, instead.

Using default encryption keys

Adding or changing the default key for a bucket

To add or change the Cloud KMS key that is used by default when objects are written to a bucket:

Console

  1. Open the Cloud Storage browser in the Google Cloud Platform Console.
    Open the Cloud Storage browser
  2. In the list of buckets, click on the desired bucket.

  3. Click Edit bucket at the top of the page.

  4. In the Edit Bucket page, click the Show advanced settings expandable.

  5. If the bucket isn't currently using a Cloud KMS key, select the Customer-managed key radio button.

  6. In the drop-down menu associated with customer-managed keys, select one of the available keys.

  7. Click Save.

gsutil

Use the gsutil kms encryption command, replacing [VALUES_IN_BRACKETS] with the appropriate values:

gsutil kms encryption -k [KEY_RESOURCE] gs://[BUCKET_NAME]

See Key resources for the expected format of [KEY_RESOURCE].

If successful, the response looks like:

Authorized service account [SERVICE_ACCOUNT_NAME] to use key:
[KEY_RESOURCE]

Code samples

C#

For more information, see the Cloud Storage C# API reference documentation .

private void AddBucketDefaultKmsKey(string bucketName,
    string keyLocation, string kmsKeyRing, string kmsKeyName)
{
    string KeyPrefix = $"projects/{s_projectId}/locations/{keyLocation}";
    string FullKeyringName = $"{KeyPrefix}/keyRings/{kmsKeyRing}";
    string FullKeyName = $"{FullKeyringName}/cryptoKeys/{kmsKeyName}";
    var storage = StorageClient.Create();
    var bucket = storage.GetBucket(bucketName, new GetBucketOptions()
    {
        Projection = Projection.Full
    });
    bucket.Encryption = new Bucket.EncryptionData
    {
        DefaultKmsKeyName = FullKeyName
    };
    var updatedBucket = storage.UpdateBucket(bucket, new UpdateBucketOptions()
    {
        // Avoid race conditions.
        IfMetagenerationMatch = bucket.Metageneration,
    });
}

Go

For more information, see the Cloud Storage Go API reference documentation .

bucket := c.Bucket(bucketName)
if _, err := bucket.Update(ctx, storage.BucketAttrsToUpdate{
	Encryption: &storage.BucketEncryption{DefaultKMSKeyName: keyName},
}); err != nil {
	return err
}

Java

For more information, see the Cloud Storage Java API reference documentation .

// Instantiate a Google Cloud Storage client
Storage storage = StorageOptions.getDefaultInstance().getService();

// The name of the existing bucket to set a default KMS key for, e.g. "my-bucket"
// String bucketName = "my-bucket"

// The name of the KMS-key to use as a default
// Key names are provided in the following format:
// 'projects/<PROJECT>/locations/<LOCATION>/keyRings/<RING_NAME>/cryptoKeys/<KEY_NAME>'
// String kmsKeyName = ""

BucketInfo bucketInfo = BucketInfo.newBuilder(bucketName)
    .setDefaultKmsKeyName(kmsKeyName)
    .build();

Bucket bucket = storage.update(bucketInfo);

System.out.println("Default KMS Key Name: " + bucket.getDefaultKmsKeyName());

Node.js

For more information, see the Cloud Storage Node.js API reference documentation .

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const bucketName = 'Name of a bucket, e.g. my-bucket';
// const defaultKmsKeyName = 'KMS key resource id, e.g. my-key';

// Enables a default KMS key for the bucket
storage
  .bucket(bucketName)
  .setMetadata({
    encryption: {
      defaultKmsKeyName,
    },
  })
  .then(() => {
    console.log(
      `Default KMS key for ${bucketName} was set to ${defaultKmsKeyName}.`
    );
  })
  .catch(err => {
    console.error('ERROR:', err);
  });

PHP

For more information, see the Cloud Storage PHP API reference documentation .

use Google\Cloud\Storage\StorageClient;

/**
 * Enable a bucket's requesterpays metadata.
 *
 * @param string $projectId Your Google Cloud project ID.
 * @param string $bucketName Name of your Google Cloud Storage bucket.
 * @param string $kmsKeyName KMS key ID to use as the default KMS key.
 *
 * @return void
 */
function enable_default_kms_key($projectId, $bucketName, $kmsKeyName)
{
    $storage = new StorageClient([
        'projectId' => $projectId
    ]);
    $bucket = $storage->bucket($bucketName);
    $bucket->update([
        'encryption' => [
            'defaultKmsKeyName' => $kmsKeyName
        ]
    ]);
    printf('Default KMS key for %s was set to %s' . PHP_EOL,
        $bucketName,
        $bucket->info()['encryption']['defaultKmsKeyName']);
}

Python

For more information, see the Cloud Storage Python API reference documentation .

"""Sets a bucket's default KMS key."""
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
bucket.default_kms_key_name = kms_key_name
bucket.patch()

print('Set default KMS key for bucket {} to {}.'.format(
    bucket.name,
    bucket.default_kms_key_name))

Ruby

For more information, see the Cloud Storage Ruby API reference documentation .

# project_id      = "Your Google Cloud project ID"
# bucket_name     = "Name of your Google Cloud Storage bucket"
# default_kms_key = "KMS key resource id"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new project: project_id
bucket  = storage.bucket bucket_name

bucket.default_kms_key = default_kms_key

puts "Default KMS key for #{bucket.name} was set to #{bucket.default_kms_key}"

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .json file that contains the following information, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    {
      "encryption": {
        "defaultKmsKeyName": "[KEY_RESOURCE]"
      }
    }

    See Key resources for the expected format of [KEY_RESOURCE].

  3. Use cURL to call the JSON API with a PATCH Bucket request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X PATCH --data-binary @[JSON_FILE_NAME].json \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "Content-Type: application/json" \
    "https://www.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=encryption"

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .xml file that contains the following information, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    <EncryptionConfiguration>
      <DefaultKmsKeyName>[KEY_RESOURCE]</DefaultKmsKeyName>
    </EncryptionConfiguration>

    See Key resources for the expected format of [KEY_RESOURCE].

  3. Use cURL to call the XML API with a PUT Bucket request and encryption query string paratmeter, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?encryptionConfig"

Viewing the default key for a bucket

To view the Cloud KMS key that is currently set as default for your bucket:

Console

  1. Open the Cloud Storage browser in the Google Cloud Platform Console.
    Open the Cloud Storage browser
  2. In the list of buckets, click on the desired bucket.

  3. In the bucket details page, click on the Overview tab.

  4. The current default key for your bucket appears in the Encryption key field.

gsutil

Use the gsutil kms encryption command, replacing [VALUES_IN_BRACKETS] with the appropriate values:

gsutil kms encryption gs://[BUCKET_NAME]

If successful, the response looks like:

Default encryption key for gs://[BUCKET_NAME]:
[KEY_RESOURCE]

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a GET Bucket request that includes the desired fields, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X GET -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://www.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=encryption"

    The response looks like the following example:

    {
      "encryption" : {
         "defaultKmsKeyName": "[KEY_RESOURCE]"
       },
    }

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API with a GET Bucket request that includes the encryption query parameter, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X GET -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?encryptionConfig"

    The response looks like the following example:

    <EncryptionConfiguration>
      <DefaultKmsKeyName>[KEY_RESOURCE]</DefaultKmsKeyName>
    </EncryptionConfiguration>

Removing the default key from a bucket

To remove any default Cloud KMS key set on a bucket:

Console

  1. Open the Cloud Storage browser in the Google Cloud Platform Console.
    Open the Cloud Storage browser
  2. In the list of buckets, click on the desired bucket.

  3. Click Edit bucket at the top of the page.

  4. In the Edit Bucket page, click the Show advanced settings expandable.

  5. Select the Google-managed key radio button.

  6. Click Save.

gsutil

Use the gsutil kms encryption command, replacing [VALUES_IN_BRACKETS] with the appropriate values:

gsutil kms encryption -d gs://[BUCKET_NAME]

If successful, the response looks like:

Clearing default encryption key for gs://[BUCKET_NAME]...

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .json file that contains the following information:

    {
      "encryption": {
        "defaultKmsKeyName": null
      }
    }
  3. Use cURL to call the JSON API with a PATCH Bucket request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X PATCH --data-binary @[JSON_FILE_NAME].json \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "Content-Type: application/json" \
    "https://www.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=encryption"

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .xml file that contains the following information:

    <EncryptionConfiguration></EncryptionConfiguration>
  3. Use cURL to call the XML API with a PUT Bucket request and encryption query string paratmeter, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?encryptionConfig"

Encrypting an object with a Cloud KMS key

You can encrypt an individual object with a Cloud KMS key. This is useful if you want to use a different key from the default key set on the bucket, or if you don't have a default key set on the bucket.

Console

The GCP Console cannot be used to encrypt individual objects. Use gsutil or the client libraries instead.

gsutil

  1. Specify a key in the .boto configuration file for gsutil, in the encryption_key attribute under the [GSUtil] section.

    See Key resources for the expected format of your key.

  2. Write an object to the bucket as you normally would, for example with gsutil cp or gsutil rewrite.

Code samples

C#

For more information, see the Cloud Storage C# API reference documentation .

        private void UploadEncryptedFileWithKmsKey(string bucketName,
            string keyLocation, string kmsKeyRing, string kmsKeyName,
            string localPath, string objectName = null)
        {
            string KeyPrefix = $"projects/{s_projectId}/locations/{keyLocation}";
            string FullKeyringName = $"{KeyPrefix}/keyRings/{kmsKeyRing}";
            string FullKeyName = $"{FullKeyringName}/cryptoKeys/{kmsKeyName}";

            var storage = StorageClient.Create();
            using (var f = File.OpenRead(localPath))
            {
                objectName = objectName ?? Path.GetFileName(localPath);
                storage.UploadObject(bucketName, objectName, null, f,
                    new UploadObjectOptions()
                    {
                        KmsKeyName = FullKeyName
                    });
                Console.WriteLine($"Uploaded {objectName}.");
            }
        }

Go

For more information, see the Cloud Storage Go API reference documentation .

obj := client.Bucket(bucket).Object(object)
// Encrypt the object's contents
wc := obj.NewWriter(ctx)
wc.KMSKeyName = keyName
if _, err := wc.Write([]byte("top secret")); err != nil {
	return err
}
if err := wc.Close(); err != nil {
	return err
}

Java

For more information, see the Cloud Storage Java API reference documentation .

byte[] data = "Hello, World!".getBytes(UTF_8);

// The name of the existing bucket to set a default KMS key for, e.g. "my-bucket"
// String bucketName = "my-bucket"

// The name of the KMS-key to use as a default
// Key names are provided in the following format:
// 'projects/<PROJECT>/locations/<LOCATION>/keyRings/<RING_NAME>/cryptoKeys/<KEY_NAME>'
// String kmsKeyName = ""

BlobId blobId = BlobId.of(bucketName, blobName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId)
    .setContentType("text/plain")
    .build();
Blob blob = storage.create(blobInfo, data, BlobTargetOption.kmsKeyName(kmsKeyName));

Node.js

For more information, see the Cloud Storage Node.js API reference documentation .

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const bucketName = 'Name of a bucket, e.g. my-bucket';
// const filename = 'Local file to upload, e.g. ./local/path/to/file.txt';
// const kmsKeyName = 'KMS key resource id, e.g. my-key';

// Uploads a local file to the bucket with the kms key
storage
  .bucket(bucketName)
  .upload(filename, {
    kmsKeyName,
  })
  .then(() => {
    console.log(`${filename} uploaded to ${bucketName} using ${kmsKeyName}.`);
  })
  .catch(err => {
    console.error('ERROR:', err);
  });

PHP

For more information, see the Cloud Storage PHP API reference documentation .

use Google\Cloud\Storage\StorageClient;

/**
 * Upload a file using KMS encryption.
 *
 * @param string $projectId Your Google Cloud project ID.
 * @param string $bucketName the name of your Google Cloud bucket.
 * @param string $objectName the name of the object.
 * @param string $source the path to the file to upload.
 * @param string $kmsKeyName KMS key ID used to encrypt objects server side.
 *
 * @return Psr\Http\Message\StreamInterface
 */
function upload_with_kms_key($projectId, $bucketName, $objectName, $source, $kmsKeyName)
{
    $storage = new StorageClient([
        'projectId' => $projectId,
    ]);
    $file = fopen($source, 'r');
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->upload($file, [
        'name' => $objectName,
        'destinationKmsKeyName' => $kmsKeyName,
    ]);
    printf('Uploaded %s to gs://%s/%s using encryption key %s' . PHP_EOL,
        basename($source),
        $bucketName,
        $objectName,
        $kmsKeyName);
}

Python

For more information, see the Cloud Storage Python API reference documentation .

"""Uploads a file to the bucket, encrypting it with the given KMS key."""
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(destination_blob_name, kms_key_name=kms_key_name)
blob.upload_from_filename(source_file_name)

print('File {} uploaded to {} with encryption key {}.'.format(
    source_file_name,
    destination_blob_name,
    kms_key_name))

Ruby

For more information, see the Cloud Storage Ruby API reference documentation .

# project_id        = "Your Google Cloud project ID"
# bucket_name       = "Your Google Cloud Storage bucket name"
# local_file_path   = "Path to local file to upload"
# storage_file_path = "Path to store the file in Google Cloud Storage"
# kms_key           = "KMS key resource id"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new project: project_id

bucket = storage.bucket bucket_name

file = bucket.create_file local_file_path, storage_file_path,
                          kms_key: kms_key

puts "Uploaded #{file.name} and encrypted service side using #{file.kms_key}"

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Add the object's data to the request body.

  3. Use cURL to call the JSON API with a POST Object request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X POST --data-binary @[OBJECT] \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "Content-Type: [OBJECT_CONTENT_TYPE]" \
    "https://www.googleapis.com/upload/storage/v1/b/[BUCKET_NAME]/o?uploadType=media&name=[OBJECT_NAME]&kmsKeyName=[KEY_RESOURCE]"

    See Key resources for the expected format of [KEY_RESOURCE].

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Add the object's data to the request body.

  3. Use cURL to call the XML API with a PUT Object request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X PUT --data-binary @[OBJECT] \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "Content-Type: [OBJECT_CONTENT_TYPE]" \
    -H "x-goog-encryption-kms-key-name: [KEY_RESOURCE]" \
    "https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]"

    See Key resources for the expected format of [KEY_RESOURCE].

Identifying the key used to encrypt an object

To find the name of the Cloud KMS key that was used to encrypt an object:

Console

  1. Open the Cloud Storage browser in the Google Cloud Platform Console.
    Open the Cloud Storage browser
  2. Navigate to the desired object in the relevant bucket.

  3. In the Encryption column, hover your mouse over the entry for the desired object.

    The key name appears in the format:

    [LOCATION]/[KEY_RING_NAME]/[KEY_NAME]

gsutil

Use the gsutil ls command with the -L flag, replacing [VALUES_IN_BRACKETS] with the appropriate values:

gsutil ls -L gs://[BUCKET_NAME]/[OBJECT_NAME]

If successful, the response contains the key name:

gs://[BUCKET_NAME]/[OBJECT_NAME]:
...
KMS key: [KEY_RESOURCE]
...

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a GET Object request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://www.googleapis.com/storage/v1/b/[BUCKET_NAME]/o/[OBJECT_NAME]?fields=kmsKeyName"

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API with a GET Object request, replacing [VALUES_IN_BRACKETS] with the appropriate values:

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]?encryption"

Decrypting an object

Decrypting an object encrypted with a customer-managed encryption key is performed automatically as long as the relevant service account has access to the key. For more information, see Service accounts with customer-managed encryption keys.

What's next

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

Send feedback about...

Cloud Storage
Need help? Visit our support page.