Skip to content

Commit 8e62682

Browse files
author
Chris Cho
authored
DOCSP-13039: Use Google Cloud KMS with Java (#693)
* DOCSP-13038: update CSFLE KMS guide for Python and GCP
1 parent 20938d2 commit 8e62682

File tree

2 files changed

+168
-112
lines changed

2 files changed

+168
-112
lines changed

source/includes/steps-fle-convert-to-a-remote-master-key-azure.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ content: |
4646
master key directly from the client application. Instead, it retrieves
4747
the key using your Azure credentials and the key vault details.
4848
49-
Configure your client application with the following authorization
49+
Configure your client application with the following authentication
5050
credentials:
5151
5252
.. list-table::
@@ -184,8 +184,8 @@ content: |
184184
- Yes
185185
- URL of the key vault. E.g. myVaultName.vault.azure.net
186186
187-
Once you have the required information, run the following code to
188-
generate the new data encryption key:
187+
Once you have the required information, update and run the following code
188+
to generate a new data encryption key:
189189
190190
.. tabs-drivers::
191191

source/includes/steps-fle-convert-to-a-remote-master-key-gcp.yaml

Lines changed: 165 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,91 @@
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
33
content: |
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
---
1517
title: Create the Master Key
16-
ref: create-the-master-key
18+
ref: create-the-master-key-gcp
1719
content: |
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
4157
content: |
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
---
94136
title: Create a New Data Encryption Key
95-
ref: create-a-new-data-key
137+
ref: create-a-new-data-key-gcp
96138
content: |
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
---
193249
title: Update the Automatic Encryption JSON Schema
194-
ref: update-the-json-schema
250+
ref: update-the-json-schema-gcp
195251
content: |
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

Comments
 (0)