Skip to main content
Send feedback
Use customer-managed encryption keys Stay organized with collections
Save and categorize content based on your preferences.
Overview
This page describes how to use a manually-created Cloud Key Management Service
encryption
key with Cloud Storage, including setting default keys on buckets and adding
keys to individual objects. A Cloud KMS encryption key is a customer-managed encryption key
(CMEK). Such keys are created and managed
through Cloud KMS and stored as software keys, in an HSM cluster
,
or externally
.
If you instead want to use the Cloud KMS Autokey feature
to
generate key rings and keys on demand that protect your Cloud Storage
buckets and the objects within them, see Using Autokey with Cloud Storage resources
. To decide which
key type is right for you when comparing CMEK to Cloud KMS with Autokey
and Google default encryption, see Comparison of CMEK and Google-owned and Google-managed encryption keys
.
Before you begin
Before using this feature in Cloud Storage, you must:
Enable the Cloud KMS API for the project that will store your
encryption keys.
Enable the API
Have sufficient permission for 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.cryptoKeys.create
permission.
Whether you plan to use new or existing key rings and keys, you should
have cloudkms.cryptoKeys.setIamPolicy
permission for the keys
that you will use for encryption.
This permission allows you to give Cloud Storage service agents
access to Cloud KMS keys.
The above permissions are contained in the Cloud KMS Admin role.
See Using IAM with Cloud KMS
for instructions on
how to get this or other Cloud KMS roles.
Have a Cloud KMS key ring
, and have at least one key
within the key ring.
The key ring must be in the same location as the data you intend to encrypt,
but it can be in a different project. For available Cloud KMS
locations, see Cloud KMS locations
.
Note: For buckets in dual-regions
, the Cloud KMS location
must match the location code associated with the dual-region. This means
that for configurable dual-regions, you must create the key ring in
the associated multi-region, but for predefined dual-regions, you must
create the key ring in the same predefined dual-region.
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 Storage Object Admin 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.
Note: The following step is not necessary if you are using the
Google Cloud CLI.
Get the email address of the service agent
associated with the project
that contains your Cloud Storage bucket. By performing this step,
you automatically create the service agent if it doesn't currently exist.
Assign a Cloud KMS key to a service agent
In order to use CMEKs, grant the Cloud Storage service agent associated
with your bucket the permission to use your Cloud KMS key for
encrypting and decrypting:
Console
In the Google Cloud console, go to the Key management
page. Go to Key management
Click the name of the key ring that contains the key you want to use.
Select the checkbox for the desired key.
The Permissions tab in the right window pane becomes available.
In the Add principals dialog, specify the email address of the
Cloud Storage service agent you are granting access.
In the Select a role drop down, select Cloud KMS CryptoKey
Encrypter/Decrypter .
Click Add .
To learn how to get detailed error information about failed Cloud Storage
operations in the Google Cloud console, see Troubleshooting
.
Command line
Use the gcloud storage service-agent
command with the --authorize-cmek
flag to give the service agent associated with your
bucket permission to encrypt and decrypt objects using your
Cloud KMS key:
gcloud storage service-agent --project= PROJECT_STORING_OBJECTS
--authorize-cmek= KEY_RESOURCE
Where:
PROJECT_STORING_OBJECTS
is the ID or number
for the project containing the objects you want to encrypt or decrypt.
For example, my-pet-project
.
KEY_RESOURCE
is your Cloud KMS key resource
.
REST APIs
JSON API
Note: This task uses a separate endpoint compared to most
Cloud Storage tasks.
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Create a JSON file that contains the following information:
{
"policy"
:
{
"bindings"
:
{
"role"
:
"roles/cloudkms.cryptoKeyEncrypterDecrypter"
,
"members"
:
"serviceAccount: SERVICE_AGENT_EMAIL_ADDRESS
"
},
}
}
Where SERVICE_AGENT_EMAIL_ADDRESS
is the
email address associated with your service agent. For example, service-7550275089395@gs-project-accounts.iam.gserviceaccount.com
.
Use cURL
to call the Cloud KMS API with
a POST setIamPolicy
request:
curl -X POST --data-binary @ JSON_FILE_NAME
\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://cloudkms.googleapis.com/v1/ KEY_RESOURCE
:setIamPolicy"
Where:
JSON_FILE_NAME
is the path for the JSON
file that you created in Step 2.
KEY_RESOURCE
is your Cloud KMS key resource
.
Caution: This request replaces any existing IAM policy on the key
resource.
Note: There may be a delay of several seconds between assigning the role
and having it applied to your service agent. If you grant this
permission programmatically, wait 30 seconds before configuring
Cloud Storage.
XML API
The XML API cannot be used to assign a Cloud KMS to a service
agent. Use one of the other Cloud Storage tools, such as the
gcloud CLI, instead.
Use default encryption keys
The following sections describe how to use default encryption keys.
Set the default key for a bucket
To add, change, or remove the Cloud KMS key that is used by default
when objects are written to a bucket:
Console
In the Google Cloud console, go to the Cloud Storage Buckets
page. Go to Buckets
In the list of buckets, click the name of the bucket.
Click the Configuration tab.
In the Protection section, click edit
Edit encryption .
In the Default encryption key type section, do either of the
following things:
To add or change the default Cloud KMS key for the bucket,
select Cloud KMS key . Then, select one of the available keys
from the list.
To remove the default Cloud KMS key, select Google-managed encryption key .
Click Save .
To learn how to get detailed error information about failed Cloud Storage
operations in the Google Cloud console, see Troubleshooting
.
Command line
Use the gcloud storage buckets update
command with the
appropriate flag:
gcloud storage buckets update gs:// BUCKET_NAME
FLAG
Where:
BUCKET_NAME
is the name of the relevant
bucket. For example, my-bucket
.
FLAG
is the desired setting for the default
key on the bucket. Use one of the following formats:
--default-encryption-key=
and a Cloud KMS key resource
,
if you want to add or change a default key.
--clear-default-encryption-key
, if you want to remove the
default key on the bucket.
If successful, the response looks like:
Updating gs://my-bucket/...
Completed 1
Client libraries
Rust
The following sample sets a default customer-managed encryption key on a bucket:
The following sample removes the default customer-managed encryption key from a bucket:
REST APIs
JSON API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Create a JSON file that contains the following information:
{
"encryption"
:
{
"defaultKmsKeyName"
:
" KEY_RESOURCE
"
}
}
Where KEY_RESOURCE
is your Cloud KMS key resource
.
To remove the default Cloud KMS key from a bucket, use the
following in the JSON file:
{
"encryption"
:
{
"defaultKmsKeyName"
:
null
}
}
Use cURL
to call the JSON API with a PATCH
Bucket
request:
curl -X PATCH --data-binary @ JSON_FILE_NAME
\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://storage.googleapis.com/storage/v1/b/ BUCKET_NAME
?fields=encryption"
Where:
JSON_FILE_NAME
is the path for the JSON
file that you created in Step 2.
BUCKET_NAME
is the name of the relevant
bucket. For example, my-bucket
.
XML API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Create an XML file that contains the following information:
<EncryptionConfiguration>
<DefaultKmsKeyName> KEY_RESOURCE
</DefaultKmsKeyName>
</EncryptionConfiguration>
Where KEY_RESOURCE
is your Cloud KMS key resource
.
To remove the default Cloud KMS key from a bucket, use the
following in the XML file.
<EncryptionConfiguration></EncryptionConfiguration>
Use cURL
to call the XML API with a PUT
Bucket
request and encryptionConfig
query string
parameter:
curl -X PUT --data-binary @ XML_FILE_NAME
\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://storage.googleapis.com/ BUCKET_NAME
?encryptionConfig"
Where:
XML_FILE_NAME
is the path for the XML
file that you created in Step 2.
BUCKET_NAME
is the name of the relevant
bucket. For example, my-bucket
.
Note: The encryption state of objects that were written to a bucket prior to
adding, changing, or removing the default key are unaffected by changes to
the default key.
View the default key for a bucket
To view the Cloud KMS key that is set as default for your bucket:
Console
In the Google Cloud console, go to the Cloud Storage Buckets
page. Go to Buckets
In the list of buckets, click the name of the bucket.
Click the Configuration tab.
The default key for the bucket appears in the Default encryption key type field.
To learn how to get detailed error information about failed Cloud Storage
operations in the Google Cloud console, see Troubleshooting
.
Command line
Use the gcloud storage buckets describe
command with the --format
flag:
gcloud storage buckets describe gs:// BUCKET_NAME
--format="default(default_kms_key)"
Where BUCKET_NAME
is the name of the bucket
whose key you want to view. For example, my-bucket
.
If successful, the response looks like:
de
fault
_kms_key
:
KEY_RESOURCE
REST APIs
JSON API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Use cURL
to call the JSON API with a GET
Bucket
request that includes the desired fields
:
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://storage.googleapis.com/storage/v1/b/ BUCKET_NAME
?fields=encryption"
Where BUCKET_NAME
is the name of the bucket
whose key you want to view. For example, my-bucket
.
The response looks like the following example:
{
"encryption"
:
{
"defaultKmsKeyName"
:
" KEY_RESOURCE
"
},
}
XML API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Use cURL
to call the XML API with a GET
Bucket
request that includes the encryption
query
parameter:
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://storage.googleapis.com/ BUCKET_NAME
?encryptionConfig"
Where BUCKET_NAME
is the name of the bucket
whose key you want to view. For example, my-bucket
.
The response looks like the following example:
<EncryptionConfiguration>
<DefaultKmsKeyName> KEY_RESOURCE
</DefaultKmsKeyName>
</EncryptionConfiguration>
Encrypt 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. The name of the
key resource used to encrypt the object is stored in the object's metadata.
Console
The Google Cloud console cannot be used to specify Cloud KMS keys
on a per-object basis. Use the gcloud CLI or the client
libraries instead.
Command line
Use the gcloud storage cp
command with the --encryption-key
flag:
gcloud storage cp SOURCE_DATA
gs:// BUCKET_NAME
/ OBJECT_NAME
--encryption-key= KEY_RESOURCE
Where:
SOURCE_DATA
is the source location of the data
you're encrypting. This can be any source location supported by the cp
command. For example gs://my-bucket/pets/old-dog.png
.
BUCKET_NAME
is the name of the destination
bucket for this copy command. For example, my-bucket
.
OBJECT_NAME
is the name of the final,
encrypted object. For example, pets/new-dog.png
.
KEY_RESOURCE
is the Cloud KMS key resource
you want to use for encrypting the object.
REST APIs
JSON API
Note: These steps apply specifically to inserting objects using the JSON
API. You can follow a similar procedure to compose or rewrite objects
with the JSON API.
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Add the object's data to the request body.
Use cURL
to call the JSON API with a POST
Object
request:
curl -X POST --data-binary @ OBJECT
\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: OBJECT_CONTENT_TYPE
" \
"https://storage.googleapis.com/upload/storage/v1/b/ BUCKET_NAME
/o?uploadType=media&name= OBJECT_NAME
&kmsKeyName= KEY_RESOURCE
"
Where:
OBJECT
is the path to the object you are
uploading. For example, Desktop/dog.png
.
OBJECT_CONTENT_TYPE
is the content type
of the object. For example, image/png
.
BUCKET_NAME
is the name of the bucket to
which you are uploading your object. For example, my-bucket
.
OBJECT_NAME
is the URL-encoded name
of the object you are uploading. For example, pets/dog.png
,
URL-encoded as pets%2Fdog.png
.
KEY_RESOURCE
is the Cloud KMS key resource
.
XML API
Note: These steps apply specifically to uploading objects using the XML
API. You can follow a similar procedure to compose or copy objects with
the XML API.
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Add the object's data to the request body.
Use cURL
to call the XML API with a PUT
Object
request:
curl -X PUT --data-binary @ OBJECT
\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: OBJECT_CONTENT_TYPE
" \
-H "x-goog-encryption-kms-key-name: KEY_RESOURCE
" \
"https://storage.googleapis.com/ BUCKET_NAME
/ OBJECT_NAME
"
Where:
OBJECT
is the path to the object you are
uploading. For example, Desktop/dog.png
.
OBJECT_CONTENT_TYPE
is the content type
of the object. For example, image/png
.
BUCKET_NAME
is the name of the bucket to
which you are uploading your object. For example, my-bucket
.
OBJECT_NAME
is the URL-encoded name
of the object you are uploading. For example, pets/dog.png
,
URL-encoded as pets%2Fdog.png
.
KEY_RESOURCE
is your Cloud KMS key resource
.
Rotate from a customer-supplied key to a Cloud KMS key
If your objects are encrypted with customer-supplied encryption keys
, you
can rotate them to use Cloud KMS keys by rewriting the object.
Note: Rotating from customer-supplied encryption keys to Cloud KMS keys
involves rewriting data, which might incur early deletion
charges, depending
on the age and storage class of the data.
Console
The Google Cloud console cannot be used to change encryption keys on a
per-object basis. Use the gcloud CLI or the client
libraries instead.
Command line
Use the gcloud storage objects update
command with the
appropriate flags:
gcloud storage objects update gs:// BUCKET_NAME
/ OBJECT_NAME
--encryption-key= KMS_KEY
--decryption-keys= CSEK_KEY
Where:
BUCKET_NAME
is the name of the bucket that
contains the object whose key you are rotating. For example, my-bucket
.
OBJECT_NAME
is the name of the object whose
key you are rotating. For example, pets/dog.png
.
KMS_KEY
is the Cloud KMS key resource
you want to use for encrypting the object.
CSEK_KEY
is the current customer-supplied
encryption key used on the object.
REST APIs
JSON API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Use cURL
to call the JSON API with a POST
Object
request:
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Length: 0" \
-H "x-goog-copy-source-encryption-algorithm: AES256" \
-H "x-goog-copy-source-encryption-key: OLD_ENCRYPTION_KEY
" \
-H "x-goog-copy-source-encryption-key-sha256: HASH_OF_OLD_KEY
" \
"https://storage.googleapis.com/storage/v1/b/ BUCKET_NAME
/o/ OBJECT_NAME
/rewriteTo/b/ BUCKET_NAME
/o/ OBJECT_NAME
?kmsKeyName= KEY_RESOURCE
"
Where:
OLD_ENCRYPTION_KEY
is the current AES-256
key used to encrypt your object.
HASH_OF_OLD_KEY
is the current SHA-256
hash for your AES-256 key.
BUCKET_NAME
is the name of the bucket
containing the relevant object. For example, my-bucket
.
OBJECT_NAME
is the URL-encoded name
of the object whose keys you are rotating. For example, pets/dog.png
, URL-encoded as pets%2Fdog.png
.
KEY_RESOURCE
is the Cloud KMS key resource
.
Identify the key used to encrypt an object
To find the Cloud KMS key that was used to encrypt an object:
Console
In the Google Cloud console, go to the Cloud Storage Buckets
page. Go to Buckets
In the list of buckets, click the name of the bucket that contains
the object.
The Bucket details page opens, with the Objects tab selected.
Navigate to the object, which might be located in a folder.
In the Encryption column, hold the pointer over the entry for the
object.
The key name and version appear in the format:
LOCATION
/ KEY_RING_NAME
/ KEY_NAME
/ KEY_VERSION
Command line
Use the gcloud storage objects describe
command with the --format
flag:
gcloud storage objects describe gs:// BUCKET_NAME
/ OBJECT_NAME
--format="default(kms_key)"
Where:
BUCKET_NAME
is the name of the bucket
containing the encrypted object. For example, my-bucket
.
OBJECT_NAME
is the name of the encrypted
object. For example, pets/dog.png
.
If successful, the response looks like:
kms_key
:
projec
ts
/my
-
pe
t
-
projec
t
/loca
t
io
ns
/ LOCATION_NAME
/keyRi
n
gs/ KEYRING_NAME
/cryp
t
oKeys/ KEY_NAME
/cryp
t
oKeyVersio
ns
/ VERSION_NUMBER
Client libraries
Rust
To view the KMS key associated with an object, follow the instructions for displaying an object's metadata and look for
the KMS key name field in the response.
REST APIs
JSON API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Use cURL
to call the JSON API with a GET
Object
request:
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://storage.googleapis.com/storage/v1/b/ BUCKET_NAME
/o/ OBJECT_NAME
?fields=kmsKeyName"
Where:
BUCKET_NAME
is the name of the bucket
containing the encrypted object. For example, my-bucket
.
OBJECT_NAME
is the URL-encoded name
of the encrypted object. For example, pets/dog.png
,
URL-encoded as pets%2Fdog.png
.
XML API
Have gcloud CLI installed and initialized
, which lets
you generate an access token for the Authorization
header.
Use cURL
to call the XML API with a GET
Object
request:
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://storage.googleapis.com/ BUCKET_NAME
/ OBJECT_NAME
?encryption"
Where:
BUCKET_NAME
is the name of the bucket
containing the encrypted object. For example, my-bucket
.
OBJECT_NAME
is the URL-encoded name
of the encrypted object. For example, pets/dog.png
,
URL-encoded as pets%2Fdog.png
.
Note: If the object was written with an encryption method other than
Cloud KMS, there is no information associated with this metadata field.
Re-encrypt objects in bulk
To re-encrypt millions or billions of objects with a different key with a
single job, use Storage batch operations
. To create a job, specify
the objects you want to re-encrypt and the destination key, either by
providing a list of objects in a manifest file or by using object prefixes.
After you have specified the object list, create a batch operation job to
re-encrypt the objects
.
Decrypt an object
Decrypting an object encrypted with a Cloud KMS key is performed
automatically as long as the relevant service agent has access to the key. For
more information, see Service agents with CMEKs
.
What's next
Send feedback
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License
, and code samples are licensed under the Apache 2.0 License
. For details, see the Google Developers Site Policies
. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-05-29 UTC.
Need to tell us more?
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-05-29 UTC."],[],[]]