-
Notifications
You must be signed in to change notification settings - Fork 245
/
Copy pathclient-side-encryption.md
2526 lines (1830 loc) · 123 KB
/
client-side-encryption.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Client Side Encryption
- Status: Accepted
- Minimum Server Version: 4.2 (CSFLE), 7.0 (QE)
- Version: 1.14.0
______________________________________________________________________
## Abstract
MongoDB 4.2 introduced support for client side encryption, guaranteeing that sensitive data can only be encrypted and
decrypted with access to both MongoDB and a separate key management provider (supporting AWS, Azure, GCP, a local
provider, and KMIP). Once enabled, data can be seamlessly encrypted and decrypted with minimal application code changes.
7.0 introduced the next generation of client side encryption based on a Structured Encryption framework which allows
expressive encrypted search operations. This spec covers both capabilities - 1st generation, "Client Side Field Level
Encryption" and generation 2, "Queryable Encryption" - as the associated core cryptographic library and supporting
drivers share a common codebase.
### Naming
The public name of this feature is
[In-Use Encryption](https://www.mongodb.com/docs/manual/core/security-in-use-encryption/) and consists of:
- Client-Side Field Level Encryption (CSFLE).
- Queryable Encryption (QE).
Internally, In-Use Encryption is sometimes called Field Level Encryption (FLE). Internally, CSFLE is sometimes called
Client Side Encryption (like this specification). Internally, CSFLE and QE are sometimes called FLE1 and FLE2,
respectively.
### Server support history
MongoDB 4.2 added support for CSFLE. This includes `encrypt` in JSON Schema
([SERVER-38900](https://jira.mongodb.org/browse/SERVER-38900)) and [mongocryptd](#mongocryptd)
([SPM-1258](https://jira.mongodb.org/browse/SPM-1258)).
MongoDB 5.3 added the [crypt_shared](#crypt_shared) library ([SPM-2403](https://jira.mongodb.org/browse/SPM-2403)).
MongoDB 6.0 added unstable support for QE (QEv1) ([SPM-2463](https://jira.mongodb.org/browse/SPM-2463)). This includes
`queryType=equality`.
MongoDB 6.2 added unstable support for QE range queries ([SPM-2719](https://jira.mongodb.org/browse/SPM-2719)). This
includes `queryType=rangePreview`.
MongoDB 7.0 dropped QEv1 and added stable support of QE (QEv2) ([SPM-2972](https://jira.mongodb.org/browse/SPM-2972)).
QEv1 and QEv2 are incompatible.
MongoDB 8.0 dropped `queryType=rangePreview` and added `queryType=range`
([SPM-3583](https://jira.mongodb.org/browse/SPM-3583)).
## META
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
## Terms
**encrypted MongoClient**
A MongoClient with client side encryption enabled.
**data key**
A key used to encrypt and decrypt BSON values. Data keys are encrypted with a key management service (e.g. AWS KMS) and
stored within a document in the MongoDB key vault collection (see
[Key vault collection schema for data keys](#key-vault-collection-schema-for-data-keys) for a description of the data
key document). Therefore, a client needs access to both MongoDB and the external KMS service to utilize a data key.
**MongoDB key vault collection**
A MongoDB collection designated to contain data keys. This can either be co-located with the data-bearing cluster, or in
a separate external MongoDB cluster.
**Key Management Service (KMS)**
An external service providing fixed-size encryption/decryption. Only data keys are encrypted and decrypted with KMS.
**KMS providers**
A map of KMS providers to credentials. Configured client-side. Example:
```javascript
kms_providers = {
"aws": {
"accessKeyId": AWS_KEYID,
"secretAccessKey": AWS_SECRET,
},
"local": {
"key": LOCAL_KEK
},
}
```
**KMS provider**
A configured KMS. Identified by a key in the KMS providers map. The key has the form `<KMS provider type>` or
`<KMS provider type>:<KMS provider name>`. Examples: `aws` or `aws:myname`. In [libmongocrypt](#libmongocrypt), the key
is referred to as the KMS ID.
**KMS provider type**
The type of backing KMS. Identified by the string: `aws`, `azure`, `gcp`, `kmip`, or `local`.
**KMS provider name**
An optional name to identify a KMS provider. Enables configuring multiple KMS providers with the same KMS provider type
(e.g. `aws:name1` and `aws:name2` can refer to different AWS accounts).
**Master Key**
The underlying key the KMS service uses to encrypt and decrypt. See
[AWS KMS Concepts](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) for an AWS-specific
example (other KMS providers work similarly).
The master key is also sometimes referred to as a Customer Master Key (CMK).
**schema**
A MongoDB JSON Schema (either supplied by the server or client-side) which may include metadata about encrypted fields.
This is a JSON Schema based on draft 4 of the JSON Schema specification,
[as documented in the MongoDB manual.](https://www.mongodb.com/docs/manual/reference/operator/query/jsonSchema/).
**[libmongocrypt](#libmongocrypt)**
A library, written in C, that coordinates communication, does encryption/decryption, caches key and schemas.
[Located here](https://github.com/mongodb/libmongocrypt).
**[mongocryptd](#mongocryptd)**
A local process the driver communicates with to determine how to encrypt values in a command.
**[crypt_shared](#crypt_shared)**
This term, spelled in all-lowercase with an underscore, refers to the client-side field-level-encryption dynamic library
provided as part of a MongoDB Enterprise distribution. It replaces [mongocryptd](#mongocryptd) as the method of
[marking-up a database command for encryption](../bson-binary-encrypted/binary-encrypted.md#intent-to-encrypt).
See also:
- [Introduction on crypt_shared](#crypt_shared)
- [Enabling crypt_shared](#enabling-crypt_shared)
**ciphertext**
One of the data formats of [BSON binary encrypted](../bson-binary-encrypted/binary-encrypted.md), representing an
encoded BSON document containing encrypted ciphertext and metadata.
**Client-Side Field Level Encryption (CSFLE)**
CSFLE is the first version of In-Use Encryption. CSFLE is almost entirely client-side with the exception of server-side
JSON schema.
**Queryable Encryption (QE)**
Queryable Encryption the second version of In-Use Encryption. Data is encrypted client-side. Queryable Encryption
supports indexed encrypted fields, which are further processed server-side.
**In-Use Encryption**
Is an umbrella term describing the both CSFLE and Queryable Encryption.
**encryptedFields**
A BSON document describing the Queryable Encryption encrypted fields. This is analogous to the JSON Schema in FLE. The
following is an example encryptedFields in extended canonical JSON:
```javascript
{
"escCollection": "enxcol_.CollectionName.esc",
"ecocCollection": "enxcol_.CollectionName.ecoc",
"fields": [
{
"path": "firstName",
"keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }},
"bsonType": "string",
"queries": {"queryType": "equality"}
},
{
"path": "ssn",
"keyId": { "$binary": { "subType": "04", "base64": "BBBBBBBBBBBBBBBBBBBBBB==" }},
"bsonType": "string"
}
]
}
```
The acronyms within `encryptedFields` are defined as follows:
- ECOC: Encrypted Compaction Collection
- ESC: Encrypted State Collection
## Introduction
Client side encryption enables users to specify what fields in a collection must be encrypted, and the driver
automatically encrypts commands and decrypts results. Automatic encryption is enterprise only. But users can manually
encrypt and decrypt with a new ClientEncryption object.
Client side encryption requires MongoDB 4.2 compatible drivers, and is only supported against 4.2 or higher servers. See
[Why is a 4.2 server required?](#why-is-a-42-server-required).
The following shows basic usage of the new API.
```python
# The schema map identifies fields on collections that must undergo encryption.
schema_map = open("./schemas.json", "r").read()
# AWS KMS is used to decrypt data keys stored in the key vault collection.
aws_creds = open("./aws_credentials.json", "r").read()
# A client is configured for automatic encryption and decryption by passing
# AutoEncryptionOpts. Automatic encryption is an enterprise only feature.
opts = AutoEncryptionOpts(
kms_providers={"aws": aws_creds},
key_vault_namespace="db.datakeys",
schema_map=schema_map)
db = MongoClient(auto_encryption_opts=opts).db
# Commands are encrypted, as determined by the JSON Schema from the schema_map.
db.coll.insert_one({"ssn": "457-55-5462"})
# Replies are decrypted.
print(db.coll.find_one()) # { "ssn": "457-55-5462" } but stored and transported as ciphertext.
# A ClientEncryption object is used for explicit encryption, decryption, and creating data keys.
opts = ClientEncryptionOpts(kms_providers=kms, key_vault_namespace="db.datakeys")
clientencryption = ClientEncryption(client, opts)
# Use a ClientEncryption to create new data keys.
# The master key identifies the KMS key on AWS KMS to use for encrypting the data key.
master_key = open("./aws_masterkey.json", "r").read()
opts = DataKeyOpts (master_key=master_key)
created_key_id = clientencryption.create_data_key("aws", opts)
# Use a ClientEncryption to explicitly encrypt and decrypt.
opts = EncryptOpts(key_id=created_key_id,
algorithm="AEAD_AES_256_CBC_HMAC_SHA_512-Random")
encrypted = clientencryption.encrypt("secret text", opts)
# Decryption does not require the key ID or algorithm. The ciphertext indicates the key ID and algorithm used.
decrypted = clientencryption.decrypt(encrypted)
```
There are many moving parts to client side encryption with lots of similar sounding terms. Before proceeding to
implement the specification, the following background should provide some context.
The driver interacts with multiple components to implement client side encryption.

The driver communicates with…
- **MongoDB cluster** to get remote JSON Schemas.
- **MongoDB key vault collection** to get encrypted data keys and create new data keys.
- **A KMS Provider** to decrypt fetched data keys and encrypt new data keys.
- **mongocryptd** to ask what values in BSON commands must be encrypted (unless [crypt_shared](#crypt_shared) is in
use).
The MongoDB key vault may be the same as the MongoDB cluster. Users may choose to have data key stored on a separate
MongoDB cluster, or co-locate with their data.
### MongoDB Key Vault collection
The key vault collection is a special MongoDB collection containing key documents. See the appendix section
[Key vault collection schema for data keys](#key-vault-collection-schema-for-data-keys) for a description of the
documents.
The key material in the key vault collection is encrypted with a separate KMS service. Therefore, encryption and
decryption requires access to a MongoDB cluster and the KMS service.
### KMS Provider
A KMS provider (AWS KMS, Azure Key Vault, GCP KMS, the local provider, or KMIP) is used to decrypt data keys after
fetching from the MongoDB Key Vault, and encrypt newly created data keys. Refer to [KMSProviders](#kmsproviders) for the
shape of the KMS provider options.
### mongocryptd
`mongocryptd` is a singleton local process needed for auto-encryption when no [crypt_shared](#crypt_shared) library is
used. It speaks the MongoDB wire protocol and the driver uses [mongocryptd](#mongocryptd) by connecting with a
MongoClient. By default, if [crypt_shared](#crypt_shared) is unavailable, the driver should attempt to automatically
spawn [mongocryptd](#mongocryptd). If the MongoClient is configured with `extraOptions.mongocryptdBypassSpawn` set to
`true`, OR `bypassAutoEncryption` is set to `true`, OR `bypassQueryAnalysis` is set to `true` then the driver will not
attempt to spawn [mongocryptd](#mongocryptd).
The [mongocryptd](#mongocryptd) process is responsible for self terminating after idling for a time period. If
[extraOptions.cryptSharedLibRequired](#extraoptions.cryptsharedlibrequired) is set to `true`, the driver will not
connect to [mongocryptd](#mongocryptd) and instead rely on [crypt_shared](#crypt_shared) being available.
### crypt_shared
[crypt_shared](#crypt_shared) is a dynamically-loaded C++ library providing query analysis for auto-encryption. It
replaces [mongocryptd](#mongocryptd) for performing query analysis to -
[mark-up sensitive fields within a command](../bson-binary-encrypted/binary-encrypted.md#intent-to-encrypt).
Drivers are not required to load and interact with [crypt_shared](#crypt_shared) directly. Instead, they inform
[libmongocrypt](#libmongocrypt) where to find [crypt_shared](#crypt_shared) and [libmongocrypt](#libmongocrypt) will
handle [crypt_shared](#crypt_shared) communication automatically.
See also: [Enabling crypt_shared](#enabling-crypt_shared) for information on using enabling the
[crypt_shared](#crypt_shared) library.
### libmongocrypt
libmongocrypt is a C library providing crypto and coordination with external components.
[Located here](https://github.com/mongodb/libmongocrypt).
**libmongocrypt is responsible for…**
- orchestrating an internal state machine.
- asking the driver to perform I/O, then handling the responses.
- includes constructing KMS HTTP requests and parsing KMS responses.
- doing encryption and decryption.
- caching data keys.
- caching results of listCollections.
- creating key material.
**The driver is responsible for…**
- performing all I/O needed at every state:
- speaking to [mongocryptd](#mongocryptd) to mark commands (unless [crypt_shared](#crypt_shared) is used).
- fetching encrypted data keys from key vault collection (mongod).
- running listCollections on mongod.
- decrypting encrypted data keys with KMS over TLS.
- doing I/O asynchronously as needed.
See [Why require including a C library?](#why-require-including-a-c-library)
## User facing API
Drivers MUST NOT preclude future options from being added to any of the new interfaces.
Drivers MAY represent the options types in a way that is idiomatic to the driver or language. E.g. options MAY be a BSON
document or dictionary type. The driver MAY forego validating options and instead defer validation to the underlying
implementation.
Drivers MAY deviate the spelling of option names to conform to their language's naming conventions and implement options
in an idiomatic way (e.g. keyword arguments, builder classes, etc.).
Drivers MAY use a native UUID type in place of a parameter or return type specified as a BSON binary with subtype 0x04
as described in [Handling of Native UUID Types](../bson-binary-uuid/uuid.md).
### MongoClient Changes
<span id="MongoClient"></span>
```typescript
class MongoClient {
MongoClient(... autoEncryptionOpts: AutoEncryptionOpts);
// Implementation details.
private mongocrypt_t libmongocrypt_handle; // Handle to libmongocrypt.
private Optional<MongoClient> mongocryptd_client; // Client to mongocryptd.
private MongoClient keyvault_client; // Client used to run find on the key vault collection. This is either an external MongoClient, the parent MongoClient, or internal_client.
private MongoClient metadata_client; // Client used to run listCollections. This is either the parent MongoClient or internal_client.
private Optional<MongoClient> internal_client; // An internal MongoClient. Created if no external keyVaultClient was set, or if a metadataClient is needed
// Exposition-only, used for caching automatic Azure credentials. The cached credentials may be globally cached.
private cachedAzureAccessToken?: AzureAccessToken;
private azureAccessTokenExpireTime?: PointInTime;
}
```
<span id="AutoEncryptionOpts"></span>
```typescript
class AutoEncryptionOpts {
keyVaultClient: Optional<MongoClient>;
keyVaultNamespace: String;
kmsProviders: KMSProviders;
schemaMap: Optional<Map<String, Document>>; // Maps namespace to a local schema
bypassAutoEncryption: Optional<Boolean>; // Default false.
extraOptions: Optional<Map<String, Value>>;
tlsOptions?: KMSProvidersTLSOptions; // Maps KMS provider to TLS options.
encryptedFieldsMap: Optional<Map<String, Document>>; // Maps namespace to encryptedFields.
// bypassQueryAnalysis disables automatic analysis of outgoing commands.
// Set bypassQueryAnalysis to true to use explicit encryption on indexed fields
// without the MongoDB Enterprise Advanced licensed crypt_shared library.
bypassQueryAnalysis: Optional<Boolean>; // Default false.
keyExpirationMS: Optional<Uint64>; // Default 60000. 0 means "never expire".
}
```
A MongoClient can be configured to automatically encrypt collection commands and decrypt results.
Drivers MUST document that auto encryption is an enterprise-only feature and that auto encryption only occurs on
collection level operations by including the following in the driver documentation for AutoEncryptionOpts:
> Automatic encryption is an enterprise only feature that only applies to operations on a collection. Automatic
> encryption is not supported for operations on a database or view, and operations that are not bypassed will result in
> error (see [libmongocrypt: Auto Encryption Allow-List](#libmongocrypt-auto-encryption-allow-list)). To bypass
> automatic encryption for all operations, set bypassAutoEncryption=true in AutoEncryptionOpts.
Explicit encryption/decryption and automatic decryption is a community feature. A MongoClient configured with
bypassAutoEncryption=true will still automatically decrypt.
Drivers MUST document that auto encryption requires the authenticated user to have the listCollections privilege action
by including the following in the driver documentation for MongoClient:
> Automatic encryption requires the authenticated user to have the
> [listCollections privilege action](https://www.mongodb.com/docs/manual/reference/command/listCollections/#dbcmd.listCollections).
See
[Why is client side encryption configured on a MongoClient?](#why-is-client-side-encryption-configured-on-a-mongoclient)
#### keyVaultNamespace
The key vault collection namespace refers to a collection that contains all data keys used for encryption and decryption
(aka the key vault collection). Data keys are stored as documents in a special MongoDB collection. Data keys are
protected with encryption by a KMS provider (AWS KMS, Azure key vault, GCP KMS, a local master key, or KMIP).
#### keyVaultClient
The key vault collection is assumed to reside on the same MongoDB cluster as indicated by the connecting URI. But the
optional keyVaultClient can be used to route data key queries to a separate MongoDB cluster.
If a `keyVaultClient` is not passed, and the parent `MongoClient` is configured with a limited `maxPoolSize`, the
`keyVaultClient` is set to an internal `MongoClient`. See
[keyVaultClient, metadataClient, and the internal MongoClient](#keyvaultclient-metadataclient-and-the-internal-mongoclient)
for configuration behavior.
See
[What's the deal with metadataClient, keyVaultClient, and the internal client?](#whats-the-deal-with-metadataclient-keyvaultclient-and-the-internal-client)
#### keyVaultClient, metadataClient, and the internal MongoClient
The following pseudo-code describes the configuration behavior for the three `MongoClient` objects:
```python
def getOrCreateInternalClient (client, clientOpts):
if client.internalClient != None:
return client.internalClient
internalClientOpts = copy(clientOpts)
internalClientOpts.autoEncryptionOpts = None
internalClientOpts.minPoolSize = 0
client.internalClient = MongoClient (internalClientOpts)
return client.internalClient
def configureAutoEncryptionClients (client, clientOpts):
if clientOpts.autoEncryptionOpts.keyVaultClient != None:
client.keyVaultClient = clientOpts.autoEncryptionOpts.keyVaultClient
elif clientOpts.maxPoolSize == 0:
client.keyVaultClient = client
else:
client.keyVaultClient = getOrCreateInternalClient (client, clientOpts)
if clientOpts.autoEncryptionOpts.bypassAutomaticEncryption:
client.metadataClient = None
elif clientOpts.maxPoolSize == 0:
client.metadataClient = client
else:
client.metadataClient = getOrCreateInternalClient (client, clientOpts)
```
Configuring the internal `MongoClient` MUST match the parent `MongoClient`, except `minPoolSize` is set to `0` and
`AutoEncryptionOpts` is omitted. This includes copying the options and host information from the URI, and other non-URI
configuration (monitoring callbacks, stable API, etc.).
Drivers MUST document that an additional `MongoClient` may be created, using the following as a template:
> If a `MongoClient` with a limited connection pool size (i.e a non-zero `maxPoolSize`) is configured with
> `AutoEncryptionOpts`, a separate internal `MongoClient` is created if any of the following are true:
>
> - `AutoEncryptionOpts.keyVaultClient` is not passed.
> - `AutoEncryptionOpts.bypassAutomaticEncryption` is `false`.
>
> If an internal `MongoClient` is created, it is configured with the same options as the parent `MongoClient` except
> `minPoolSize` is set to `0` and `AutoEncryptionOpts` is omitted.
See
[What's the deal with metadataClient, keyVaultClient, and the internal client?](#whats-the-deal-with-metadataclient-keyvaultclient-and-the-internal-client)
<span id="GCPKMSOptions"></span> <span id="AWSKMSOptions"></span> <span id="KMSProvider"></span>
<span id="KMSProviders"></span> <span id="AzureAccessToken"></span> <span id="kmsproviders"></span>
#### kmsProviders
The `kmsProviders` property may be specified on [ClientEncryptionOpts](#ClientEncryptionOpts) or
[AutoEncryptionOpts](#AutoEncryptionOpts). Multiple KMS providers may be specified, each using a specific property on
the [KMSProviders](#kmsproviders) object. The options differ for each KMS provider type. The "local" KMS provider type
is configured with master key material. The external providers are configured with credentials to authenticate.
Throughout this document, the KMS provider is annotated as - `KMSProvider`, but this name is for *exposition only*:
drivers MUST accept arbitrary strings at runtime for forward-compatibility.
```typescript
interface KMSProviders {
aws?: AWSKMSOptions | { /* Empty (See "Automatic Credentials") */ };
azure?: AzureKMSOptions | { /* Empty (See "Automatic Credentials") */ };
gcp?: GCPKMSOptions | { /* Empty (See "Automatic Credentials") */ };
local?: LocalKMSOptions;
kmip?: KMIPKMSOptions;
// KMS providers may be specified with an optional name suffix separated by a colon.
// Named KMS providers do not support "Automatic Credentials".
// Note: the named KMS providers strings below are not valid Typescript regexes. They are intended for exposition only.
"^aws:[a-zA-Z0-9_]+$"?: AWSKMSOptions;
"^azure:[a-zA-Z0-9_]+$"?: AzureKMSOptions;
"^gcp:[a-zA-Z0-9_]+$"?: GCPKMSOptions;
"^local:[a-zA-Z0-9_]+$"?: LocalKMSOptions;
"^kmip:[a-zA-Z0-9_]+$"?: KMIPKMSOptions;
};
// KMSProvider is a string identifying a KMS provider. Note: For forward
// compatibility, any string should be accepted.
type KMSProvider = string;
interface AWSKMSOptions {
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string; // Required for temporary AWS credentials.
};
type AzureKMSOptions = AzureKMSCredentials | AzureAccessToken;
interface AzureKMSCredentials {
tenantId: string;
clientId: string;
clientSecret: string;
identityPlatformEndpoint?: string; // Defaults to login.microsoftonline.com
};
interface AzureAccessToken {
accessToken: string;
};
type GCPKMSOptions = GCPKMSCredentials | GCPKMSAccessToken
interface GCPKMSCredentials {
email: string;
privateKey: byte[] | string; // May be passed as a base64 encoded string.
endpoint?: string; // Defaults to oauth2.googleapis.com
};
interface GCPKMSAccessToken {
accessToken: string;
}
interface LocalKMSOptions {
key: byte[96] | string; // The master key used to encrypt/decrypt data keys. May be passed as a base64 encoded string.
};
interface KMIPKMSOptions {
endpoint: string;
};
```
The following shows an example object of `KMSProviders`:
```javascript
{
// Pass credentials for AWS:
"aws": { "accessKeyId": "foo", "secretAccessKey": "bar" },
// Use an empty document to enable "Automatic Credentials" for Azure:
"azure": {},
// Pass an access token for GCP:
"gcp": { "accessToken": "foo" },
// Pass a 96 byte base64 encoded string for the local KMS provider.
"local": { "key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" }
// Pass the endpoint for KMIP:
"kmip": { "endpoint": "localhost:5698" }
// Pass credentials for a different AWS account by appending a name.
// Note: credentials with a name do not support "Automatic Credentials".
"aws:name2": { "accessKeyId": "foo2", "secretAccessKey": "bar2" }
}
```
<span id="automatic-credentials"></span>
##### Automatic Credentials
Certain values of [KMSProviders](#kmsproviders) indicate a request by the user that the associated KMS providers should
be populated lazily on-demand. The driver MUST be able to populate the respective options object on-demand
if-and-only-if such respective credentials are needed. The request for KMS credentials will be indicated by
[libmongocrypt](#libmongocrypt) only once they are needed.
When such a state is detected, [libmongocrypt](#libmongocrypt) will call back to the driver by entering the
`MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS` state, upon which the driver should fill in the KMS options automatically.
Automatic credentials are only supported for the KMS provider types `aws`, `gcp`, and `azure`. KMS providers containing
a name (e.g. `aws:myname`) do not support automatic credentials. Attempting to configure a KMS provider with a name for
automatic credentials results in a runtime error from [libmongocrypt](#libmongocrypt). See
[Why do on-demand KMS credentials not support named KMS providers?](#why-do-on-demand-kms-credentials-not-support-named-kms-providers)
> [!NOTE]
> Drivers MUST NOT eagerly fill an empty KMS options property.
Once requested, drivers MUST create a new [KMSProviders](#kmsproviders) $P$ according to the following process:
1. Let $K$ be the [kmsProviders](#kmsproviders) value provided by the user as part of the original
[ClientEncryptionOpts](#ClientEncryptionOpts) or [AutoEncryptionOpts](#AutoEncryptionOpts).
2. Initialize $P$ to an empty [KMSProviders](#kmsproviders) object.
3. If $K$ contains an `aws` property, and that property is an empty map:
1. Attempt to obtain credentials $C$ from the environment using similar logic as is detailed in
[the obtaining-AWS-credentials section from the Driver Authentication specification](../auth/auth.md#obtaining-credentials),
but ignoring the case of loading the credentials from a URI
2. If credentials $C$ were successfully loaded, create a new [AWSKMSOptions](#AWSKMSOptions) map from $C$ and insert
that map onto $P$ as the `aws` property.
4. If $K$ contains an `gcp` property, and that property is an empty map:
1. Attempt to obtain credentials $C$ from the environment logic as is detailed in
[Obtaining GCP Credentials](#obtaining-gcp-credentials).
2. If credentials $C$ were successfully loaded, create a new [GCPKMSOptions](#GCPKMSOptions) map from $C$ and insert
that map onto $P$ as the `gcp` property.
5. If $K$ contains an `azure` property, and that property is an empty map:
1. If there is a `cachedAzureAccessToken` AND the duration until `azureAccessTokenExpireTime` is greater than one
minute, insert `cachedAzureAccessToken` as the `azure` property on $P$.
2. Otherwise:
1. Let $t_0$ be the current time.
2. Attempt to obtain an Azure VM Managed Identity Access Token $T$ as detailed in
[Obtaining an Access Token for Azure Key Vault](#obtaining-an-access-token-for-azure-key-vault).
3. If a token $T$ with expire duration $d\_{exp}$ were obtained successfully, create a new
[AzureAccessToken](#AzureAccessToken) object with $T$ as the `accessToken` property. Insert that
[AzureAccessToken](#AzureAccessToken) object into $P$ as the `azure` property. Record the generated
[AzureAccessToken](#AzureAccessToken) in `cachedAzureAccessToken`. Record the `azureAccessTokenExpireTime` as
$t_0 + d\_{exp}$.
6. Return $P$ as the additional KMS providers to [libmongocrypt](#libmongocrypt).
<span id="obtaining-gcp-credentials"></span>
##### Obtaining GCP Credentials
Set `HOST` to `metadata.google.internal`.
Send an HTTP request to the URL `http://<HOST>/computeMetadata/v1/instance/service-accounts/default/token` with the
header `Metadata-Flavor: Google`.
If the HTTP response code is not 200, return an error including the body of the HTTP response in the error message.
Parse the HTTP response body as JSON. If parsing fails, return an error including the body of the HTTP response in the
error message.
Check the parsed JSON for the field "access_token". If "access_token" is not present, return an error including the body
of the HTTP response in the error message.
Return "access_token" as the credential.
##### Obtaining an Access Token for Azure Key Vault
Virtual machines running on the Azure platform have one or more *Managed Identities* associated with them. From within
the VM, an identity can be used by obtaining an access token via HTTP from the *Azure Instance Metadata Service* (IMDS).
[See this documentation for more information](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http)
> [!NOTE]
> To optimize for testability, it is recommended to implement an isolated abstraction for communication with IMDS. This
> will aide in the implementation of the prose tests of the communication with an IMDS server.
The below steps should be taken:
1. Let $U$ be a new URL, initialized from the URL string `"http://169.254.169.254/metadata/identity/oauth2/token"`
2. Add a query parameter `api-version=2018-02-01` to $U$.
3. Add a query parameter `resource=https://vault.azure.net/` to $U$.
4. Prepare an HTTP GET request $Req$ based on $U$.
> [!NOTE]
> All query parameters on $U$ should be appropriately percent-encoded
5. Add HTTP headers `Metadata: true` and `Accept: application/json` to $Req$.
6. Issue $Req$ to the Azure IMDS server `169.254.169.254:80`. Let $Resp$ be the response from the server. If the HTTP
response is not completely received within ten seconds, consider the request to have timed out, and return an
error instead of an access token.
7. If $Resp\_{status} ≠ 200$, obtaining the access token has failed, and the HTTP response body of $Resp$ encodes
information about the error that occurred. Return an error including the HTTP response body instead of an access
token.
8. Otherwise, let $J$ be the JSON document encoded in the HTTP response body of $Resp$.
9. The result access token $T$ is given as the `access_token` string property of $J$. Return $T$ as the resulting
access token.
10. The resulting "expires in" duration $d\_{exp}$ is a count of seconds given as an ASCII-encoded integer string
`expires_in` property of $J$.
> [!NOTE]
> If JSON decoding of $Resp$ fails, or the `access_token` property is absent from $J$, this is a protocol error from
> IMDS. Indicate this error to the requester of the access token.
> [!NOTE]
> If an Azure VM has more than one managed identity, requesting an access token requires additional query parameters to
> disambiguate the request. For simplicity, these parameters are omitted, and only VMs that have a single managed
> identity are supported.
##### KMS provider TLS options
Drivers MUST provide TLS options to configure TLS connections KMS providers.
The TLS options SHOULD be consistent with the existing TLS options for MongoDB server TLS connections. The TLS options
MUST enable setting a custom client certificate, equivalent to the `tlsCertificateKeyFile` URI option.
Drivers SHOULD provide API that is consistent with configuring TLS options for MongoDB server TLS connections. New API
to support the TLS options MUST support future addition of KMS providers without requiring a driver API change. The
following is an example:
```typescript
class AutoEncryptionOpts {
// setTLSOptions accepts a map of KMS providers to TLSOptions.
// The TLSOptions apply to any TLS socket required to communicate
// with the KMS provider.
setTLSOptions (opts: KMSProvidersTLSOptions)
}
class ClientEncryptionOpts {
// setTLSOptions accepts a map of KMS providers to TLSOptions.
// The TLSOptions apply to any TLS socket required to communicate
// with the KMS provider.
setTLSOptions (opts: KMSProvidersTLSOptions)
}
```
Drivers MUST raise an error if the TLS options are set to disable TLS. The error MUST contain the message "TLS is
required".
Drivers SHOULD raise an error if insecure TLS options are set. The error MUST contain the message "Insecure TLS options
prohibited". This includes options equivalent to the following URI options:
- `tlsInsecure`
- `tlsAllowInvalidCertificates`
- `tlsAllowInvalidHostnames`
- `tlsDisableCertificateRevocationCheck`
Drivers MUST NOT raise an error if `tlsDisableOCSPEndpointCheck` is set. Setting `tlsDisableOCSPEndpointCheck` may
prevent operation errors when OCSP responders are unresponsive.
See the OCSP specification for a description of the default values of
[tlsDisableOCSPEndpointCheck](../ocsp-support/ocsp-support.md#tlsdisableocspendpointcheck) and
[tlsDisableCertificateRevocationCheck](../ocsp-support/ocsp-support.md#tlsdisablecertificaterevocationcheck) Drivers
MUST NOT modify the default value of `tlsDisableOCSPEndpointCheck` and `tlsDisableCertificateRevocationCheck` for KMS
TLS connections.
See [Why do KMS providers require TLS options?](#why-do-kms-providers-require-tls-options)
#### schemaMap
Automatic encryption is configured with an "encrypt" field in a collection's JSONSchema. By default, a collection's
JSONSchema is periodically polled with the listCollections command. But a JSONSchema may be specified locally with the
schemaMap option. Drivers MUST document that a local schema is more secure and MUST include the following in the driver
documentation for MongoClient:
> Supplying a schemaMap provides more security than relying on JSON Schemas obtained from the server. It protects
> against a malicious server advertising a false JSON Schema, which could trick the client into sending unencrypted data
> that should be encrypted.
Drivers MUST document that a local schema only applies to client side encryption, and specifying JSON Schema features
unrelated to encryption will result in error. Drivers MUST include the following in the driver documentation for
MongoClient:
> Schemas supplied in the schemaMap only apply to configuring automatic encryption for client side encryption. Other
> validation rules in the JSON schema will not be enforced by the driver and will result in an error.
#### bypassAutoEncryption
Drivers MUST disable auto encryption when the 'bypassAutoEncryption' option is true and not try to spawn mongocryptd.
Automatic encryption may be disabled with the bypassAutoEncryption option. See
[Why is there a bypassAutoEncryption?](#why-is-there-a-bypassautoencryption).
#### extraOptions
The extraOptions relate to the mongocryptd process, an implementation detail described in the
[Implementation](#implementation) section:
```typescript
{
// Defaults to "mongodb://localhost:27020".
mongocryptdURI: Optional<String>,
// Defaults to false.
mongocryptdBypassSpawn: Optional<Boolean>,
// Used for spawning. Defaults to empty string and spawns mongocryptd from system path.
mongocryptdSpawnPath: Optional<String>,
// Passed when spawning mongocryptd. If omitted, this defaults to ["--idleShutdownTimeoutSecs=60"]
mongocryptdSpawnArgs: Optional<Array[String]>
// Override the path used to load the crypt_shared library
cryptSharedLibPath: Optional<string>;
// If 'true', refuse to continue encryption without a crypt_shared library
cryptSharedLibRequired: boolean;
}
```
Drivers MUST implement extraOptions in a way that allows deprecating/removing options in the future without an API
break, such as with a BSON document or map type instead of a struct type with fixed fields. See
[Why are extraOptions and kmsProviders maps?](#why-are-extraoptions-and-kmsproviders-maps).
<span id="extraoptions.cryptsharedlibpath"></span>
##### `extraOptions.cryptSharedLibPath`
- Type: `undefined | string`
- Default: `undefined`
Allow the user to specify an absolute path to a [crypt_shared](#crypt_shared) dynamic library to load. Refer:
- [Overriding the crypt_shared Library Path](#overriding-the-crypt_shared-library-path)
- [Path Resolution Behavior](#path-resolution-behavior)
- [Enabling crypt_shared](#enabling-crypt_shared)
<span id="extraoptions.cryptsharedlibrequired"></span>
##### `extraOptions.cryptSharedLibRequired`
- Type: `boolean`
- Default: `false`
If `true`, the driver MUST refuse to continue unless [crypt_shared](#crypt_shared) was loaded successfully.
If, after initializing a `libmongocrypt_handle`, [crypt_shared](#crypt_shared) is detected to be unavailable AND
[extraOptions.cryptSharedLibRequired](#extraoptions.cryptsharedlibrequired) is `true`, the driver MUST consider the
`libmongocrypt_handle` to be invalid and return an error to the user. Refer:
<span id="managing-mongocryptd"></span> <span id="detecting-crypt_shared-availability"></span>
#### encryptedFieldsMap
`encryptedFieldsMap` maps a collection namespace to an `encryptedFields`.
`encryptedFieldsMap` only applies to Queryable Encryption.
If a collection is present on both the `encryptedFieldsMap` and `schemaMap`, [libmongocrypt](#libmongocrypt) will error
on initialization. See `fle2-and-fle1-error`.
If a collection has a set of encrypted fields, the behavior of `CreateCollection()` and `Collection.Drop()` is altered.
An additional helper, `CreateEncryptedCollection()` has been defined as a convenience wrapper around
`CreateCollection()`. See `fle2-createcollection-drop`.
Automatic encryption in Queryable Encryption is configured with the `encryptedFields`.
If a collection is not present on the `encryptedFields` a server-side collection `encryptedFields` may be used by
[libmongocrypt](#libmongocrypt). Drivers MUST include the following in the documentation for MongoClient:
> Supplying an `encryptedFieldsMap` provides more security than relying on an `encryptedFields` obtained from the
> server. It protects against a malicious server advertising a false `encryptedFields`.
#### bypassQueryAnalysis
See [Why is bypassQueryAnalysis needed?](#why-is-bypassqueryanalysis-needed).
### Queryable Encryption Create and Drop Collection Helpers
A collection supporting Queryable Encryption requires an index and three additional collections.
<span id="GetEncryptedFields"></span>
#### Collection `encryptedFields` Lookup (GetEncryptedFields)
The convenience methods support the following lookup process for finding the `encryptedFields` associated with a
collection.
Assume an exposition-only function $GetEncryptedFields(opts, collName, dbName, askDb)$, where $opts$ is a set of
options, $collName$ is the name of the collection, $dbName$ is the name of the database associated with that collection,
and $askDb$ is a boolean value. The resulting `encryptedFields` $EF$ is found by:
1. Let $QualName$ be the string formed by joining $dbName$ and $collName$ with an ASCII dot `"."`.
2. If $opts$ contains an `"encryptedFields"` property, then $EF$ is the value of that property.
3. Otherwise, if `AutoEncryptionOptions.encryptedFieldsMap` contains an element named by $QualName$, then $EF$ is the
value of that element.
4. Otherwise, if $askDb$ is `true`:
1. Issue a `listCollections` command against the database named by $dbName$, filtered by `{name: <collName>}`. Let
the result be the document $L$.
2. If $L$ contains an `options` document element, and that element contains an `encryptedFields` document element,
$EF$ is $L$ `["options"]["encryptedFields"]`.
3. Otherwise, $EF$ is *not-found*
5. Otherwise, $EF$ is considered *not-found*.
<span id="create-collection-helper"></span>
#### Create Collection Helper
Drivers MUST support a BSON document option named `encryptedFields` for any
[create](https://www.mongodb.com/docs/manual/reference/command/create) command helpers (e.g.
`Database.createCollection()`). This option will be interpreted by the helper method and MUST be passed to the
[create](https://www.mongodb.com/docs/manual/reference/command/create) command.
> [!NOTE]
> Users are not expected to set the `escCollection` and `ecocCollection` options in `encryptedFields`.
> [SERVER-74069](https://jira.mongodb.org/browse/SERVER-74069) added server-side validation for those fields and no
> longer allows names to deviate from the following:
>
> - `enxcol_.<collectionName>.esc`
> - `enxcol_.<collectionName>.ecoc`
>
> Drivers MUST NOT document the `escCollection` and `ecocCollection` options.
For a helper function, `CreateCollection(collectionName, collectionOptions)` with the name of the database associated as
$dbName$, look up the encrypted fields `encryptedFields` for the collection as $GetEncryptedFields(collectionOptions,
collectionName, dbName, false)$ ([See here](#GetEncryptedFields)).
If a set of `encryptedFields` was found, then do the following operations. If any of the following operations error, the
remaining operations are not attempted:
- Check the wire version of the writable server. If the wire version is less than 21 (for server 7.0.0), return an error
containing the error message: "Driver support of Queryable Encryption is incompatible with server. Upgrade server to
use Queryable Encryption."
- Create the collection with name `encryptedFields["escCollection"]` as a clustered collection using the options
`{clusteredIndex: {key: {_id: 1}, unique: true}}`. If `encryptedFields["escCollection"]` is not set, use the
collection name `enxcol_.<collectionName>.esc`. Creating this collection MUST NOT check if the collection namespace
is in the `AutoEncryptionOpts.encryptedFieldsMap`. the collection namespace is in the
`AutoEncryptionOpts.encryptedFieldsMap`.
- Create the collection with name `encryptedFields["ecocCollection"]` as a clustered collection using the options
`{clusteredIndex: {key: {_id: 1}, unique: true}}`. If `encryptedFields["ecocCollection"]` is not set, use the
collection name `enxcol_.<collectionName>.ecoc`. Creating this collection MUST NOT check if the collection namespace
is in the `AutoEncryptionOpts.encryptedFieldsMap`.
- Create the collection `collectionName` with `collectionOptions` and the option `encryptedFields` set to the
`encryptedFields`.
- Create the the index `{"__safeContent__": 1}` on collection `collectionName`.
#### Create Encrypted Collection Helper
To support automatic generation of encryption data keys, a helper $CreateEncryptedCollection(CE, database, collName,
collOpts, kmsProvider, masterKey)$ is defined, where $CE$ is a [ClientEncryption](#clientencryption) object,
$kmsProvider$ is a [KMSProvider](#KMSProvider) and $masterKey$ is equivalent to the $masterKey$ defined in
[DataKeyOpts](#datakeyopts). It has the following behavior:
- If $collOpts$ contains an `"encryptedFields"` property, then $EF$ is the value of that property. Otherwise, report an
error that there are no `encryptedFields` defined for the collection.
- Let $EF'$ be a copy of $EF$. Update $EF'$ in the following manner:
- Let $Fields$ be the `"fields"` element within $EF'$.
- If $Fields$ is present and is an array value, then for each element $F$ of `Fields`:
- If $F$ is not a document element, skip it.
- Otherwise, if $F$ has a `"keyId"` named element $K$ and $K$ is a `null` value:
- Create a [DataKeyOpts](#datakeyopts) named $dkOpts$ with the $masterKey$ argument.
- Let $D$ be the result of `CE.createDataKey(kmsProvider, dkOpts)`.
- If generating $D$ resulted in an error $E$, the entire $CreateEncryptedCollection$ must now fail with error $E$.
Return the partially-formed $EF'$ with the error so that the caller may know what datakeys have already been
created by the helper.
- Replace $K$ in $F$ with $D$.
- Create a new set of options $collOpts'$ duplicating $collOpts$. Set the `"encryptedFields"` named element of
$collOpts'$ to $EF'$.
- Invoke the `CreateCollection` helper as $CreateCollection(database, collName, collOpts')$. Return the resulting
collection and the generated $EF'$. If an error occurred, return the resulting $EF$ with the error so that the
caller may know what datakeys have already been created by the helper.
Drivers MUST document that $createEncryptedCollection$ does not affect any auto encryption settings on existing
MongoClients that are already configured with auto encryption. Users must configure auto encryption after creating the
encrypted collection with the $createEncryptedCollection$ helper.
#### Drop Collection Helper
Drivers MUST support a BSON document option named `encryptedFields` for any
[drop](https://www.mongodb.com/docs/manual/reference/command/drop) command helpers (e.g. `Database.dropCollection()`,
`Collection.drop()`). This option will only be interpreted by the helper method and MUST NOT be passed to the
[drop](https://www.mongodb.com/docs/manual/reference/command/drop) command.
> [!NOTE]
> Users are not expected to set the `escCollection` and `ecocCollection` options in `encryptedFields`.
> [SERVER-74069](https://jira.mongodb.org/browse/SERVER-74069) added server-side validation for those fields and no
> longer allows names to deviate from the following:
>
> - `enxcol_.<collectionName>.esc`
> - `enxcol_.<collectionName>.ecoc`
>
> Drivers SHOULD NOT document the `escCollection` and `ecocCollection` options.
For a helper function `DropCollection(dropOptions)` with associated collection named $collName$ and database named
$dbName$, look up the encrypted fields `encryptedFields` as $GetEncryptedFields(dropOptions, collName, dbname, true)$
([See here](#GetEncryptedFields)).
If a set of `encryptedFields` was found, then perform the following operations. If any of the following operations
error, the remaining operations are not attempted. A `namespace not found` error returned from the server (server error
code 26) MUST be ignored:
- Drop the collection with name `encryptedFields["escCollection"]`. If `encryptedFields["escCollection"]` is not set,
use the collection name `enxcol_.<collectionName>.esc`.
- Drop the collection with name `encryptedFields["ecocCollection"]`. If `encryptedFields["ecocCollection"]` is not set,
use the collection name `enxcol_.<collectionName>.ecoc`.
- Drop the collection `collectionName`.
### ClientEncryption
```typescript
class ClientEncryption {
ClientEncryption(opts: ClientEncryptionOpts);
// The "Create Encrypted Collection" helper is a convenience function wrapping CreateCollection. It will
// create a collection with encrypted fields, automatically allocating and assigning new data encryption
// keys. It returns a handle to the new collection, as well as a document consisting of the generated
// "encryptedFields" options. Refer to "Create Encrypted Collection Helper"
createEncryptedCollection(database: Database, collName: string, collOpts, kmsProvider: KMSProvider, masterKey: Optional<Document>): [Collection, Document];
// Creates a new key document and inserts into the key vault collection.
// Returns the _id of the created document as a UUID (BSON binary subtype 0x04).
createDataKey(kmsProvider: KMSProvider, opts: DataKeyOpts | null): Binary;
// Decrypts multiple data keys and (re-)encrypts them with a new masterKey, or with their current masterKey if a new one is not given.
// The updated fields of each rewrapped data key is updated in the key vault collection as part of a single bulk write operation.
// If no data key matches the given filter, no bulk write operation is executed.
// Returns a RewrapManyDataKeyResult.
rewrapManyDataKey(filter: Document, opts: RewrapManyDataKeyOpts | null): RewrapManyDataKeyResult;
// Removes the key document with the given UUID (BSON binary subtype 0x04) from the key vault collection.
// Returns the result of the internal deleteOne() operation on the key vault collection.
deleteKey(id: Binary): DeleteResult;