@@ -24,10 +24,11 @@ Installation
2424============
2525
2626In addition to the :doc: `installation </intro/install >` and :doc: `configuration
27- </intro/configure>` steps for Django MongoDB Backend, Queryable
28- Encryption requires encryption support and a Key Management Service (KMS).
27+ </intro/configure>` steps required to use Django MongoDB Backend, Queryable
28+ Encryption has additional dependencies. You can install these dependencies
29+ by using the ``encryption `` extra when installing ``django-mongodb-backend ``:
2930
30- You can install encryption support with the following command::
31+ .. code-block :: console
3132
3233 pip install django-mongodb-backend[encryption]
3334
@@ -36,16 +37,23 @@ You can install encryption support with the following command::
3637Configuring the ``DATABASES `` setting
3738=====================================
3839
39- In addition to :ref: `configuring-databases-setting `, you must also configure an
40- encrypted database in your :setting: `django:DATABASES ` setting.
40+ In addition to the :ref: `database settings <configuring-databases-setting >`
41+ required to use Django MongoDB Backend, Queryable Encryption requires you to
42+ configure a separate encrypted database connection in your
43+ :setting: `django:DATABASES ` setting.
4144
42- This database will be used to store encrypted fields in your models. The
43- following example shows how to configure an encrypted database using the
44- :class: `AutoEncryptionOpts <pymongo.encryption_options.AutoEncryptionOpts> ` from the
45- :mod: `encryption_options <pymongo.encryption_options> ` module.
45+ .. admonition :: Encrypted database
4646
47- This example uses a local KMS provider and a key vault namespace for storing
48- encryption keys.
47+ An encrypted database is a separate database connection in your
48+ :setting: `django:DATABASES ` setting that is configured to use PyMongo's
49+ :class: `automatic encryption
50+ <pymongo.encryption_options.AutoEncryptionOpts> `.
51+
52+ The following example shows how to
53+ configure an encrypted database using the :class: `AutoEncryptionOpts
54+ <pymongo.encryption_options.AutoEncryptionOpts> ` from the
55+ :mod: `encryption_options <pymongo.encryption_options> ` module with a local KMS
56+ provider and encryption keys stored in the ``encryption.__keyVault `` collection.
4957
5058.. code-block :: python
5159
@@ -70,7 +78,7 @@ encryption keys.
7078 " encrypted" : {
7179 " ENGINE" : " django_mongodb_backend" ,
7280 " HOST" : " mongodb+srv://cluster0.example.mongodb.net" ,
73- " NAME" : " encrypted " ,
81+ " NAME" : " my_database_encrypted " ,
7482 " USER" : " my_user" ,
7583 " PASSWORD" : " my_password" ,
7684 " PORT" : 27017 ,
@@ -83,63 +91,77 @@ encryption keys.
8391 },
8492 }
8593
94+ .. admonition :: Local KMS provider key
95+
96+ In the example above, a random key is generated for the local KMS provider
97+ using ``os.urandom(96) ``. In a production environment, you should securely
98+ store and manage your encryption keys.
99+
86100.. _qe-configuring-database-routers-setting :
87101
88102Configuring the ``DATABASE_ROUTERS `` setting
89103============================================
90104
91- Similar to :ref: `configuring-database-routers-setting ` for using :doc: `embedded
92- models </topics/embedded-models>`, to use Queryable Encryption you must also
93- configure the :setting: `django:DATABASE_ROUTERS ` setting to route queries to the
94- encrypted database.
105+ Similar to configuring the :ref: `DATABASE_ROUTERS
106+ <configuring-database-routers-setting>` setting for
107+ :doc: `embedded models </topics/embedded-models >`, Queryable Encryption
108+ requires a :setting: `DATABASE_ROUTERS <django:DATABASE_ROUTERS> ` setting to
109+ route database operations to the encrypted database.
95110
96- This is done by adding a custom router that routes queries to the encrypted
97- database based on the model's metadata. The following example shows how to
98- configure a custom router for Queryable Encryption:
111+ The following example shows how to configure a router for the "myapp"
112+ application that routes database operations to the encrypted database for all
113+ models in that application. The router also specifies the :ref: `KMS provider
114+ <qe-configuring-kms>` to use.
99115
100116.. code-block :: python
101117
118+ # myapp/routers.py
102119 class EncryptedRouter :
103- """
104- A router for routing queries to the encrypted database for Queryable
105- Encryption.
106- """
107-
108- def db_for_read (self , model , ** hints ):
109- if model._meta.app_label == " myapp" :
110- return " encrypted"
111- return None
112-
113- db_for_write = db_for_read
114-
115120 def allow_migrate (self , db , app_label , model_name = None , ** hints ):
116121 if app_label == " myapp" :
117122 return db == " encrypted"
118- # Don't create other app's models in the encrypted database.
123+ # Prevent migrations on the encrypted database for other apps
119124 if db == " encrypted" :
120125 return False
121126 return None
122127
128+ def db_for_read (self , model , ** hints ):
129+ if model._meta.app_label == " myapp" :
130+ return " encrypted"
131+ return None
132+
123133 def kms_provider (self , model , ** hints ):
124134 return " local"
125135
136+ db_for_write = db_for_read
137+
126138
127- DATABASE_ROUTERS = [EncryptedRouter]
139+ Then in your Django settings, add the custom router to the
140+ :setting: `django:DATABASE_ROUTERS ` setting:
141+
142+ .. code-block :: python
143+
144+ # settings.py
145+ DATABASE_ROUTERS = [" myapp.routers.EncryptedRouter" ]
128146
129147 .. _qe-configuring-kms :
130148
131149Configuring the Key Management Service (KMS)
132150============================================
133151
134- To use Queryable Encryption, you must configure a Key Management Service (KMS).
152+ To use Queryable Encryption, you must configure a Key Management Service (KMS)
153+ to store and manage your encryption keys. Django MongoDB Backend allows you to
154+ configure multiple KMS providers and select the appropriate provider for each
155+ model using a custom database router.
156+
135157The KMS is responsible for managing the encryption keys used to encrypt and
136158decrypt data. The following table summarizes the available KMS configuration
137159options followed by an example of how to use them.
138160
139161+-------------------------------------------------------------------------+--------------------------------------------------------+
140162| :setting: `KMS_CREDENTIALS <DATABASE-KMS-CREDENTIALS> ` | A dictionary of Key Management Service (KMS) |
141- | | credentials configured in the |
142- | | :setting: `django:DATABASES ` setting. |
163+ | | credentials configured in an inner option of the |
164+ | | encrypted :setting: `django:DATABASES ` setting. |
143165+-------------------------------------------------------------------------+--------------------------------------------------------+
144166| :class: `kms_providers <pymongo.encryption_options.AutoEncryptionOpts> ` | A dictionary of KMS provider credentials used to |
145167| | access the KMS with |
@@ -158,23 +180,7 @@ Example of KMS configuration with AWS KMS:
158180
159181 DATABASES = {
160182 " encrypted" : {
161- " ENGINE" : " django_mongodb_backend" ,
162- " HOST" : " mongodb+srv://cluster0.example.mongodb.net" ,
163- " NAME" : " encrypted" ,
164- " USER" : " my_user" ,
165- " PASSWORD" : " my_password" ,
166- " PORT" : 27017 ,
167- " OPTIONS" : {
168- " auto_encryption_opts" : AutoEncryptionOpts(
169- key_vault_namespace = " encryption.__keyVault" ,
170- kms_providers = {
171- " aws" : {
172- " accessKeyId" : " your-access-key-id" ,
173- " secretAccessKey" : " your-secret-access-key" ,
174- }
175- },
176- )
177- },
183+ # ...
178184 " KMS_CREDENTIALS" : {
179185 " aws" : {
180186 " key" : os.getenv(" AWS_KEY_ARN" , " " ),
@@ -195,22 +201,22 @@ Example of KMS configuration with AWS KMS:
195201Configuring the ``encrypted_fields_map ``
196202========================================
197203
198- When you :ref: `configure an encrypted database connection
199- <qe-configuring-databases- setting>` without specifying an
204+ When you configure the :ref: `DATABASES < qe-configuring-databases-setting >`
205+ setting for Queryable Encryption * without * specifying an
200206``encrypted_fields_map ``, Django MongoDB Backend will create encrypted
201- collections for you when you run ``python manage.py migrate --database
202- encrypted ``.
207+ collections, including data keys, when you run ``python manage.py migrate
208+ --database encrypted ``.
203209
204- Encryption keys for encrypted fields are stored in the key vault
205- :ref: `specified in the Django settings <qe-configuring-kms >`. To see the keys
206- created by Django MongoDB Backend, along with the entire schema, you can run the
210+ Encryption keys for encrypted fields are stored in the key vault specified in
211+ the :ref: `DATABASES <qe-configuring-kms >` setting . To see the keys created by
212+ Django MongoDB Backend, along with the entire schema, you can run the
207213:djadmin: `showencryptedfieldsmap ` command::
208214
209215 $ python manage.py showencryptedfieldsmap --database encrypted
210216
211- Use the output of the :djadmin: `showencryptedfieldsmap ` command to set the
212- ``encrypted_fields_map `` in
213- :class: ` pymongo.encryption_options.AutoEncryptionOpts ` in your Django settings.
217+ Use the output of :djadmin: `showencryptedfieldsmap ` to set the
218+ ``encrypted_fields_map `` in :class: ` AutoEncryptionOpts
219+ < pymongo.encryption_options.AutoEncryptionOpts> ` in your Django settings.
214220
215221.. code-block :: python
216222
@@ -219,21 +225,10 @@ Use the output of the :djadmin:`showencryptedfieldsmap` command to set the
219225
220226 DATABASES = {
221227 " encrypted" : {
222- " ENGINE" : " django_mongodb_backend" ,
223- " HOST" : " mongodb+srv://cluster0.example.mongodb.net" ,
224- " NAME" : " encrypted" ,
225- " USER" : " my_user" ,
226- " PASSWORD" : " my_password" ,
227- " PORT" : 27017 ,
228+ # ...
228229 " OPTIONS" : {
229230 " auto_encryption_opts" : AutoEncryptionOpts(
230- key_vault_namespace = " encryption.__keyVault" ,
231- kms_providers = {
232- " aws" : {
233- " accessKeyId" : " your-access-key-id" ,
234- " secretAccessKey" : " your-secret-access-key" ,
235- }
236- },
231+ # ...
237232 encrypted_fields_map = json_util.loads(
238233 """ {
239234 "encrypt_patient": {
@@ -260,6 +255,13 @@ Use the output of the :djadmin:`showencryptedfieldsmap` command to set the
260255 },
261256 }
262257
258+
259+ .. admonition :: Security consideration
260+
261+ Supplying an encrypted fields map provides more security than relying on an
262+ encrypted fields map obtained from the server. It protects against a
263+ malicious server advertising a false encrypted fields map.
264+
263265Configuring the Automatic Encryption Shared Library
264266===================================================
265267
@@ -271,60 +273,25 @@ You can :ref:`download the shared library
271273<manual:qe-csfle-shared-library-download>` from the
272274:ref: `manual:enterprise-official-packages ` and configure it in your Django
273275settings using the ``crypt_shared_lib_path `` option in
274- :class: `pymongo.encryption_options.AutoEncryptionOpts `. The following example
275- shows how to configure the shared library in your Django settings:
276+ :class: `AutoEncryptionOpts <pymongo.encryption_options.AutoEncryptionOpts> `.
277+
278+ The following example shows how to configure the shared library in your Django
279+ settings:
276280
277281.. code-block :: python
278282
279283 from pymongo.encryption_options import AutoEncryptionOpts
280284
281285 DATABASES = {
282286 " encrypted" : {
283- " ENGINE" : " django_mongodb_backend" ,
284- " HOST" : " mongodb+srv://cluster0.example.mongodb.net" ,
285- " NAME" : " encrypted" ,
286- " USER" : " my_user" ,
287- " PASSWORD" : " my_password" ,
288- " PORT" : 27017 ,
287+ # ...
289288 " OPTIONS" : {
290289 " auto_encryption_opts" : AutoEncryptionOpts(
291- key_vault_namespace = " encryption.__keyVault" ,
292- kms_providers = {
293- " aws" : {
294- " accessKeyId" : " your-access-key-id" ,
295- " secretAccessKey" : " your-secret-access-key" ,
296- }
297- },
298- encrypted_fields_map = json_util.loads(
299- """ {
300- "encrypt_patient": {
301- "fields": [
302- {
303- "bsonType": "string",
304- "path": "patient_record.ssn",
305- "keyId": {
306- "$binary": {
307- "base64": "2MA29LaARIOqymYHGmi2mQ==",
308- "subType": "04"
309- }
310- },
311- "queries": {
312- "queryType": "equality"
313- }
314- },
315- ]
316- }
317- }"""
318- ),
290+ # ...
319291 crypt_shared_lib_path = " /path/to/mongo_crypt_shared_v1.dylib" ,
320292 )
321293 },
322- " KMS_CREDENTIALS" : {
323- " aws" : {
324- " key" : os.getenv(" AWS_KEY_ARN" , " " ),
325- " region" : os.getenv(" AWS_KEY_REGION" , " " ),
326- },
327- },
294+ # ...
328295 },
329296 }
330297
0 commit comments