Skip to content

Commit ee86799

Browse files
committed
Update docs
1 parent 012ea2d commit ee86799

File tree

3 files changed

+128
-150
lines changed

3 files changed

+128
-150
lines changed

docs/howto/queryable-encryption.rst

Lines changed: 101 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,36 @@ Installation
2424
============
2525

2626
In 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
32-
pip install django-mongodb-backend[encryption]
33+
$ pip install django-mongodb-backend[encryption]
3334
3435
.. _qe-configuring-databases-setting:
3536

3637
Configuring 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
@@ -58,19 +66,12 @@ encryption keys.
5866
"ENGINE": "django_mongodb_backend",
5967
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
6068
"NAME": "my_database",
61-
"USER": "my_user",
62-
"PASSWORD": "my_password",
63-
"PORT": 27017,
64-
"OPTIONS": {
65-
"retryWrites": "true",
66-
"w": "majority",
67-
"tls": "false",
68-
},
69+
# ...
6970
},
7071
"encrypted": {
7172
"ENGINE": "django_mongodb_backend",
7273
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
73-
"NAME": "encrypted",
74+
"NAME": "my_database_encrypted",
7475
"USER": "my_user",
7576
"PASSWORD": "my_password",
7677
"PORT": 27017,
@@ -83,134 +84,138 @@ encryption keys.
8384
},
8485
}
8586
87+
.. admonition:: Local KMS provider key
88+
89+
In the example above, a random key is generated for the local KMS provider
90+
using ``os.urandom(96)``. In a production environment, you should securely
91+
:ref:`store and manage your encryption keys
92+
<manual:qe-fundamentals-kms-providers>`.
93+
8694
.. _qe-configuring-database-routers-setting:
8795

8896
Configuring the ``DATABASE_ROUTERS`` setting
8997
============================================
9098

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.
99+
Similar to configuring the :ref:`DATABASE_ROUTERS
100+
<configuring-database-routers-setting>` setting for
101+
:doc:`embedded models </topics/embedded-models>`, Queryable Encryption
102+
requires a :setting:`DATABASE_ROUTERS <django:DATABASE_ROUTERS>` setting to
103+
route database operations to the encrypted database.
95104

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:
105+
The following example shows how to configure a router for the "myapp"
106+
application that routes database operations to the encrypted database for all
107+
models in that application. The router also specifies the :ref:`KMS provider
108+
<qe-configuring-kms>` to use.
99109

100110
.. code-block:: python
101111
112+
# myapp/routers.py
102113
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-
115114
def allow_migrate(self, db, app_label, model_name=None, **hints):
116115
if app_label == "myapp":
117116
return db == "encrypted"
118-
# Don't create other app's models in the encrypted database.
117+
# Prevent migrations on the encrypted database for other apps
119118
if db == "encrypted":
120119
return False
121120
return None
122121
122+
def db_for_read(self, model, **hints):
123+
if model._meta.app_label == "myapp":
124+
return "encrypted"
125+
return None
126+
123127
def kms_provider(self, model, **hints):
124128
return "local"
125129
130+
db_for_write = db_for_read
126131
127-
DATABASE_ROUTERS = [EncryptedRouter]
132+
Then in your Django settings, add the custom database router to the
133+
:setting:`django:DATABASE_ROUTERS` setting:
134+
135+
.. code-block:: python
136+
137+
# settings.py
138+
DATABASE_ROUTERS = ["myapp.routers.EncryptedRouter"]
128139
129140
.. _qe-configuring-kms:
130141

131142
Configuring the Key Management Service (KMS)
132143
============================================
133144

134-
To use Queryable Encryption, you must configure a Key Management Service (KMS).
145+
To use Queryable Encryption, you must configure a Key Management Service (KMS)
146+
to store and manage your encryption keys. Django MongoDB Backend allows you to
147+
configure multiple KMS providers and select the appropriate provider for each
148+
model using a custom database router.
149+
135150
The KMS is responsible for managing the encryption keys used to encrypt and
136151
decrypt data. The following table summarizes the available KMS configuration
137152
options followed by an example of how to use them.
138153

139-
+-------------------------------------------------------------------------+--------------------------------------------------------+
140-
| :setting:`KMS_CREDENTIALS <DATABASE-KMS-CREDENTIALS>` | A dictionary of Key Management Service (KMS) |
141-
| | credentials configured in the |
142-
| | :setting:`django:DATABASES` setting. |
143154
+-------------------------------------------------------------------------+--------------------------------------------------------+
144155
| :class:`kms_providers <pymongo.encryption_options.AutoEncryptionOpts>` | A dictionary of KMS provider credentials used to |
145-
| | access the KMS with |
146-
| | :setting:`KMS_CREDENTIALS <DATABASE-KMS-CREDENTIALS>`. |
156+
| | access the KMS with ``kms_provider``. |
147157
+-------------------------------------------------------------------------+--------------------------------------------------------+
148-
| ``kms_provider`` | A single KMS provider name |
158+
| :ref:`kms_provider <qe-configuring-database-routers-setting>` | A single KMS provider name |
149159
| | configured in your custom database |
150160
| | router. |
151161
+-------------------------------------------------------------------------+--------------------------------------------------------+
152162

153-
Example of KMS configuration with AWS KMS:
163+
Example of KMS configuration with ``aws`` in your :class:`kms_providers
164+
<pymongo.encryption_options.AutoEncryptionOpts>` setting:
154165

