@@ -60,7 +60,210 @@ Convert to a Remote Master Key
6060This following steps explain the setup and updates necessary to move from
6161a local key provider to AWS KMS.
6262
63- .. include:: /includes/steps/fle-convert-to-a-remote-master-key.rst
63+ .. _create-an-aws-iam-user:
64+
65+ Step 1: Create an AWS IAM User
66+ ------------------------------
67+
68+ Create a new programmatic IAM user in the AWS management console.
69+ CSFLE-enabled clients authenticate with AWS KMS using the IAM user to
70+ encrypt and decrypt the remote master key. The IAM user must be granted
71+ full ``List`` and ``Read`` permissions for the KMS service.
72+
73+ .. note:: Client IAM User Credentials
74+
75+ The CSFLE-enabled client uses the IAM User's :guilabel:`Access Key
76+ ID` and :guilabel:`Secret Access Key` as configuration values. Take
77+ note of these and reference them when we update the client.
78+
79+ .. _create-the-master-key:
80+
81+ Step 2: Create the Master Key
82+ -----------------------------
83+
84+ The following diagram shows how the **master key** is created and stored
85+ when using a KMS provider:
86+
87+ .. image:: /figures/CSFLE_Master_Key_KMS.png
88+ :alt: Diagram that describes creating a master key when using a KMS provider
89+
90+ In AWS management console, create a new symmetric master key in the KMS
91+ section. Choose a name and description that helps you identify it; these
92+ fields do not affect the functionality or configuration.
93+
94+ In the :guilabel:`Usage Permissions` step of the key generation
95+ process, add the full KMS ``List`` and ``Read`` permissions to the IAM
96+ user you created in the previous step. This authorizes the user to encrypt
97+ and decrypt the new master key.
98+
99+ .. important::
100+
101+ The new client IAM User *should not* have administrative permissions
102+ for the master key.
103+
104+ .. _specify-the-aws-kms-provider-credentials:
105+
106+ Step 3: Specify the AWS KMS Provider Credentials
107+ ------------------------------------------------
108+
109+ Unlike the local key provider, the AWS KMS provider does not read
110+ the master key directly from the client application. Instead,
111+ it accepts the :guilabel:`Access Key ID` and :guilabel:`Secret Access
112+ Key` configurations that point to the master key. The IAM user must have
113+ the permissions set up in the previous step in order for the client to
114+ use the KMS to encrypt and decrypt data encryption keys.
115+
116+ Update the KMS Provider configuration in your CSFLE-enabled client
117+ creation code:
118+
119+ .. tabs-drivers::
120+
121+ .. tab::
122+ :tabid: java-sync
123+
124+ .. code-block:: java
125+
126+ BsonString masterKeyRegion = new BsonString("<Master Key AWS Region>"); // e.g. "us-east-2"
127+ BsonString awsAccessKeyId = new BsonString("<IAM User Access Key ID>");
128+ BsonString awsSecretAccessKey = new BsonString("<IAM User Secret Access Key>");
129+ Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
130+ Map<String, Object> providerDetails = new HashMap<String, Object>();
131+
132+ providerDetails.put("accessKeyId", awsAccessKeyId);
133+ providerDetails.put("secretAccessKey", awsSecretAccessKey);
134+ providerDetails.put("region", masterKeyRegion);
135+
136+ kmsProviders.put("aws", providerDetails);
137+ .. tab::
138+ :tabid: nodejs
139+
140+ .. code-block:: javascript
141+
142+ kmsProviders = {
143+ aws: {
144+ accessKeyId: '<IAM User Access Key ID>',
145+ secretAccessKey: '<IAM User Secret Access Key>',
146+ }
147+ }
148+ .. tab::
149+ :tabid: python
150+
151+ .. code-block:: python
152+
153+ kms_providers = {
154+ "aws": {
155+ "accessKeyId": "<IAM User Access Key ID>",
156+ "secretAccessKey": "<IAM User Secret Access Key>"
157+ }
158+ }
159+
160+ .. _create-a-new-data-key:
161+
162+ Step 4: Create a New Data Encryption Key
163+ ----------------------------------------
164+
165+ The following diagram shows how the **customer master key** is created and
166+ stored when using a KMS provider:
167+
168+ .. image:: /figures/CSFLE_Data_Key_KMS.png
169+ :alt: Diagram that describes creating a data encryption key when using a KMS provider
170+
171+ You must generate a new **data encryption key** using the **master key**
172+ in the remote KMS. The original data encryption key was encrypted by
173+ your locally-managed master key.
174+
175+ Specify the AWS region and `Amazon Resource Number
176+ <https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn>`_
177+ (ARN) of the new CMK in the CSFLE-enabled client settings. Use the client
178+ to create a new data encryption key as follows:
179+
180+ Once you have the required information, run the following code to
181+ generate the new data encryption key:
182+
183+ .. tabs-drivers::
184+
185+ .. tab::
186+ :tabid: java-sync
187+
188+ .. code-block:: Java
189+
190+ ClientEncryption clientEncryption = ClientEncryptions.create(ClientEncryptionSettings.builder()
191+ .keyVaultMongoClientSettings(MongoClientSettings.builder()
192+ .applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
193+ .build())
194+ .keyVaultNamespace(keyVaultNamespace)
195+ .kmsProviders(kmsProviders)
196+ .build());
197+
198+ BsonString masterKeyRegion = new BsonString("<Master Key AWS Region>"); // e.g. "us-east-2"
199+ BsonString masterKeyArn = new BsonString("<Master Key ARN>"); // e.g. "arn:aws:kms:us-east-2:111122223333:alias/test-key"
200+ DataKeyOptions dataKeyOptions = new DataKeyOptions().masterKey(
201+ new BsonDocument()
202+ .append("region", masterKeyRegion)
203+ .append("key", masterKeyArn));
204+
205+ BsonBinary dataKeyId = clientEncryption.createDataKey("aws", dataKeyOptions);
206+ String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
207+
208+ System.out.println("DataKeyId [base64]: " + base64DataKeyId);
209+ .. tab::
210+ :tabid: nodejs
211+
212+ .. code-block:: javascript
213+
214+ const encryption = new ClientEncryption(client, {
215+ keyVaultNamespace,
216+ kmsProviders
217+ });
218+ const key = await encryption.createDataKey('aws', {
219+ masterKey: {
220+ key: '<Master Key ARN>', // e.g. 'arn:aws:kms:us-east-2:111122223333:alias/test-key'
221+ region: '<Master Key AWS Region>', // e.g. 'us-east-1'
222+ }
223+ });
224+
225+ const base64DataKeyId = key.toString('base64');
226+ console.log('DataKeyId [base64]: ', base64DataKeyId);
227+ .. tab::
228+ :tabid: python
229+
230+ .. code-block:: python
231+
232+ import pymongo
233+ from pymongo import MongoClient
234+ from pymongo.encryption_options import AutoEncryptionOpts
235+ from bson.binary import STANDARD
236+ from bson.codec_options import CodecOptions
237+
238+ connection_string = "mongodb://localhost:27017"
239+ key_vault_namespace = "encryption.__keyVault"
240+
241+ fle_opts = AutoEncryptionOpts(
242+ kms_providers, # pass in the kms_providers from the previous step
243+ key_vault_namespace
244+ )
245+
246+ client_encryption = pymongo.encryption.ClientEncryption(
247+ {
248+ "aws": {
249+ "accessKeyId": "<IAM User Access Key ID>",
250+ "secretAccessKey": "<IAM User Secret Access Key>"
251+ }
252+ },
253+ key_vault_namespace,
254+ client,
255+ CodecOptions(uuid_representation=STANDARD)
256+ )
257+ data_key_id = client_encryption.create_data_key("aws")
258+
259+ .. _update-the-json-schema:
260+
261+ Step 5: Update the Automatic Encryption JSON Schema
262+ ---------------------------------------------------
263+
264+ If you embedded the key id of your data encryption key in your
265+ automatic encryption rules, you will need to update the :ref:`JSON
266+ Schema <fle-define-a-json-schema>` with the new data encryption key id.
64267
65268For more information on client-side field level encryption in MongoDB,
66269check out the reference docs in the server manual:
0 commit comments