0
# Client-Side Field Level Encryption
1
2
Client-side field level encryption (CSFLE) support for Motor. Enables encryption and decryption of sensitive document fields before they are sent to or received from MongoDB, providing end-to-end security for sensitive data.
3
4
## Capabilities
5
6
### Client Encryption
7
8
The main encryption client for managing encryption keys and performing field-level encryption operations.
9
10
```python { .api }
11
class AsyncIOMotorClientEncryption:
12
def __init__(
13
self,
14
kms_providers: Dict[str, Any],
15
key_vault_namespace: str,
16
key_vault_client: AsyncIOMotorClient,
17
codec_options: Optional[CodecOptions] = None,
18
kms_tls_options: Optional[Dict[str, Any]] = None
19
):
20
"""
21
Create a new client encryption instance.
22
23
Parameters:
24
- kms_providers: Configuration for key management systems (AWS KMS, Azure, GCP, local)
25
- key_vault_namespace: Database and collection name for the key vault (format: "db.collection")
26
- key_vault_client: Motor client connected to the key vault database
27
- codec_options: Options for encoding/decoding BSON documents
28
- kms_tls_options: TLS configuration for KMS providers
29
"""
30
31
async def create_data_key(
32
self,
33
kms_provider: str,
34
master_key: Optional[Dict[str, Any]] = None,
35
key_alt_names: Optional[List[str]] = None,
36
key_material: Optional[bytes] = None
37
) -> Binary:
38
"""
39
Create a new data encryption key.
40
41
Parameters:
42
- kms_provider: The KMS provider to use ('aws', 'azure', 'gcp', 'kmip', 'local')
43
- master_key: Master key configuration specific to the KMS provider
44
- key_alt_names: Alternative names for the key
45
- key_material: Custom key material (for local KMS only)
46
47
Returns:
48
Binary: The _id of the created data key
49
"""
50
51
async def encrypt(
52
self,
53
value: Any,
54
algorithm: str,
55
key_id: Optional[Binary] = None,
56
key_alt_name: Optional[str] = None,
57
query_type: Optional[str] = None,
58
contention_factor: Optional[int] = None,
59
range_opts: Optional[RangeOpts] = None
60
) -> Binary:
61
"""
62
Encrypt a value using client-side field level encryption.
63
64
Parameters:
65
- value: The value to encrypt
66
- algorithm: Encryption algorithm ('AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' or 'AEAD_AES_256_CBC_HMAC_SHA_512-Random')
67
- key_id: The data key _id to use for encryption
68
- key_alt_name: Alternative name of the data key
69
- query_type: Query type for queryable encryption ('equality', 'range')
70
- contention_factor: Contention factor for queryable encryption
71
- range_opts: Range options for range queries
72
73
Returns:
74
Binary: The encrypted value
75
"""
76
77
async def decrypt(self, value: Binary) -> Any:
78
"""
79
Decrypt an encrypted value.
80
81
Parameters:
82
- value: The encrypted Binary value to decrypt
83
84
Returns:
85
Any: The decrypted value
86
"""
87
88
async def encrypt_expression(
89
self,
90
expression: Dict[str, Any],
91
algorithm: str,
92
key_id: Optional[Binary] = None,
93
key_alt_name: Optional[str] = None,
94
query_type: Optional[str] = None,
95
contention_factor: Optional[int] = None,
96
range_opts: Optional[RangeOpts] = None
97
) -> RawBSONDocument:
98
"""
99
Encrypt a MongoDB expression for queryable encryption.
100
101
Parameters:
102
- expression: MongoDB query expression to encrypt
103
- algorithm: Encryption algorithm
104
- key_id: The data key _id to use for encryption
105
- key_alt_name: Alternative name of the data key
106
- query_type: Query type for queryable encryption
107
- contention_factor: Contention factor for queryable encryption
108
- range_opts: Range options for range queries
109
110
Returns:
111
RawBSONDocument: The encrypted expression
112
"""
113
114
async def rewrap_many_data_key(
115
self,
116
filter: Dict[str, Any],
117
provider: Optional[str] = None,
118
master_key: Optional[Dict[str, Any]] = None
119
) -> RewrapManyDataKeyResult:
120
"""
121
Rewrap multiple data keys with a new master key.
122
123
Parameters:
124
- filter: Query filter to select data keys to rewrap
125
- provider: New KMS provider (if changing providers)
126
- master_key: New master key configuration
127
128
Returns:
129
RewrapManyDataKeyResult: Result of the rewrap operation
130
"""
131
132
async def delete_key(self, id: Binary) -> DeleteResult:
133
"""
134
Delete a data key from the key vault.
135
136
Parameters:
137
- id: The _id of the data key to delete
138
139
Returns:
140
DeleteResult: Result of the delete operation
141
"""
142
143
async def get_key(self, id: Binary) -> Optional[RawBSONDocument]:
144
"""
145
Get a data key from the key vault.
146
147
Parameters:
148
- id: The _id of the data key to retrieve
149
150
Returns:
151
Optional[RawBSONDocument]: The data key document or None if not found
152
"""
153
154
async def add_key_alt_name(self, id: Binary, key_alt_name: str) -> Optional[RawBSONDocument]:
155
"""
156
Add an alternative name to a data key.
157
158
Parameters:
159
- id: The _id of the data key
160
- key_alt_name: The alternative name to add
161
162
Returns:
163
Optional[RawBSONDocument]: The updated data key document
164
"""
165
166
async def get_key_by_alt_name(self, key_alt_name: str) -> Optional[RawBSONDocument]:
167
"""
168
Get a data key by its alternative name.
169
170
Parameters:
171
- key_alt_name: The alternative name to search for
172
173
Returns:
174
Optional[RawBSONDocument]: The data key document or None if not found
175
"""
176
177
async def remove_key_alt_name(self, id: Binary, key_alt_name: str) -> Optional[RawBSONDocument]:
178
"""
179
Remove an alternative name from a data key.
180
181
Parameters:
182
- id: The _id of the data key
183
- key_alt_name: The alternative name to remove
184
185
Returns:
186
Optional[RawBSONDocument]: The updated data key document
187
"""
188
189
async def close(self) -> None:
190
"""Close the client encryption instance and release resources."""
191
```
192
193
## Usage Examples
194
195
### Basic Encryption Setup
196
197
```python
198
import motor.motor_asyncio
199
from pymongo.encryption import ClientEncryption
200
201
async def setup_encryption():
202
# Configure KMS providers
203
kms_providers = {
204
"local": {
205
"key": b"your-96-byte-local-master-key-here" * 4 # 96 bytes
206
}
207
}
208
209
# Connect to MongoDB
210
key_vault_client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017')
211
client_encryption = motor.motor_asyncio.AsyncIOMotorClientEncryption(
212
kms_providers=kms_providers,
213
key_vault_namespace="encryption.__keyVault",
214
key_vault_client=key_vault_client
215
)
216
217
# Create a data key
218
data_key_id = await client_encryption.create_data_key(
219
"local",
220
key_alt_names=["example-key"]
221
)
222
223
# Encrypt a value
224
encrypted_value = await client_encryption.encrypt(
225
"sensitive data",
226
algorithm="AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
227
key_id=data_key_id
228
)
229
230
# Decrypt the value
231
decrypted_value = await client_encryption.decrypt(encrypted_value)
232
print(f"Decrypted: {decrypted_value}")
233
234
await client_encryption.close()
235
key_vault_client.close()
236
```
237
238
### AWS KMS Integration
239
240
```python
241
async def setup_aws_kms_encryption():
242
kms_providers = {
243
"aws": {
244
"accessKeyId": "your-access-key-id",
245
"secretAccessKey": "your-secret-access-key",
246
"region": "us-east-1"
247
}
248
}
249
250
key_vault_client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017')
251
client_encryption = motor.motor_asyncio.AsyncIOMotorClientEncryption(
252
kms_providers=kms_providers,
253
key_vault_namespace="encryption.__keyVault",
254
key_vault_client=key_vault_client
255
)
256
257
# Create data key with AWS KMS
258
data_key_id = await client_encryption.create_data_key(
259
"aws",
260
master_key={
261
"region": "us-east-1",
262
"key": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
263
},
264
key_alt_names=["aws-example-key"]
265
)
266
267
return client_encryption, data_key_id
268
```
269
270
### Queryable Encryption
271
272
```python
273
async def queryable_encryption_example():
274
# Setup encryption client (same as above)
275
client_encryption, data_key_id = await setup_aws_kms_encryption()
276
277
# Encrypt for equality queries
278
encrypted_ssn = await client_encryption.encrypt(
279
"123-45-6789",
280
algorithm="Indexed",
281
key_id=data_key_id,
282
query_type="equality",
283
contention_factor=1
284
)
285
286
# Encrypt expression for range queries
287
range_expression = {"$gte": 1000, "$lte": 9999}
288
encrypted_expression = await client_encryption.encrypt_expression(
289
range_expression,
290
algorithm="Range",
291
key_id=data_key_id,
292
query_type="range",
293
range_opts={"min": 0, "max": 10000, "sparsity": 1}
294
)
295
296
await client_encryption.close()
297
```
298
299
## Types
300
301
```python { .api }
302
from typing import Dict, List, Optional, Any
303
from bson import Binary
304
from bson.raw_bson import RawBSONDocument
305
from pymongo.results import DeleteResult
306
307
class RewrapManyDataKeyResult:
308
bulk_write_result: Optional[Any]
309
310
class RangeOpts:
311
min: Optional[Any]
312
max: Optional[Any]
313
sparsity: int
314
precision: Optional[int]
315
```