Skip to content

RUBY-3143 split CSFLE and QE docs into separate sections #2703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/reference/in-use-encryption.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.. _in-use-encryption:

*****************
In-Use Encryption
*****************

.. default-domain:: mongodb

This section describes the different encryption methods in use by the Ruby
driver for MongoDB.

.. toctree::
:titlesonly:

/reference/in-use-encryption/queryable-encryption
/reference/in-use-encryption/client-side-encryption

Original file line number Diff line number Diff line change
Expand Up @@ -375,229 +375,6 @@ master key and create data keys, see the following sections of this tutorial:
- :ref:`Creating A Master Key <creating-a-master-key>`
- :ref:`Creating A Data Key <creating-a-data-key>`

Queryable Encryption
====================

Queryable encryption is a new feature in MongoDB 6.0. It also requires
libmongocrypt version 1.5.2 or above.

You can find more information about queryable encryption in `MongoDB Manual
<https://www.mongodb.com/docs/upcoming/core/queryable-encryption/queryable-encryption/>`_

.. note::

The queryable encryption feature is in public technical preview.
Therefore, the following options should be considered experimental
and are subject to change:

- ``:encrypted_fields_map`` and ``:bypass_query_analysis`` in auto encryption options.
- ``:contention_factor`` and ``:query_type`` in client encryption options.

Below is an example of using automatic queryable encryption using the Ruby driver:

.. code-block:: ruby

require 'mongo'

#####################################
# Step 1: Create a local master key #
#####################################

# A local master key is a 96-byte binary blob.
local_master_key = SecureRandom.random_bytes(96)
# => "\xB2\xBE\x8EN\xD4\x14\xC2\x13\xC3..."

#############################
# Step 2: Create a data key #
#############################

kms_providers = {
local: {
key: local_master_key
}
}

# The key vault client is a Mongo::Client instance
# that will be used to store your data keys.
key_vault_client = Mongo::Client.new('mongodb://localhost:27017,localhost:27018')

# Use an instance of Mongo::ClientEncryption to create a new data key
client_encryption = Mongo::ClientEncryption.new(
key_vault_client,
key_vault_namespace: 'encryption.__keyVault',
kms_providers: kms_providers
)

data_key_id = client_encryption.create_data_key('local')
# => <BSON::Binary... type=ciphertext...>

#######################################################
# Step 3: Configure Mongo::Client for auto-encryption #
#######################################################

# Create an encrypted fields map, which tells the Mongo::Client which fields to encrypt.
encrypted_fields_map = {
'encryption_db.encryption_coll' => {
fields: [
{
path: 'encrypted_field',
bsonType: 'string',
keyId: data_key_id,
queries: {
queryType: 'equality'
}
}
]
}
}

# Configure the client for automatic encryption
client = Mongo::Client.new(
'mongodb://localhost:27017,localhost:27018',
auto_encryption_options: {
key_vault_namespace: 'encryption.__keyVault',
kms_providers: kms_providers,
encrypted_fields_map: encrypted_fields_map,
},
database: 'encryption_db'
)

# Make sure there is no data in the collection.
client.database.drop

# Create encrypted collection explicitly.
collection = client['encryption_coll'].create

# The string "sensitive data" will be encrypted and stored in the database
# as ciphertext
collection.insert_one(encrypted_field: 'sensitive data')

# The data is decrypted before being returned to the user
collection.find(encrypted_field: 'sensitive data').first['encrypted_field']
# => "sensitive data"

# A client with no auto_encryption_options is unable to decrypt the data
client_no_encryption = Mongo::Client.new(['localhost:27017'], database: 'encryption_db')
client_no_encryption['encryption_coll'].find.first['encrypted_field']
# => <BSON::Binary... type=ciphertext...>

The example above demonstrates using automatic encryption with a local master key.
For more information about using other key management services to create a
master key and create data keys, see the following sections of this tutorial:

- :ref:`Creating A Master Key <creating-a-master-key>`
- :ref:`Creating A Data Key <creating-a-data-key>`

Below is an example of explicit queryable encryption.

.. code-block:: ruby

require 'mongo'

#####################################
# Step 1: Create a local master key #
#####################################

# A local master key is a 96-byte binary blob.
local_master_key = SecureRandom.random_bytes(96)
# => "\xB2\xBE\x8EN\xD4\x14\xC2\x13\xC3..."

#############################
# Step 2: Create a data key #
#############################

kms_providers = {
local: {
key: local_master_key
}
}

# The key vault client is a Mongo::Client instance
# that will be used to store your data keys.
key_vault_client = Mongo::Client.new('mongodb://localhost:27017,localhost:27018')

# Use an instance of Mongo::ClientEncryption to create a new data key
client_encryption = Mongo::ClientEncryption.new(
key_vault_client,
key_vault_namespace: 'encryption.__keyVault',
kms_providers: kms_providers
)

data_key_id = client_encryption.create_data_key('local')
# => <BSON::Binary... type=ciphertext...>

##########################################
# Step 3: Create an encrypted collection #
##########################################
encrypted_fields = {
fields: [
{
path: 'encrypted_field',
bsonType: 'string',
keyId: data_key_id,
queries: {
queryType: 'equality',
contention: 0
}
}
]
}

# Create the client you will use to read and write the data to MongoDB
# Please note that to insert or query with an "Indexed" encrypted payload,
# you should use a ``Mongo::Client`` that is configured with ``:auto_encryption_options``.
# ``auto_encryption_options[:bypass_query_analysis]`` may be true.
# ``auto_encryption_options[:bypass_auto_encryption]`` must be not set or false.
client = Mongo::Client.new(
['localhost:27017'],
auto_encryption_options: {
key_vault_namespace: 'encryption.__keyVault',
kms_providers: kms_providers,
bypass_query_analysis: true,
},
database: 'encryption_db',
)

# Make sure there is no data in the collection.
client['encryption_coll'].drop(encrypted_fields: encrypted_fields)
# Create encrypted collection explicitly.
client['encryption_coll'].create(encrypted_fields: encrypted_fields)

#####################################################
# Step 4: Encrypt a string with explicit encryption #
#####################################################

# The value to encrypt
value = 'sensitive data'

# Encrypt the value
insert_payload = client_encryption.encrypt(
'sensitive data',
{
key_id: data_key_id,
algorithm: "Indexed",
contention_factor: 0
}
)

# Insert the encrypted value into the collection
client['encryption_coll'].insert_one(encrypted_field: insert_payload)

# Use the client to read the encrypted value from the database, then
# use the ClientEncryption object to decrypt it.
find_payload = client_encryption.encrypt(
'sensitive data',
{
key_id: data_key_id,
algorithm: "Indexed",
contention_factor: 0,
query_type: "equality"
}
)

find_result = client['encryption_coll'].find(encrypted_field: find_payload).first['encrypted_field']
# => 'sensitive data'

.. _creating-a-master-key:

Creating a Master Key
Expand Down
Loading