To set your project in your environment, use the gcloud config set
command. To check if the project is already set in your environment, run
gcloud config list.
If no project is set, or you want to use a different project for your key,
run gcloud config set:
Create a key in the key ring. The ROTATION_PERIOD indicates the
interval to rotate the key, and the NEXT_ROTATION_TIME indicates
the date and time when the first rotation should occur.
For example, to rotate the key every 30 days and perform the first rotation
in 1 week, set ROTATION_PERIOD to 30d and
NEXT_ROTATION_TIME to
$(date --utc --date="next week" --iso-8601=seconds).
Create a workload identity pool provider. The --attribute-condition
argument verifies that the caller is a confidential match service account.
gcloudiamworkload-identity-poolsproviderscreate-oidcPROVIDER_ID\--location=global\--workload-identity-pool=WIP_ID\--display-name="PROVIDER_DISPLAY_NAME"\--description="PROVIDER_DESCRIPTION"\--attribute-mapping="google.subject=assertion.sub,google.groups=[\"PROVIDER_ID\"]"\--attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' &&
'STABLE' in assertion.submods.confidential_space.support_attributes &&
['cfm-services@admcloud-cfm-services.iam.gserviceaccount.com'].exists( a, a in assertion.google_service_accounts) &&
'ECDSA_P256_SHA256:6b1f357b59e9407fb017ca0e3e783b2bd5acbfea6c83dd82971a4150df5b25f9' in assertion.submods.container.image_signatures.map(sig, sig.signature_algorithm+':'+sig.key_id)"\--issuer-uri="https://confidentialcomputing.googleapis.com"\--allowed-audiences="https://sts.googleapis.com"
Grant the key decrypter role to the WIP provider.
# Grants the role to the WIP provider.
gcloudkmskeysadd-iam-policy-bindingKEY_NAME\--keyringKEY_RING_NAME\--locationKEY_RING_LOCATION\--member"principalSet://iam.googleapis.com/projects/PROJECT_ID/locations/global/workloadIdentityPools/WIP_ID/group/PROVIDER_ID"\--role"roles/cloudkms.cryptoKeyDecrypter"
If you want to encrypt event data for offline conversions and
enhanced conversions for leads, grant the key decrypter role to the Google
service account datamanager-api@datamanager-ga.iam.gserviceaccount.com.
# Grants the role to the Google service account.
gcloudkmskeysadd-iam-policy-bindingKEY_NAME\--keyringKEY_RING_NAME\--locationKEY_RING_LOCATION\--member"serviceAccount:datamanager-api@datamanager-ga.iam.gserviceaccount.com"\--role"roles/cloudkms.cryptoKeyDecrypter"
Encrypt data
Encryption in the Data Manager API requires a data encryption key (DEK). A DEK is a
symmetric key that you use to encrypt data. Your DEK is encrypted using
your Google Cloud KMS key. You send the encrypted DEK as part of the request.
To prepare the data in the request for encryption, follow the same formatting
and hashing guidelines you'd use for unencrypted data.
Don't encrypt unhashed values. For example, the region_code or postal_code
of an AddressInfo.
Once the data for each field is formatted and hashed, encrypt the hashed value
using the following steps:
Encode the hash bytes using Base64 encoding.
Encrypt the Base64-encoded hash using your DEK.
Encode the output from the encryption process using either hex or Base64
encoding.
To use the Data Manager API library and
utilities to construct and send a request,
see the IngestAudienceMembersWithEncryption code sample for Java or the
ingest_audience_members_with_encryption code sample for Python.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-04 UTC."],[],[],null,["# Encrypt user data\n\nHere's how to send encrypted data.\n\nSet up the Google Cloud command line interface\n----------------------------------------------\n\n1. [Install and\n initialize](//cloud.google.com/sdk/docs/install-sdk) the Google Cloud command line interface.\n\n2. To select or create a new Google Cloud project and enable the\n [Cloud Key Management Service](//cloud.google.com/kms/docs/key-management-service), click **Enable Cloud KMS**.\n\n | **Tip:** We recommend using a separate project for your Cloud KMS resources that doesn't contain any other Google Cloud resources.\n\n\n Enable Cloud KMS\n3. To set your project in your environment, use the [`gcloud config set`](//cloud.google.com/sdk/gcloud/reference/config/set)\n command. To check if the project is already set in your environment, run\n `gcloud config list`.\n\n If no `project` is set, or you want to use a different project for your key,\n run `gcloud config set`: \n\n gcloud config set project \u003cvar translate=\"no\"\u003ePROJECT_ID\u003c/var\u003e\n\nCreate a key\n------------\n\nFor more information, see the [Cloud Key Management Service overview](//cloud.google.com/kms/docs/key-management-service).\n\n1. Create a key ring.\n\n gcloud kms keyrings create \u003cvar translate=\"no\"\u003eKEY_RING_NAME\u003c/var\u003e \\\n --location \u003cvar translate=\"no\"\u003eKEY_RING_LOCATION\u003c/var\u003e\n\n For more information, see [Create a key ring](//cloud.google.com/kms/docs/create-key-ring).\n2. Create a key in the key ring. The \u003cvar translate=\"no\"\u003eROTATION_PERIOD\u003c/var\u003e indicates the\n interval to rotate the key, and the \u003cvar translate=\"no\"\u003eNEXT_ROTATION_TIME\u003c/var\u003e indicates\n the date and time when the first rotation should occur.\n\n For example, to rotate the key every 30 days and perform the first rotation\n in 1 week, set \u003cvar translate=\"no\"\u003eROTATION_PERIOD\u003c/var\u003e to `30d` and\n \u003cvar translate=\"no\"\u003eNEXT_ROTATION_TIME\u003c/var\u003e to\n `$(date --utc --date=\"next week\" --iso-8601=seconds)`. \n\n gcloud kms keys create \u003cvar translate=\"no\"\u003eKEY_NAME\u003c/var\u003e \\\n --keyring \u003cvar translate=\"no\"\u003eKEY_RING_NAME\u003c/var\u003e \\\n --location \u003cvar translate=\"no\"\u003eKEY_RING_LOCATION\u003c/var\u003e \\\n --purpose \"encryption\" \\\n --rotation-period \u003cvar translate=\"no\"\u003eROTATION_PERIOD\u003c/var\u003e \\\n --next-rotation-time \"\u003cvar translate=\"no\"\u003eNEXT_ROTATION_TIME\u003c/var\u003e\"\n\n For more information, see [Create a key](//cloud.google.com/kms/docs/create-key).\n\nCreate a workload identity pool provider\n----------------------------------------\n\nThis section is a short overview of Workload Identity Federation. For more\ninformation, see [Workload Identity Federation](//cloud.google.com/iam/docs/workload-identity-federation).\n\n1. Create a workload identity pool (WIP). The `location` for the pool must be\n `global`.\n\n gcloud iam workload-identity-pools create \u003cvar translate=\"no\"\u003eWIP_ID\u003c/var\u003e \\\n --location=global \\\n --display-name=\"\u003cvar translate=\"no\"\u003eWIP_DISPLAY_NAME\u003c/var\u003e\" \\\n --description=\"\u003cvar translate=\"no\"\u003eWIP_DESCRIPTION\u003c/var\u003e\"\n\n For more information, see [Manage workload identity pools and\n providers](//cloud.google.com/iam/docs/manage-workload-identity-pools-providers).\n2. Create a workload identity pool provider. The `--attribute-condition`\n argument verifies that the caller is a confidential match service account.\n\n gcloud iam workload-identity-pools providers create-oidc \u003cvar translate=\"no\"\u003ePROVIDER_ID\u003c/var\u003e \\\n --location=global \\\n --workload-identity-pool=\u003cvar translate=\"no\"\u003eWIP_ID\u003c/var\u003e \\\n --display-name=\"\u003cvar translate=\"no\"\u003ePROVIDER_DISPLAY_NAME\u003c/var\u003e\" \\\n --description=\"\u003cvar translate=\"no\"\u003ePROVIDER_DESCRIPTION\u003c/var\u003e\" \\\n --attribute-mapping=\"google.subject=assertion.sub,google.groups=[\\\"\u003cvar translate=\"no\"\u003ePROVIDER_ID\u003c/var\u003e\\\"]\" \\\n --attribute-condition=\"assertion.swname == 'CONFIDENTIAL_SPACE' &&\n 'STABLE' in assertion.submods.confidential_space.support_attributes &&\n ['cfm-services@admcloud-cfm-services.iam.gserviceaccount.com'].exists(\n a, a in assertion.google_service_accounts) &&\n 'ECDSA_P256_SHA256:6b1f357b59e9407fb017ca0e3e783b2bd5acbfea6c83dd82971a4150df5b25f9'\n in assertion.submods.container.image_signatures.map(sig, sig.signature_algorithm+':'+sig.key_id)\" \\\n --issuer-uri=\"https://confidentialcomputing.googleapis.com\" \\\n --allowed-audiences=\"https://sts.googleapis.com\"\n\n3. Grant the key decrypter role to the WIP provider.\n\n # Grants the role to the WIP provider.\n gcloud kms keys add-iam-policy-binding \u003cvar translate=\"no\"\u003eKEY_NAME\u003c/var\u003e \\\n --keyring \u003cvar translate=\"no\"\u003eKEY_RING_NAME\u003c/var\u003e \\\n --location \u003cvar translate=\"no\"\u003eKEY_RING_LOCATION\u003c/var\u003e \\\n --member \"principalSet://iam.googleapis.com/projects/\u003cvar translate=\"no\"\u003ePROJECT_ID\u003c/var\u003e/locations/global/workloadIdentityPools/\u003cvar translate=\"no\"\u003eWIP_ID\u003c/var\u003e/group/\u003cvar translate=\"no\"\u003ePROVIDER_ID\u003c/var\u003e\" \\\n --role \"roles/cloudkms.cryptoKeyDecrypter\"\n\n4. If you want to encrypt [event data](/data-manager/api/get-started/quickstart/send-events) for offline conversions and\n enhanced conversions for leads, grant the key decrypter role to the Google\n\n service account `datamanager-api@datamanager-ga.iam.gserviceaccount.com`.\n\n # Grants the role to the Google service account.\n gcloud kms keys add-iam-policy-binding \u003cvar translate=\"no\"\u003eKEY_NAME\u003c/var\u003e \\\n --keyring \u003cvar translate=\"no\"\u003eKEY_RING_NAME\u003c/var\u003e \\\n --location \u003cvar translate=\"no\"\u003eKEY_RING_LOCATION\u003c/var\u003e \\\n --member \"serviceAccount:datamanager-api@datamanager-ga.iam.gserviceaccount.com\" \\\n --role \"roles/cloudkms.cryptoKeyDecrypter\"\n\n \u003cbr /\u003e\n\nEncrypt data\n------------\n\nEncryption in the Data Manager API requires a data encryption key (DEK). A DEK is a\nsymmetric key that you use to encrypt data. Your DEK is encrypted using\nyour Google Cloud KMS key. You send the encrypted DEK as part of the request.\n\nTo prepare the data in the request for encryption, follow the same [formatting\nand hashing guidelines](/data-manager/api/get-started/formatting) you'd use for unencrypted data.\n\nDon't encrypt unhashed values. For example, the `region_code` or `postal_code`\nof an [`AddressInfo`](/data-manager/api/reference/rpc/google.ads.datamanager.v1#addressinfo).\n\nOnce the data for each field is formatted and hashed, encrypt the hashed value\nusing the following steps:\n\n1. Encode the hash bytes using Base64 encoding.\n2. Encrypt the Base64-encoded hash using your DEK.\n3. Encode the output from the encryption process using either hex or Base64 encoding.\n4. Use the encoded value for the field.\n5. Set the [`encryption_info`](/data-manager/api/reference/rpc/google.ads.datamanager.v1#encryptioninfo) and [`encoding`](/data-manager/api/reference/rpc/google.ads.datamanager.v1#encoding) on the request.\n\n| **Tip:** We recommend using [Tink](/tink) to implement encryption. Tink helps users without a cryptography background safely implement common cryptographic tasks.\n\nTo complete the last step, modify the\n[`IngestAudienceMembersRequest`](/data-manager/api/reference/rpc/google.ads.datamanager.v1#ingestaudiencemembersrequest) or\n[`IngestEventsRequest`](/data-manager/api/reference/rpc/google.ads.datamanager.v1#ingesteventsrequest)\nto indicate you encrypted\nyour data:\n\n- Set the `encryption_info` field.\n- Set the `encoding` field to the encoding used to encode the encrypted field values.\n\nHere's a snippet of a request with the encryption and encoding fields set: \n\n {\n ...\n \"encryptionInfo\": {\n \"gcpWrappedKeyInfo\": {\n \"kekUri\": \"gcp-kms://projects/\u003cvar translate=\"no\"\u003ePROJECT_ID\u003c/var\u003e/locations/\u003cvar translate=\"no\"\u003eKEY_RING_LOCATION\u003c/var\u003e/keyRings/\u003cvar translate=\"no\"\u003eKEY_RING_NAME\u003c/var\u003e/cryptoKeys/\u003cvar translate=\"no\"\u003eKEY_NAME\u003c/var\u003e\",\n \"wipProvider\": \"projects/\u003cvar translate=\"no\"\u003ePROJECT_ID\u003c/var\u003e/locations/global/workloadIdentityPools/\u003cvar translate=\"no\"\u003eWIP_ID\u003c/var\u003e/providers/\u003cvar translate=\"no\"\u003ePROVIDER_ID\u003c/var\u003e\",\n \"keyType\": \"XCHACHA20_POLY1305\",\n \"encryptedDek\": \"\u003cvar translate=\"no\"\u003eENCRYPTED_DEK\u003c/var\u003e\"\n }\n },\n \"encoding\": \"\u003cvar label=\"encoding (HEX or BASE64)\" translate=\"no\"\u003eENCODING\u003c/var\u003e\"\n }\n\nTo use the Data Manager API [library and\nutilities](/data-manager/api/get-started/set-up-access) to construct and send a request,\nsee the `IngestAudienceMembersWithEncryption` code sample for Java or the\n`ingest_audience_members_with_encryption` code sample for Python."]]