155166
.. code-block:: python
156167
157168
from pymongo.encryption_options import AutoEncryptionOpts
158169
159170
DATABASES = {
160171
"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,
172+
# ...
167173
"OPTIONS": {
168174
"auto_encryption_opts": AutoEncryptionOpts(
169-
key_vault_namespace="encryption.__keyVault",
175+
# ...
170176
kms_providers={
171177
"aws": {
172-
"accessKeyId": "your-access-key-id",
173-
"secretAccessKey": "your-secret-access-key",
174-
}
178+
"key": os.getenv("AWS_KEY_ARN", ""),
179+
"region": os.getenv("AWS_KEY_REGION", ""),
180+
},
175181
},
176-
)
177-
},
178-
"KMS_CREDENTIALS": {
179-
"aws": {
180-
"key": os.getenv("AWS_KEY_ARN", ""),
181-
"region": os.getenv("AWS_KEY_REGION", ""),
182-
},
182+
),
183183
},
184184
},
185185
}
186186
187187
188+
In your :ref:`custom database router <qe-configuring-database-routers-setting>`,
189+
specify the KMS provider to use for the models in your application:
190+
191+
.. code-block:: python
192+
188193
class EncryptedRouter:
189194
# ...
190195
def kms_provider(self, model, **hints):
191196
return "aws"
192197
193198
.. _qe-configuring-encrypted-fields-map:
194199

195-
Configuring the ``encrypted_fields_map``
196-
========================================
200+
Configuring the ``encrypted_fields_map`` option
201+
===============================================
197202

198-
When you :ref:`configure an encrypted database connection
199-
<qe-configuring-databases-setting>` without specifying an
203+
When you configure the :ref:`DATABASES <qe-configuring-databases-setting>`
204+
setting for Queryable Encryption *without* specifying an
200205
``encrypted_fields_map``, Django MongoDB Backend will create encrypted
201-
collections for you when you run ``python manage.py migrate --database
202-
encrypted``.
206+
collections, including encryption keys, when you :ref:`run migrations for models
207+
that have encrypted fields <qe-migrations>`.
203208

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
209+
Encryption keys for encrypted fields are stored in the key vault specified in
210+
the :ref:`DATABASES <qe-configuring-kms>` setting. To see the keys created by
211+
Django MongoDB Backend, along with the entire schema, you can run the
207212
:djadmin:`showencryptedfieldsmap` command::
208213

209214
$ python manage.py showencryptedfieldsmap --database encrypted
210215

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.
216+
Use the output of :djadmin:`showencryptedfieldsmap` to set the
217+
``encrypted_fields_map`` in :class:`AutoEncryptionOpts
218+
<pymongo.encryption_options.AutoEncryptionOpts>` in your Django settings.
214219

215220
.. code-block:: python
216221
@@ -219,21 +224,10 @@ Use the output of the :djadmin:`showencryptedfieldsmap` command to set the
219224
220225
DATABASES = {
221226
"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,
227+
# ...
228228
"OPTIONS": {
229229
"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-
},
230+
# ...
237231
encrypted_fields_map=json_util.loads(
238232
"""{
239233
"encrypt_patient": {
@@ -260,6 +254,13 @@ Use the output of the :djadmin:`showencryptedfieldsmap` command to set the
260254
},
261255
}
262256
257+
258+
.. admonition:: Security consideration
259+
260+
Supplying an encrypted fields map provides more security than relying on an
261+
encrypted fields map obtained from the server. It protects against a
262+
malicious server advertising a false encrypted fields map.
263+
263264
Configuring the Automatic Encryption Shared Library
264265
===================================================
265266

@@ -271,60 +272,25 @@ You can :ref:`download the shared library
271272
<manual:qe-csfle-shared-library-download>` from the
272273
:ref:`manual:enterprise-official-packages` and configure it in your Django
273274
settings 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:
275+
:class:`AutoEncryptionOpts <pymongo.encryption_options.AutoEncryptionOpts>`.
276+
277+
The following example shows how to configure the shared library in your Django
278+
settings:
276279

277280
.. code-block:: python
278281
279282
from pymongo.encryption_options import AutoEncryptionOpts
280283
281284
DATABASES = {
282285
"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,
286+
# ...
289287
"OPTIONS": {
290288
"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-
),
289+
# ...
319290
crypt_shared_lib_path="/path/to/mongo_crypt_shared_v1.dylib",
320291
)
321292
},
322-
"KMS_CREDENTIALS": {
323-
"aws": {
324-
"key": os.getenv("AWS_KEY_ARN", ""),
325-
"region": os.getenv("AWS_KEY_REGION", ""),
326-
},
327-
},
293+
# ...
328294
},
329295
}
330296

docs/ref/models/encrypted-fields.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ for use with Queryable Encryption.
7272
| ``EncryptedObjectIdField`` | :class:`~.fields.ObjectIdField` |
7373
+----------------------------------------+------------------------------------------------------+
7474

75-
The following fields are supported by Django MongoDB Backend but not by
76-
Queryable Encryption.
75+
The following fields are supported by Django MongoDB Backend but not supported
76+
by Queryable Encryption.
7777

7878
+--------------------------------------+--------------------------------------------------------------------------------------------------------------------+
7979
| Field | Limitation |

0 commit comments

Comments
 (0)