@@ -204,10 +204,11 @@ in order to perform automatic encryption.
204204 key_vault_namespace: 'encryption.__keyVault',
205205 kms_providers: kms_providers,
206206 schema_map: schema_map
207- }
207+ },
208+ database: 'encryption_db',
208209 )
209210
210- collection = client.use('encryption_db') ['encryption_coll']
211+ collection = client['encryption_coll']
211212 collection.drop # Make sure there is no data in the collection
212213
213214 # The string "sensitive data" will be encrypted and stored in the database
@@ -219,8 +220,11 @@ in order to perform automatic encryption.
219220 # => "sensitive data"
220221
221222 # A client with no auto_encryption_options is unable to decrypt the data
222- client_no_encryption = Mongo::Client.new(['localhost:27017'])
223- client_no_encryption.use('encryption_db')['encryption_coll'].find.first['encrypted_field']
223+ client_no_encryption = Mongo::Client.new(
224+ ['localhost:27017'],
225+ database: 'encryption_db',
226+ )
227+ client_no_encryption.['encryption_coll'].find.first['encrypted_field']
224228 # => <BSON::Binary... type=ciphertext...>
225229
226230The example above demonstrates using automatic encryption with a local master key.
@@ -232,6 +236,7 @@ master key and create data keys, see the following sections of this tutorial:
232236
233237Explicit Encryption
234238===================
239+
235240Explicit encryption is a feature that allows users to encrypt and decrypt
236241individual pieces of data such as strings, integers, or symbols. Explicit
237242encryption is a community feature and does not require an enterprise build
@@ -302,8 +307,11 @@ in order to perform explicit encryption.
302307 )
303308
304309 # Create the client you will use to read and write the data to MongoDB
305- client = Mongo::Client.new(['localhost:27017'])
306- collection = client.use('encryption_db')['encryption_coll']
310+ client = Mongo::Client.new(
311+ ['localhost:27017'],
312+ database: 'encryption_db',
313+ )
314+ collection = client['encryption_coll']
307315 collection.drop # Make sure there is no data in the collection
308316
309317 # Insert the encrypted value into the collection
@@ -324,6 +332,215 @@ master key and create data keys, see the following sections of this tutorial:
324332- `Creating A Master Key`_,
325333- `Creating A Data Key`_,
326334
335+ Queryable Encryption
336+ ====================
337+
338+ Queryable encryption is a new feature in MongoDB 6.0. It also requires
339+ libmongocrypt version 1.5.0-rc1 or above.
340+
341+ You can find more information about queryable encryption in `MongoDB Manual
342+ <https://www.mongodb.com/docs/upcoming/core/queryable-encryption/queryable-encryption/>`_
343+
344+ .. note::
345+
346+ The queryable encryption feature is in public technical preview.
347+ Therefore, the following options should be considered experimental
348+ and are subject to change:
349+
350+ - ``:encrypted_fields_map`` and ``:bypass_query_analysis`` in auto encryption options.
351+ - ``:contention_factor`` and ``:query_type`` in client encryption options.
352+
353+ Below is an example of using automatic queryable encryption using the Ruby driver:
354+
355+ .. code-block:: ruby
356+
357+ require 'mongo'
358+
359+ #####################################
360+ # Step 1: Create a local master key #
361+ #####################################
362+
363+ # A local master key is a 96-byte binary blob.
364+ local_master_key = SecureRandom.random_bytes(96)
365+ # => "\xB2\xBE\x8EN\xD4\x14\xC2\x13\xC3..."
366+
367+ #############################
368+ # Step 2: Create a data key #
369+ #############################
370+
371+ kms_providers = {
372+ local: {
373+ key: local_master_key
374+ }
375+ }
376+
377+ # The key vault client is a Mongo::Client instance
378+ # that will be used to store your data keys.
379+ key_vault_client = Mongo::Client.new(['localhost:27017'])
380+
381+ # Use an instance of Mongo::ClientEncryption to create a new data key
382+ client_encryption = Mongo::ClientEncryption.new(
383+ key_vault_client,
384+ key_vault_namespace: 'encryption.__keyVault',
385+ kms_providers: kms_providers
386+ )
387+
388+ data_key_id = client_encryption.create_data_key('local')
389+ # => <BSON::Binary... type=ciphertext...>
390+
391+ #######################################################
392+ # Step 3: Configure Mongo::Client for auto-encryption #
393+ #######################################################
394+
395+ # Create an encrypted fields map, which tells the Mongo::Client which fields to encrypt.
396+ encrypted_fields_map = {
397+ 'encryption_db.encryption_coll' => {
398+ fields: [
399+ {
400+ path: 'encrypted_field',
401+ bsonType: 'string',
402+ keyId: data_key_id,
403+ queries: {
404+ queryType: 'equality'
405+ }
406+ }
407+ ]
408+ }
409+ }
410+
411+ # Configure the client for automatic encryption
412+ client = Mongo::Client.new(
413+ ['localhost:27017'],
414+ auto_encryption_options: {
415+ key_vault_namespace: 'encryption.__keyVault',
416+ kms_providers: kms_providers,
417+ encrypted_fields_map: encrypted_fields_map,
418+ },
419+ database: 'encryption_db'
420+ )
421+
422+ # Make sure there is no data in the collection.
423+ client.database.drop
424+
425+ # Create encrypted collection explicitly.
426+ collection = client['encryption_coll'].create
427+
428+ # The string "sensitive data" will be encrypted and stored in the database
429+ # as ciphertext
430+ collection.insert_one(encrypted_field: 'sensitive data')
431+
432+ # The data is decrypted before being returned to the user
433+ collection.find(encrypted_field: 'sensitive data').first['encrypted_field']
434+ # => "sensitive data"
435+
436+ # A client with no auto_encryption_options is unable to decrypt the data
437+ client_no_encryption = Mongo::Client.new(['localhost:27017'], database: 'encryption_db')
438+ client_no_encryption['encryption_coll'].find.first['encrypted_field']
439+ # => <BSON::Binary... type=ciphertext...>
440+
441+ The example above demonstrates using automatic encryption with a local master key.
442+ For more information about using other key management services to create a
443+ master key and create data keys, see the following sections of this tutorial:
444+
445+ - `Creating A Master Key`_
446+ - `Creating A Data Key`_
447+
448+ Below is an example of explicit queryable encryption.
449+
450+ .. code-block:: ruby
451+
452+ require 'mongo'
453+
454+ #####################################
455+ # Step 1: Create a local master key #
456+ #####################################
457+
458+ # A local master key is a 96-byte binary blob.
459+ local_master_key = SecureRandom.random_bytes(96)
460+ # => "\xB2\xBE\x8EN\xD4\x14\xC2\x13\xC3..."
461+
462+ #############################
463+ # Step 2: Create a data key #
464+ #############################
465+
466+ kms_providers = {
467+ local: {
468+ key: local_master_key
469+ }
470+ }
471+
472+ # The key vault client is a Mongo::Client instance
473+ # that will be used to store your data keys.
474+ key_vault_client = Mongo::Client.new(['localhost:27017'])
475+
476+ # Use an instance of Mongo::ClientEncryption to create a new data key
477+ client_encryption = Mongo::ClientEncryption.new(
478+ key_vault_client,
479+ key_vault_namespace: 'encryption.__keyVault',
480+ kms_providers: kms_providers
481+ )
482+
483+ data_key_id = client_encryption.create_data_key('local')
484+ # => <BSON::Binary... type=ciphertext...>
485+
486+ ##########################################
487+ # Step 3: Create an encrypted collection #
488+ ##########################################
489+
490+ # Create the client you will use to read and write the data to MongoDB
491+ client = Mongo::Client.new(['localhost:27017'], database: 'encryption_db')
492+
493+ encrypted_fields = {
494+ fields: [
495+ {
496+ path: 'encrypted_field',
497+ bsonType: 'string',
498+ keyId: data_key_id,
499+ queries: {
500+ queryType: 'equality'
501+ }
502+ }
503+ ]
504+ }
505+
506+ # Make sure there is no data in the collection.
507+ client['encryption_coll'].drop(encrypted_field: encrypted_fields)
508+ # Create encrypted collection explicitly.
509+ collection = client['encryption_coll'].create(encrypted_fields: encrypted_fields)
510+
511+ #####################################################
512+ # Step 4: Encrypt a string with explicit encryption #
513+ #####################################################
514+
515+ # The value to encrypt
516+ value = 'sensitive data'
517+
518+ # Encrypt the value
519+ insert_payload = client_encryption.encrypt(
520+ 'sensitive data',
521+ {
522+ key_id: data_key_id,
523+ algorithm: "Indexed"
524+ }
525+ )
526+
527+ # Insert the encrypted value into the collection
528+ collection.insert_one(encrypted_field: insert_payload)
529+
530+ # Use the client to read the encrypted value from the database, then
531+ # use the ClientEncryption object to decrypt it
532+ find_payload = client_encryption.encrypt(
533+ 'sensitive data',
534+ {
535+ key_id: data_key_id,
536+ algorithm: "Indexed",
537+ query_type: :equality
538+ }
539+ )
540+ find_result = collection.find(encrypted_field: find_payload).first['encrypted_field']
541+ # => 'sensitive data'
542+
543+
327544Creating a Master Key
328545=====================
329546Both automatic encryption and explicit encryption require an encryption master key.
@@ -335,6 +552,7 @@ Google Cloud Key Management (GCP KMS).
335552
336553Local Master Key
337554~~~~~~~~~~~~~~~~
555+
338556A local master key is a 96-byte binary string. It should be persisted
339557on your machine as an environment variable or in a text file.
340558
@@ -363,6 +581,7 @@ section of the MongoDB manual.
363581
364582Creating a Data Key
365583===================
584+
366585Once you have created a master key, create a data key by calling the
367586``#create_data_key`` method on an instance of the ``Mongo::ClientEncryption``
368587class. This method generates a new data key and inserts it into the key vault
@@ -434,7 +653,6 @@ and key id. You will use that information to generate a data key. You may also
434653need certificate authority certificate(s), as well as and your client
435654certificate and private key to authenticate to KMIP server.
436655
437-
438656.. code-block:: ruby
439657
440658 # A Mongo::Client instance that will be used to connect to the key vault
@@ -527,13 +745,15 @@ see :manual:`create client reference </reference/config-database/>`.
527745
528746Auto-Encryption Options
529747=======================
748+
530749Automatic encryption can be configured on a ``Mongo::Client`` using the
531750``auto_encryption_options`` option ``Hash``. This section provides an overview
532751of the fields inside ``auto_encryption_options`` and explains how to choose their
533752values.
534753
535754``:key_vault_client``
536755~~~~~~~~~~~~~~~~~~~~~
756+
537757The key vault client is a ``Mongo::Client`` instance that will be used to connect
538758to the MongoDB collection containing your encryption data keys. For example, if
539759your key vault was hosted on a MongoDB instance at ``localhost:30000``:
@@ -555,6 +775,7 @@ to insert and fetch data keys.
555775
556776``:key_vault_namespace``
557777~~~~~~~~~~~~~~~~~~~~~~~~
778+
558779The key vault namespace is a ``String`` in the format ``"database_name.collection_name"``,
559780where ``database_name`` and ``collection_name`` are the name of the database and
560781collection in which you would like to store your data keys. For example, if your data
@@ -573,6 +794,7 @@ There is no default key vault namespace, and this option must be provided.
573794
574795``:kms_providers``
575796~~~~~~~~~~~~~~~~~~
797+
576798A Hash that contains KMP provider names as keys, and provider options as values.
577799
578800.. code-block:: ruby
@@ -590,7 +812,8 @@ A Hash that contains KMP provider names as keys, and provider options as values.
590812 )
591813
592814``:kms_tls_options``
593- ~~~~~~~~~~~~~~~~~~
815+ ~~~~~~~~~~~~~~~~~~~~
816+
594817A Hash that contains KMP provider names as keys, and TLS options to connect to
595818corresponding providers.
596819
@@ -617,6 +840,7 @@ corresponding providers.
617840
618841``:schema_map``
619842~~~~~~~~~~~~~~~
843+
620844A schema map is a Hash with information about which fields to automatically
621845encrypt and decrypt.
622846
@@ -697,6 +921,7 @@ When you intend to use your schema map, convert it to a Ruby ``Hash`` using the
697921
698922``:bypass_auto_encryption``
699923~~~~~~~~~~~~~~~~~~~~~~~~~~~
924+
700925The ``:bypass_auto_encryption`` option is a ``Boolean`` that specifies whether the
701926``Mongo::Client`` should skip encryption when writing to the database. If
702927``:bypass_auto_encryption`` is ``true``, the client will still perform automatic
@@ -713,6 +938,7 @@ decryption of any previously-encrypted data.
713938
714939``:extra_options``
715940~~~~~~~~~~~~~~~~~~
941+
716942``:extra_options`` is a ``Hash`` of options related to spawning mongocryptd.
717943Every option in this ``Hash`` has a default value, so it is only necessary to
718944provide the options whose defaults you want to override.
0 commit comments