1- title : Create an AWS IAM User  
2- ref : create-an-aws-iam-user  
1+ title : Create a GCP Service Account  
2+ ref : create-a-gcp-service-account  
33content : | 
4-   Create a new programmatic IAM user in the AWS management console. 
5-   CSFLE-enabled clients authenticate with AWS KMS using the IAM user to 
6-   encrypt and decrypt the remote master key. The IAM user must be granted 
7-   full ``List`` and ``Read`` permissions for the KMS service. 
84
9-   .. note:: Client IAM User Credentials 
5+   Create a service account for your client application by following the 
6+   official Google documentation on 
7+   `Creating and managing a service account <https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating>`__. 
8+ 
9+   After you create the service account, locate and record the following 
10+   authentication settings for use in a later step: 
11+ 
12+   - **email** 
13+   - **privateKey** (this value is only returned when you create the account) 
14+   - **endpoint** 
1015
11-      The CSFLE-enabled client uses the IAM User's :guilabel:`Access Key 
12-      ID` and :guilabel:`Secret Access Key` as configuration values. Take 
13-      note of these and reference them when we update the client. 
1416 ---
1517title : Create the Master Key 
16- ref : create-the-master-key 
18+ ref : create-the-master-key-gcp  
1719content : | 
1820
19-   The following diagram shows how  the **master key** is created and stored  
20-   when using  a KMS provider: 
21+   The following diagram shows the creation and storage of a   **master key** 
22+   on  a KMS provider: 
2123
2224  .. image:: /figures/CSFLE_Master_Key_KMS.png 
2325     :alt: Diagram that describes creating a master key when using a KMS provider 
2426
25-   In AWS management console, create a new symmetric master key in the KMS 
26-   section. Choose a name and description that helps you identify it; these 
27-   fields do not affect the functionality or configuration. 
27+   Create a **symmetric key** using the official Google Cloud 
28+   `Creating symmetric keys guide <https://cloud.google.com/kms/docs/creating-keys>`__. 
29+   This is your master key which you can access from your application. 
30+ 
31+   .. note:: 
32+ 
33+      If you rotate the key, either by specifying a date or manually, the 
34+     provider changes the content of the master key. To transition 
35+     to the new key: 
2836
29-   In the :guilabel:`Usage Permissions` step of the key generation 
30-   process, add the full KMS ``List`` and ``Read`` permissions to the IAM 
31-   user you created in the previous step. This authorizes the user to encrypt 
32-   and decrypt the new master key. 
37+      1. Decrypt and save the data using the original data encryption key. 
38+      #. Generate a new data encryption key with the new master key. 
39+      #. Update the ``keyVersion`` parameter to the latest version of the master key. 
40+      #. Re-encrypt the data using the new data encryption key. 
41+ 
42+   Make sure your application has appropriate roles to encrypt and decrypt 
43+   using the key. For example, the 
44+   `roles/cloudkms.cryptoKeyEncrypterDecrypter <https://cloud.google.com/kms/docs/reference/permissions-and-roles>`__ 
45+   role has permissions to both encrypt and decrypt keys. 
3346
3447  .. important:: 
3548
36-      The new client IAM User *should not* have administrative permissions 
37-      for the master key. 
49+      The client application *should not* have administrative permissions 
50+      for the master key. We recommend that you follow the 
51+      `principle of least privilege <https://en.wikipedia.org/wiki/Principle_of_least_privilege>`__ 
52+      to keep your data secure. 
53+ 
3854 ---
39- title : Specify the AWS KMS Provider  Credentials 
40- ref : specify-the-aws -kms-provider-credentials 
55+ title : Specify your Google Cloud KMS  Credentials 
56+ ref : specify-your-gcp -kms-provider-credentials 
4157content : | 
42-   Unlike the local key provider, the AWS KMS provider  does not read 
58+   Unlike the local key provider, the Google Cloud KMS  does not read 
4359  the master key directly from the client application. Instead, 
44-   it accepts the :guilabel:`Access Key ID` and :guilabel:`Secret Access 
45-   Key` configurations that point to the master key. The IAM user must have 
46-   the permissions set up in the previous step in order for the client to 
47-   use the KMS to encrypt and decrypt data encryption keys. 
60+   it retrieves the key using your service client credentials and key 
61+   details. 
62+ 
63+   Configure your client application with the following authentication 
64+   credentials: 
65+ 
66+   .. list-table:: 
67+      :header-rows: 1 
68+      :stub-columns: 1 
69+ 
70+      * - Field 
71+        - Required 
72+        - Description 
73+ 
74+      * - email 
75+        - Yes 
76+        - Identifies your service account email address. 
77+ 
78+      * - privateKey 
79+        - Yes 
80+        - Identifies your service account private key in either 
81+          `base64 string <https://en.wikipedia.org/wiki/Base64>`__ or 
82+          :manual:`Binary subtype 0 <reference/mongodb-extended-json/#bson.Binary>` 
83+          format. 
84+ 
85+      * - endpoint 
86+        - No 
87+        - Specifies a hostname and port number for the authentication server. 
88+          Defaults to oauth2.googleapis.com. 
4889
4990  Update the KMS Provider configuration in your CSFLE-enabled client 
5091  creation code: 
@@ -55,103 +96,127 @@ content: |
5596        :tabid: java-sync 
5697
5798        .. code-block:: java 
58-            :emphasize-lines: 7-9, 11 
5999
60-            BsonString masterKeyRegion = new BsonString("<Master Key AWS Region>"); // e.g. "us-east-2" 
61-            BsonString awsAccessKeyId = new BsonString("<IAM User Access Key ID>"); 
62-            BsonString awsSecretAccessKey = new BsonString("<IAM User Secret Access Key>"); 
63100           Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); 
64101           Map<String, Object> providerDetails = new HashMap<String, Object>(); 
65102
66-            providerDetails.put("accessKeyId", awsAccessKeyId); 
67-            providerDetails.put("secretAccessKey", awsSecretAccessKey); 
68-            providerDetails.put("region", masterKeyRegion); 
103+            providerDetails.put("email", new BsonString("<GCP service account email>")); 
104+            providerDetails.put("privateKey", new BsonString("<GCP service account private key>")); 
105+            providerDetails.put("endpoint", new BsonString("<GCP authentication endpoint>")); 
106+ 
107+            kmsProviders.put("gcp", providerDetails); 
69108
70-            kmsProviders.put("aws", providerDetails); 
71109     .. tab:: 
72110        :tabid: nodejs 
73111
74112        .. code-block:: javascript 
75113
114+            // TODO: check correctness 
76115           kmsProviders = { 
77-              aws: { 
78-                accessKeyId: '<IAM User Access Key ID>', 
79-                secretAccessKey: '<IAM User Secret Access Key>', 
116+              gcp: { 
117+                email: '<GCP service account email>', 
118+                privateKey: '<GCP service account private key>', 
119+                endpoint: '<GCP authentication endpoint>', 
80120             } 
81121           } 
122+ 
82123     .. tab:: 
83124        :tabid: python 
84125
85126        .. code-block:: python 
86127
87-            kms_providers = { 
88-                "aws": { 
89-                    "accessKeyId": "<IAM User Access Key ID>", 
90-                    "secretAccessKey": "<IAM User Secret Access Key>" 
128+            kms_provider = { 
129+                "gcp": { 
130+                    "email": "<GCP service account email>", 
131+                    "privateKey": "<GCP service account private key>", 
132+                    "endpoint": "<GCP authentication endpoint>", 
91133               } 
92134           } 
93135 ---
94136title : Create a New Data Encryption Key 
95- ref : create-a-new-data-key 
137+ ref : create-a-new-data-key-gcp  
96138content : | 
97-   The following diagram shows how the **customer master key** is created and 
98-   stored when using a KMS provider: 
139+   Generate a new **data encryption key** using the **master key** in the 
140+   remote KMS. The following diagram shows the requests you make from the 
141+   client application to create and store a new data encryption key: 
99142
100143  .. image:: /figures/CSFLE_Data_Key_KMS.png 
101144     :alt: Diagram that describes creating a data encryption key when using a KMS provider 
102145
103-   You must generate a new **data encryption key** using the **master key** 
104-   in the remote KMS. The original data encryption key was encrypted by 
105-   your locally-managed master key. 
146+   Provide your client with the following information to access the master key: 
147+ 
148+   .. list-table:: 
149+      :header-rows: 1 
150+      :stub-columns: 1 
106151
107-   Specify the AWS region and `Amazon Resource Number 
108-   <https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn>`_ 
109-   (ARN) of the new CMK in the CSFLE-enabled client settings. Use the client 
110-   to create a new data encryption key as follows: 
152+      * - Field 
153+        - Required 
154+        - Description 
111155
112-   Once you have the required information, run the following code to 
113-   generate the new data encryption key: 
156+      * - projectId 
157+        - Yes 
158+        - Identifier for your project in which you created the key. 
159+ 
160+      * - location 
161+        - Yes 
162+        - Region specified for your key. 
163+ 
164+      * - keyRing 
165+        - Yes 
166+        - Identifier for the group of keys your key belongs to. 
167+ 
168+      * - keyName 
169+        - Yes 
170+        - Identifier for the symmetric master key. 
171+ 
172+      * - keyVersion 
173+        - No 
174+        - Specifies the version of the named key. If not specified, the default 
175+          version of the key is used. 
176+ 
177+      * - endpoint 
178+        - No 
179+        - Specifies the host and optional port of the Cloud KMS. The default 
180+          is ``cloudkms.googleapis.com``. 
181+ 
182+   Once you have the required information, update and run the following code 
183+   to generate a new data encryption key: 
114184
115185  .. tabs-drivers:: 
116186
117187     .. tab:: 
118188        :tabid: java-sync 
119189
190+         In ``CSFLEHelpers.java``, update your call to 
191+         ``DataKeyOptions.masterKey()`` to include your master key data: 
192+ 
120193        .. code-block:: Java 
121-            :emphasize-lines: 9-14, 16-17 
122- 
123-            ClientEncryption clientEncryption = ClientEncryptions.create(ClientEncryptionSettings.builder() 
124-                .keyVaultMongoClientSettings(MongoClientSettings.builder() 
125-                    .applyConnectionString(new ConnectionString("mongodb://localhost:27017")) 
126-                    .build()) 
127-                .keyVaultNamespace(keyVaultNamespace) 
128-                .kmsProviders(kmsProviders) 
129-                .build()); 
130- 
131-            BsonString masterKeyRegion = new BsonString("<Master Key AWS Region>"); // e.g. "us-east-2" 
132-            BsonString masterKeyArn = new BsonString("<Master Key ARN>"); // e.g. "arn:aws:kms:us-east-2:111122223333:alias/test-key" 
194+ 
133195           DataKeyOptions dataKeyOptions = new DataKeyOptions().masterKey( 
134196               new BsonDocument() 
135-                    .append("region", masterKeyRegion) 
136-                    .append("key", masterKeyArn)); 
137- 
138-            BsonBinary dataKeyId = clientEncryption.createDataKey("aws", dataKeyOptions); 
139-            String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData()); 
140- 
141-            System.out.println("DataKeyId [base64]: " + base64DataKeyId); 
197+                    .append("provider", "gcp") 
198+                    .append("projectId", "<GCP project identifier>") 
199+                    .append("location", "<GCP region>") 
200+                    .append("keyRing", "<GCP key ring name>") 
201+                    .append("keyVersion", "<GCP key version>") 
202+                    .append("endpoint", "<GCP KMS API endpoint>")); 
203+ 
204+            BsonBinary dataKeyId = clientEncryption.createDataKey("gcp", dataKeyOptions); 
142205     .. tab:: 
143206        :tabid: nodejs 
144207
145208        .. code-block:: javascript 
146209
147-            const encryption = new ClientEncryption(client, { 
148-                keyVaultNamespace, 
149-                kmsProviders 
150-            }); 
151-            const key = await encryption.createDataKey('aws', { 
210+            // TODO: check correctness 
211+            const key = await encryption.createDataKey('gcp', { 
152212              masterKey: { 
153-                 key: '<Master Key ARN>', // e.g. 'arn:aws:kms:us-east-2:111122223333:alias/test-key' 
154-                 region: '<Master Key AWS Region>', // e.g. 'us-east-1' 
213+                 provider: 'gcp', 
214+                 projectId: '<GCP project identifier>', 
215+                 location: '<GCP region>', 
216+                 keyRing: '<GCP key ring name>', 
217+                 keyName: '<GCP key name>', 
218+                 keyVersion: '<GCP key version>', 
219+                 endpoint: '<GCP KMS API endpoint>', 
155220              } 
156221           }); 
157222
@@ -160,38 +225,29 @@ content: |
160225     .. tab:: 
161226        :tabid: python 
162227
228+         In ``app.py``, define the following dictionary to pass to your call to 
229+         ``create_data_key()``: 
230+ 
163231        .. code-block:: python 
164232
165-            import pymongo 
166-            from pymongo import MongoClient 
167-            from pymongo.encryption_options import AutoEncryptionOpts 
168-            from bson.binary import STANDARD 
169-            from bson.codec_options import CodecOptions 
170- 
171-            connection_string = "mongodb://localhost:27017" 
172-            key_vault_namespace = "encryption.__keyVault" 
173- 
174-            fle_opts = AutoEncryptionOpts( 
175-               kms_providers, # pass in the kms_providers from the previous step 
176-               key_vault_namespace 
177-            ) 
178- 
179-            client_encryption = pymongo.encryption.ClientEncryption( 
180-               { 
181-                 "aws": { 
182-                   "accessKeyId": "<IAM User Access Key ID>", 
183-                   "secretAccessKey": "<IAM User Secret Access Key>" 
184-                 } 
185-               }, 
186-               key_vault_namespace, 
187-               client, 
188-               CodecOptions(uuid_representation=STANDARD) 
189-            ) 
190-            data_key_id = client_encryption.create_data_key("aws") 
233+            master_key = { 
234+                 "provider": "gcp", 
235+                 "projectId": "<GCP project identifier>", 
236+                 "location": "<GCP region>", 
237+                 "keyRing": "<GCP key ring name>", 
238+                 "keyName": "<GCP key name>", 
239+                 "keyVersion": "<GCP key version>", 
240+                 "endpoint": "<GCP KMS API endpoint>", 
241+            } 
242+ 
243+         .. note:: 
244+ 
245+            To use Google Cloud KMS, you must use `pymongocrypt <https://pypi.org/project/pymongocrypt/>`__ 
246+            version 1.1 or later in your application's environment. 
191247
192248 ---
193249title : Update the Automatic Encryption JSON Schema 
194- ref : update-the-json-schema 
250+ ref : update-the-json-schema-gcp  
195251content : | 
196252  If you embedded the key id of your data encryption key in your 
197253  automatic encryption rules, you will need to update the :ref:`JSON 
0 commit comments