diff --git a/snooty.toml b/snooty.toml index f2840471..7ca8e8a9 100644 --- a/snooty.toml +++ b/snooty.toml @@ -30,3 +30,4 @@ server-manual = "Server manual" api = "https://www.mongodb.com/docs/mongoid/current/api" ruby-api = "https://www.mongodb.com/docs/ruby-driver/current/api" active-record-docs = "https://guides.rubyonrails.org" +shared-library = "Automatic Encryption Shared Library" diff --git a/source/includes/security/encryption.rb b/source/includes/security/encryption.rb new file mode 100644 index 00000000..e2ee5555 --- /dev/null +++ b/source/includes/security/encryption.rb @@ -0,0 +1,102 @@ +# start-encryption-schema +class Patient + include Mongoid::Document + include Mongoid::Timestamps + + encrypt_with key_id: '' + + # This field is not encrypted + field :category, type: String + + # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Random + # algorithm + field :passport_id, type: String, encrypt: { + deterministic: false + } + + # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic + # algorithm + field :blood_type, type: String, encrypt: { + deterministic: true + } + + # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Random + # algorithm and a different data key + field :ssn, type: Integer, encrypt: { + deterministic: false, key_id: '') + +# Create the encryption object +encryption = Mongo::ClientEncryption.new( + key_vault_client, + key_vault_namespace: 'encryption.__keyVault', + kms_providers: { + aws: { + "accessKeyId": "", + "secretAccessKey": "" + } + } +) + +encryption.rewrap_many_data_key( + {}, # Empty filter to rewrap all keys + { + provider: 'aws', + master_key: { + region: 'us-east-2', + key: 'arn:aws:kms:us-east-2:...' + } + } +) +# end-rewrap-keys + +# start-in-place + +# Print all documents in the collection. The first document is unencrypted, and +# the second is encrypted. +Patient.all.to_a +# => +# [#, +# #] + +# Querying for documents with a CSFLE-enabled client returns only the encrypted document +Patient.where(blood_type: 'AB+').to_a +# => [#] +# end-in-place \ No newline at end of file diff --git a/source/index.txt b/source/index.txt index 5ec4d9ba..9925127e 100644 --- a/source/index.txt +++ b/source/index.txt @@ -18,9 +18,10 @@ MongoDB in Ruby. To work with {+odm+} from the command line using Interact with Data Model Your Data Configuration + Secure Your Data /working-with-data API Documentation /whats-new Issues & Help /additional-resources - /ecosystem + /ecosystem \ No newline at end of file diff --git a/source/security.txt b/source/security.txt new file mode 100644 index 00000000..3b8db0b6 --- /dev/null +++ b/source/security.txt @@ -0,0 +1,21 @@ +.. _mongoid-security: + +================ +Secure Your Data +================ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ruby framework, odm, security + +.. toctree:: + :caption: Secure Your Data + + In-Use Encryption + +In this section, you can learn how to secure your data when using {+odm+}. + +- :ref:`Client-Side Field Level Encryption ` Learn how to encrypt your data with {+odm+}. \ No newline at end of file diff --git a/source/security/encryption.txt b/source/security/encryption.txt new file mode 100644 index 00000000..904affc0 --- /dev/null +++ b/source/security/encryption.txt @@ -0,0 +1,333 @@ +.. _automatic-encryption: +.. _mongoid-encryption: + +================================== +Client-Side Field Level Encryption +================================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ruby framework, odm, security, encrypt data, csfle, code example + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to encrypt your data by using **client-side +field level encryption** (CSFLE). CSFLE allows you to encrypt data in your +application before sending it over the network to MongoDB. This means that no +MongoDB product has access to your data in unencrypted form. + +You can set up CSFLE by using one of the following mechanisms: + +- Automatic encryption: Allows you to perform encrypted read and write + operations without specifying how to encrypt fields +- Explicit encryption: Allows you to perform encrypted read and write operations + with specified encryption logic throughout your application. + +This guide describes how to set up CSFLE with automatic encryption. To learn more +about using explicit encryption, see the :ruby:`Explicit Encryption +` guide +in the {+ruby-driver+} documentation. + +Install Dependencies +-------------------- + +To use CSFLE with {+odm+}, you must first install the following dependencies: + +- ``libmongocrypt`` +- {+shared-library+} if you are using {+ruby-driver+} v2.19 or later. Or + ``mongocryptd`` if you are using {+ruby-driver+} v2.18 or earlier. +- ``ffi`` + +The following sections provide details on how to install these +dependencies. + +libmongocrypt +~~~~~~~~~~~~~ + +You can install ``libmongocrypt`` by adding the :github:`libmongocrypt-helper gem +` to your ``Gemfile`` +or by downloading the library manually. + +To install ``libmongocrypt`` by adding the gem file, navigate to the folder in +which your application is located and run the following command in your shell: + +.. code-block:: bash + + gem install libmongocrypt-helper --pre + +.. note:: + + Because the version number of ``libmongocrypt-helper`` might contain letters, + which indicates a pre-release version in {+language+}, the ``--pre`` flag is + required. + +To learn how to download and install the library manually, see the +:ruby:`libmongocrypt installation guide +` +in the {+ruby-driver+} documentation. + +Shared Library (Driver v2.19 or later) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following steps detail how to install the {+shared-library+}: + +1. In a browser, navigate to the :website:`MongoDB Download Center + `. +#. Select the latest current version in the ``Version`` dropdown, denoted by the + ``(current)`` tag. +#. Select your platform in the ``Platform`` dropdown. +#. Select ``crypt_shared`` in the ``Package`` dropdown. +#. Click the ``Download`` button to download the shared library. + +After you download the file, extract the contents and save the +file in a location that your application can access. Then, configure your +``mongoid.yml`` file in your application to point to the library, as shown in +the following example: + +.. code-block:: ruby + :emphasize-lines: 5-7 + + development: + clients: + default: + options: + auto_encryption_options: + extra_options: + crypt_shared_lib_path: '' + +mongocryptd (Driver v2.18 or earlier) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are using {+ruby-driver+} version 2.18 or earlier, you must use ``mongocryptd`` +instead of the {+shared-library+}. ``mongocryptd`` comes +pre-packaged with enterprise builds of MongoDB Server. For instructions on how to +install and configure ``mongocryptd``, see the :manual:`Install mongocryptd guide +` in the MongoDB +{+server-manual+}. + +ffi +~~~ + +{+odm+} uses the `ffi gem `__ to call functions from +``libmongocrypt``. Add the gem to your ``Gemfile`` by running the following +command in your shell: + +.. code-block:: bash + + gem 'ffi' + +Create a Customer Master Key +---------------------------- + +To encrypt and decrypt data, you must first create a Customer Master Key (CMK). +A CMK is a key that you use to encrypt your :ref:`Data Encryption Key +` (DEK). Without access to a CMK, your client application cannot decrypt +DEKs associated with your encrypted data. + +You can create a locally-stored key to use as a local CMK for testing purposes +by running the following {+language+} code: + +.. code-block:: ruby + + require 'securerandom' + + SecureRandom.hex(48) + +.. warning:: + + Using a local CMK in a production environment is insecure. For production + environments, use a remote key management service to create and + store your CMK. + + To learn more about key management service providers, see the :manual:`KMS Providers + guide ` in the MongoDB + {+server-manual+}. + +Configure your Client +--------------------- + +You must configure your MongoDB client to implement CSFLE. To configure a +client for CSFLE, add the following code to your ``mongoid.yml`` file: + +.. code-block:: bash + + development: + clients: + default: + uri: "" + options: + auto_encryption_options: # This key enables automatic encryption + key_vault_namespace: 'encryption.__keyVault' # Database and collection in which to store data keys + kms_providers: # Tells the driver where to obtain master keys + local: # Specifies that the key is local + key: "" + extra_options: + crypt_shared_lib_path: '' # Only required for Ruby versions 2.19 or later + +.. note:: + + Ensure that you replace the placeholders surrounded by brackets (``<>``) in the preceding code + example. + +.. _mongoid-dek: + +Create a Data Encryption Key +---------------------------- + +A Data Encryption Key (DEK) is a key that you use to encrypt the fields in your +documents. MongoDB stores DEKs, encrypted with your CMK, in the Key Vault +collection as BSON documents. MongoDB can never decrypt the DEKs, as key +management is client-side and customer controlled. + +To create a DEK in {+odm+}, you can use the +``db:mongoid:encryption:create_data_key`` rake task, as shown in the following +example: + +.. code-block:: bash + + rake db:mongoid:encryption:create_data_key + +You can create multiple DEKs by repeating the preceding command for the number +of keys you want to generate. + +You can also provide an alternate name for your DEK. This allows you to reference +the DEK by name when configuring encryption for your fields and +to dynamically assign a DEK to a field at runtime. + +The following example creates an alternate name when generating a new DEK: + +.. code-block:: bash + + rake db:mongoid:encryption:create_data_key -- --key-alt-name= + +Configure Encryption Schema +--------------------------- + +You can specify which fields to encrypt by adding the ``encrypt`` option to the +field definition in your models and specifying the ``deterministic`` and +``key_id`` options, as shown in the following example: + +.. literalinclude:: /includes/security/encryption.rb + :language: ruby + :start-after: start-encryption-schema + :end-before: end-encryption-schema + +.. note:: + + If you are developing a Rails application, we recommend setting the + ``preload_models`` option to ``true`` in your ``mongoid.yml`` file. This + ensures that {+odm+} loads all models and configures the encryption schema + before any data is read or written. + +Limitations +----------- + +The following limitations apply when using CSFLE with {+odm+}: + +- {+odm+} does not support encryption of ``embeds_many`` associations. +- If you use the ``:key_name_field`` option, you must encrypt the field by using + a non-deterministic algorithm. To encrypt your field deterministically, you must + specify the ``:key_id`` option instead. +- The limitations listed on the :manual:`CSFLE Limitations + ` page in the MongoDB {+server-manual+} + also apply to {+odm+}. + +Working with Data +----------------- + +Usually, automatic CSLFE works transparently in your application. After +your application is configured for CSFLE, you can create documents as usual and {+odm+} +automatically encrypts and decrypts them according to your configuration. + +The following example creates a new ``Patient`` document in an application +configured for CSFLE. It then uses a client called ``unencrypted_client`` that +is connected to the database but not configured for CSFLE to read the document. + +.. io-code-block:: + + .. input:: /includes/security/encryption.rb + :language: ruby + :start-after: start-query-encrypted + :end-before: end-query-encrypted + + .. output:: + + {"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4292'), + "category"=>"ER", + "passport_id"=>, + "blood_type"=>, + "ssn"=>, + "insurance"=>{"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4293'), + "insurer"=>"TK", "policy_number"=>}, "policy_number_key"=>"my_data_key"} + +In the preceding example, the ``unencrypted_client`` client is unable to read +the encrypted fields. However, if you query the document with a client that *is* +configured for CSFLE, {+odm+} automatically decrypts the fields. + +Rotate Encryption Keys +---------------------- + +You can rotate your encryption keys by using the ``rewrap_many_data_key`` {+ruby-driver+} +method. This method automatically decrypts multiple data encryption keys +and re-encrypts them using a specified CMK. It then updates the rotated keys in +the key vault collection. + +The ``rewrap_many_data_key`` method takes the following parameters: + +- Filter, used to specify which fields to rotate. If no data key matches the + given filter, no keys will be rotated. Omit the filter to rotate all keys in + your key vault collection. +- Object that represents a new CMK with which to re-encrypt the DEKs. Omit + this object to rotate the data keys by using their current CMKs. + +The following example rotates encryption keys by using the AWS KMS: + +.. literalinclude:: /includes/security/encryption.rb + :language: ruby + :start-after: start-rewrap-keys + :end-before: end-rewrap-keys + +Add Automatic Encryption to Existing Project +-------------------------------------------- + +Automatic CSFLE with {+odm+} supports encryption in place. You can enable +encryption on an existing database and still read unencrypted data. However, +once you enable encryption, all new data is encrypted, and any query operation +uses only the encrypted documents. This means that queries might not return all documents +if some were saved before enabling encryption. + +The following example queries a collection that has one encrypted document and +one unencrypted document: + +.. literalinclude:: /includes/security/encryption.rb + :language: ruby + :start-after: start-in-place + :end-before: end-in-place + +You can encrypt existing data in a collection by reading and then writing back +all data with a CSFLE-enabled client. When doing so, ensure that all existing +data is the expected type and that empty values are not set as ``nil``. + +Additional Information +---------------------- + +To learn more about CSFLE, see the :manual:`Client-Side Field Level Encryption +` guide in the MongoDB {+server-manual+}. + +To learn more about using CSFLE with the {+ruby-driver+}, see the +:ruby:`Client-Side Encryption +` guide in the +{+ruby-driver+} documentation. + +.. TODO: Add link to mongoid configuration page for encryption settings when available. \ No newline at end of file diff --git a/source/tutorials.txt b/source/tutorials.txt index 8b30c6e0..2a564253 100644 --- a/source/tutorials.txt +++ b/source/tutorials.txt @@ -8,12 +8,10 @@ Tutorials :titlesonly: tutorials/common-errors - tutorials/automatic-encryption Overview -------- See the following sections to learn more about working with Mongoid: -- :ref:`Common Errors ` -- :ref:`Automatic Client-Side Field Level Encryption ` \ No newline at end of file +- :ref:`Common Errors ` \ No newline at end of file diff --git a/source/tutorials/automatic-encryption.txt b/source/tutorials/automatic-encryption.txt deleted file mode 100644 index 62e68c27..00000000 --- a/source/tutorials/automatic-encryption.txt +++ /dev/null @@ -1,439 +0,0 @@ -.. _automatic-encryption: - -******************************************** -Automatic Client-Side Field Level Encryption -******************************************** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - - -Since version 4.2 MongoDB supports `Client-Side Field Level Encryption -(CSFLE) `_. This is a feature -that enables you to encrypt data in your application before you send it over the -network to MongoDB. With CSFLE enabled, no MongoDB product has access to your -data in an unencrypted form. - -You can set up CSFLE using the following mechanisms: - -* `Automatic Encryption `_: - Enables you to perform encrypted read and write operations without you having - to write code to specify how to encrypt fields. -* `Explicit Encryption `_: - Enables you to perform encrypted read and write operations through your - MongoDB driver's encryption library. You must specify the logic for encryption - with this library throughout your application. - -Starting with version 9.0, Mongoid supports CSFLE's Automatic Encryption -feature. This tutorial walks you through the process of setting up and using -CSFLE in Mongoid. - -.. note:: - This tutorial does not cover all CSLFE features. - You can find more information about MongoDB CSFLE in - `the server documentation. `_ - -.. note:: - If you want to use explicit FLE, please follow `the Ruby driver documentation. - `_ - - -Installation -============ - -You can find the detailed description of how to install the necessary -dependencies in `the driver documentation. `_ - -Note the version of the Ruby driver being used in your application and select -the appropriate steps below. - -Install ``libmongocrypt`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -This can be done one of two ways. - -* Add the `libmongocrypt-helper gem `_ to - your ``Gemfile`` or -* Download the ``libmongocrypt`` `release archive `_, - extract the version that matches your operating system, and set the - ``LIBMONGOCRYPT_PATH`` environment variable accordingly. - -Install the automatic encryption shared library (Ruby driver 2.19+) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you use the Ruby driver version 2.19 and above, the automatic encryption -shared library should be installed by following the instructions on the -:manual:`Automatic Encryption Shared Library for Queryable Encryption -` -page in the Server manual. - -The steps required are as follows: - -1. Navigate to the `MongoDB Download Center `_ -2. From the Version dropdown, select ``x.y.z (current)`` (the latest current version). -3. In the Platform dropdown, select your platform. -4. In the Package dropdown, select ``crypt_shared``. -5. Click Download. - -Once extracted, ensure the full path to the library is configured within your -``mongoid.yml`` as follows: - -.. code-block:: yaml - - development: - clients: - default: - options: - auto_encryption_options: - extra_options: - crypt_shared_lib_path: '/path/to/mongo_crypt_v1.so' - -Install the ``mongocryptd`` (Ruby driver 2.18 or older) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are using an older version of the Ruby driver ``mongocryptd`` will -need to be installed manually. ``mongocryptd`` comes pre-packaged with -enterprise builds of the MongoDB server (versions 4.2 and newer). -For installation instructions, see the `MongoDB manual `_. - -Add ``ffi`` to your Gemfile -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The MongoDB Ruby driver uses the `ffi gem `_ to call -functions from ``libmongocrypt``. As this gem is not a dependency of -the driver, it will need to be manually added to your ``Gemfile``: - -.. code-block:: ruby - - gem 'ffi' - -Create a Customer Master Key -============================ - -A Customer Master Key (CMK) is used to encrypt Data Encryption Keys. -The easiest way is to use a locally stored 96-bytes key. You can generate such -a key using the following Ruby code: - -.. code-block:: ruby - - require 'securerandom' - - SecureRandom.hex(48) # => "f54ab...." - -Later in this tutorial we assume that the Customer Master Key is -available from the ``CUSTOMER_MASTER_KEY`` environment variable. - -.. warning:: - - Using a local master key is insecure. It is recommended that you use a remote - Key Management Service to create and store your master key. To do so, follow - steps of the `"Set up a Remote Master Key" `_ - in the MongoDB Client-Side Encryption documentation. - - For more information about creating a master key, see the - `Create a Customer Master Key `_ - section of the MongoDB manual. - -Configure Clients -================= - -Automatic CSFLE requires some additional configuration for the MongoDB client. -Assuming that your application has just one ``default`` client, you need to -add the following to your ``mongoid.yml``: - -.. code-block:: yaml - - development: - clients: - default: - uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority - options: - auto_encryption_options: # This key enables automatic encryption - key_vault_namespace: 'encryption.__keyVault' # Database and collection to store data keys - kms_providers: # Tells the driver where to obtain master keys - local: # We use the local key in this tutorial - key: "<%= ENV['CUSTOMER_MASTER_KEY'] %>" # Key that we generated earlier - extra_options: - crypt_shared_lib_path: '/path/to/mongo_crypt_v1.so' # Only if you use the library - - -Create a Data Encryption Key -============================ - -A Data Encryption Key (DEK) is the key you use to encrypt the fields in your -MongoDB documents. You store your Data Encryption Key in your Key Vault -collection encrypted with your CMK. - -To create a DEK in Mongoid you can use the -``db:mongoid:encryption:create_data_key`` ``Rake`` task: - -.. code-block:: sh - - % rake db:mongoid:encryption:create_data_key - Created data key with id: 'KImyywsTQWi1+cFYIHdtlA==' for kms provider: 'local' in key vault: 'encryption.__keyVault'. - -You can create multiple DEKs, if necessary. - -.. code-block:: sh - - % rake db:mongoid:encryption:create_data_key - Created data key with id: 'Vxr5m+5cQISjDOruzZgE0w==' for kms provider: 'local' in key vault: 'encryption.__keyVault'. - -You can also provide an alternate name for the DEK. This allows you to reference -the DEK by name when configuring encryption for your fields. It also allows you -to dynamically assign a DEK to a field at runtime. - -.. code-block:: sh - - % rake db:mongoid:encryption:create_data_key -- --key-alt-name=my_data_key - Created data key with id: 'yjF8hKmKQsqGeFGXlB9Sow==' with key alt name: 'my_data_key' for kms provider: 'local' in key vault: 'encryption.__keyVault'. - - -Configure Encryption Schema -=========================== - -Now we can tell Mongoid what should be encrypted: - -.. code-block:: ruby - - class Patient - include Mongoid::Document - include Mongoid::Timestamps - - # Tells Mongoid what DEK should be used to encrypt fields of the document - # and its embedded documents. - encrypt_with key_id: 'KImyywsTQWi1+cFYIHdtlA==' - - # This field is not encrypted. - field :category, type: String - - # This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random - # algorithm. - field :passport_id, type: String, encrypt: { - deterministic: false - } - # This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic - # algorithm. - field :blood_type, type: String, encrypt: { - deterministic: true - } - # This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random - # algorithm and using a different data key. - field :ssn, type: Integer, encrypt: { - deterministic: false, key_id: 'Vxr5m+5cQISjDOruzZgE0w==' - } - - embeds_one :insurance - end - - class Insurance - include Mongoid::Document - include Mongoid::Timestamps - - field :insurer, type: String - - # This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random - # algorithm using the key which alternate name is stored in the - # policy_number_key field. - field :policy_number, type: Integer, encrypt: { - deterministic: false, - key_name_field: :policy_number_key - } - - embedded_in :patient - end - -.. note:: - If you are developing a Rails application, it is recommended to set - ``preload_models`` to ``true`` in ``mongoid.yml``. This will ensure that - Mongoid loads all models before the application starts, and the encryption - schema is configured before any data is read or written. - -Known Limitations -~~~~~~~~~~~~~~~~~ - -* MongoDB CSFLE has some limitations that are described on the - :manual:`CSFLE Limitations ` - page in the Server manual. These limitations also apply to Mongoid. -* Mongoid does not support encryption of ``embeds_many`` relations. -* If you use ``:key_name_field`` option, the field must be encrypted using - non-deterministic algorithm. To encrypt your field deterministically, you must - specify ``:key_id`` option instead. - -Working with Data -================= - -Automatic CSFLE usage is transparent in many situations. - -.. note:: - In code examples below we assume that there is a variable ``unencrypted_client`` - that is a ``MongoClient`` connected to the same database but without encryption. - We use this client to demonstrate what is actually persisted in the database. - -Documents can be created as usual, fields will be encrypted and decrypted -according to the configuration: - -.. code-block:: ruby - - Patient.create!( - category: 'ER', - passport_id: '123456', - blood_type: 'AB+', - ssn: 98765, - insurance: Insurance.new(insurer: 'TK', policy_number: 123456, policy_number_key: 'my_data_key') - ) - - # Fields are encrypted in the database - unencrypted_client['patients'].find.first - # => - # {"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4292'), - # "category"=>"ER", - # "passport_id"=>, - # "blood_type"=>, - # "ssn"=>, - # "insurance"=>{"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4293'), "insurer"=>"TK", "policy_number"=>}, "policy_number_key"=>"my_data_key"} - -Fields encrypted using a deterministic algorithm can be queried. Only exact match -queries are supported. For more details please consult `the server documentation -`_. - -.. code-block:: ruby - - # We can find documents by deterministically encrypted fields. - Patient.where(blood_type: "AB+").to_a - # => [#] - -Encryption Key Management -========================= - -Customer Master Keys -~~~~~~~~~~~~~~~~~~~~ - -Your Customer Master Key is the key you use to encrypt your Data Encryption Keys. -MongoDB automatically encrypts Data Encryption Keys using the specified CMK -during Data Encryption Key creation. - -The CMK is the most sensitive key in CSFLE. If your CMK is compromised, all of -your encrypted data can be decrypted. - -.. important:: - Ensure you store your Customer Master Key (CMK) on a remote KMS. - - To learn more about why you should use a remote KMS, see `Reasons to Use a Remote KMS. `_ - - To view a list of all supported KMS providers, see the `KMS Providers `_ page. - -MongoDB CSFLE supports the following Key Management System (KMS) providers: - * `Amazon Web Services KMS `_ - * `Azure Key Vault `_ - * `Google Cloud Platform KMS `_ - * Any KMIP Compliant Key Management System - * Local Key Provider (for testing only) - -Data Encryption Keys -~~~~~~~~~~~~~~~~~~~~ - -Data Encryption Keys can be created using the -``db:mongoid:encryption:create_data_key`` ``Rake`` task. By default they are -stored on the same cluster as the database. -However, it might be a good idea to store the keys separately. This can be -done by specifying a key vault client in ``mongoid.yml``: - -.. code-block:: yaml - - development: - clients: - key_vault: - uri: mongodb+srv://user:pass@anothercluster.mongodb.net/blog_development?retryWrites=true&w=majority - default: - uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority - options: - auto_encryption_options: - key_vault_client: :key_vault # Client to connect to key vault - # ... - -Encryption Keys Rotation -~~~~~~~~~~~~~~~~~~~~~~~~ - -You can rotate encryption keys using the ``rewrap_many_data_key`` method -of the Ruby driver. This method automatically decrypts multiple data encryption -keys and re-encrypts them using a specified CMK. It then updates -the rotated keys in the key vault collection. This method allows you to rotate -encryption keys based on two optional arguments: - -* A filter used to specify which keys to rotate. If no data key matches the - given filter, no keys will be rotated. Omit the filter to rotate all keys in - your key vault collection. -* An object that represents a new CMK. Omit this object to rotate the data - keys using their current CMKs. - -Here is an example of rotating keys using AWS KMS: - -.. code-block:: ruby - - # Create a key vault client - key_vault_client = Mongo::Client.new('mongodb+srv://user:pass@yourcluster.mongodb.net') - # Or, if you declared the key value client in mongoid.yml, use it - key_vault_client = Mongoid.client(:key_vault) - - # Create the encryption object - encryption = Mongo::ClientEncryption.new( - key_vault_client, - key_vault_namespace: 'encryption.__keyVault', - kms_providers: { - aws: { - "accessKeyId": "", - "secretAccessKey": "" - } - } - ) - - encryption.rewrap_many_data_key( - {}, # We want to rewrap all keys - { - provider: 'aws', - master_key: { - region: 'us-east-2', - key: 'arn:aws:kms:us-east-2:...' - } - } - ) - -Adding Automatic Encryption To Existing Project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -MongoDB automatic CSFLE supports encryption in place. You can enable encryption -for your existing database, and will still able to read unencrypted data. -All data written to the database will be encrypted. However, as soon as the -encryption is enabled, all query operations will use encrypted data: - -.. code-block:: ruby - - # We assume that there are two documents in the database, one created without - # encryption enabled, and one with encryption. - - # We can still read both. - Patient.all.to_a - # => - # [#, - # #] - - # But when we query, we can see only the latter one. - Patient.where(blood_type: 'AB+').to_a - # => [#] - -If you want to encrypt the existing database, it can be achieved by reading -and writing back all data, even without any changes. If you decide to do so, -please keep the following in mind: - -* Validate the integrity of existing data for consistent fidelity. CSFLE is - type sensitive - for example you cannot store integers in a field that is - declared as ``String``. -* For strings, make sure that empty values are always empty strings or just - not set, but not ``nil`` (CSFLE doesn't support native ``null``). -* This operation requires application downtime.