From 5d379daf03b41569fd3ac8fbff3366ea58eb1a1b Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 18 Oct 2022 14:33:19 +0200 Subject: [PATCH 1/4] PHPLIB-986: Split keyAltName example and link key management docs --- docs/tutorial/client-side-encryption.txt | 40 ++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/client-side-encryption.txt b/docs/tutorial/client-side-encryption.txt index 6ed2e00d4..fbb574bfb 100644 --- a/docs/tutorial/client-side-encryption.txt +++ b/docs/tutorial/client-side-encryption.txt @@ -202,6 +202,15 @@ specified when creating the key. The following example creates an encryption key with an alternative name, which could be done when deploying the application. The software then encrypts data by referencing the key by its alternative name. +Creating the encryption key +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To create the encryption key, create a client instance with encryption options +and create a new data key. You can pass multiple alternate names for this key +and later reference the key by these alternate names instead of the key ID. +Creating a new data encryption key would typically be done on initial deployment, +but depending on your use-case you may want to use more than one encryption key. + .. code-block:: php createClientEncryption($clientEncryptionOpts); - // Create an encryption key with an alternative name. This could be done when - // deploying the application + // Create an encryption key with an alternate name. $keyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['altname']]); +Using an encryption key by alternate name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use an alternate name when referencing an encryption key, use the +``keyAltName`` option instead of ``keyId``. + +.. code-block:: php + + ', Binary::TYPE_GENERIC); + + $clientEncryptionOpts = [ + 'keyVaultNamespace' => 'encryption.__keyVault', + 'kmsProviders' => [ + 'local' => ['key' => $localKey], + ], + ]; + + $client = new Client(); + $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); + $collection = $client->selectCollection('test', 'coll'); $collection->drop(); // clear old data @@ -329,3 +363,5 @@ query on the ``encryptedIndexed`` field. $unencryptedCollection = $client->selectCollection('test', 'coll'); var_dump($unencryptedCollection->findOne(['_id' => 1])); + +.. seealso:: :manual:`Encryption Key Management ` in the MongoDB manual From 3fcb260decc612104c2a9de9bac59e8cdf2c3cbc Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 19 Oct 2022 13:58:08 +0200 Subject: [PATCH 2/4] Apply grammar suggestions --- docs/tutorial/client-side-encryption.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/tutorial/client-side-encryption.txt b/docs/tutorial/client-side-encryption.txt index fbb574bfb..3ab8892d5 100644 --- a/docs/tutorial/client-side-encryption.txt +++ b/docs/tutorial/client-side-encryption.txt @@ -196,20 +196,20 @@ Referencing Encryption Keys by an Alternative Name While it is possible to create an encryption key every time data is encrypted, this is not the recommended approach. Instead, you should create your encryption -keys depending on your use-case, e.g. by creating a user-specific encryption +keys depending on your use case, e.g. by creating a user-specific encryption key. To reference keys in your software, you can use the keyAltName attribute specified when creating the key. The following example creates an encryption key with an alternative name, which could be done when deploying the application. The software then encrypts data by referencing the key by its alternative name. -Creating the encryption key +Creating the Encryption Key ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To create the encryption key, create a client instance with encryption options and create a new data key. You can pass multiple alternate names for this key and later reference the key by these alternate names instead of the key ID. Creating a new data encryption key would typically be done on initial deployment, -but depending on your use-case you may want to use more than one encryption key. +but depending on your use case you may want to use more than one encryption key. .. code-block:: php @@ -231,10 +231,10 @@ but depending on your use-case you may want to use more than one encryption key. $client = new Client(); $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); - // Create an encryption key with an alternate name. + // Create an encryption key with an alternate name $keyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['altname']]); -Using an encryption key by alternate name +Using an Encryption Key by Alternate Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use an alternate name when referencing an encryption key, use the From 670d3af61f79fc58ae6677f40ce5ef4f9b92d0f0 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 19 Oct 2022 14:15:57 +0200 Subject: [PATCH 3/4] Move key creation to top of csfle tutorial --- docs/tutorial/client-side-encryption.txt | 131 ++++++++++++----------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/docs/tutorial/client-side-encryption.txt b/docs/tutorial/client-side-encryption.txt index 3ab8892d5..9bccb55ed 100644 --- a/docs/tutorial/client-side-encryption.txt +++ b/docs/tutorial/client-side-encryption.txt @@ -14,6 +14,50 @@ Client-Side Field Level Encryption allows administrators and developers to encrypt specific data fields in addition to other MongoDB encryption features. +Creating an Encryption Key +-------------------------- + +.. note:: + + The following examples use a local master key; however, other key providers + such as AWS KMS are also an option. This master key is used to encrypt data + keys that are stored locally. It is important that you keep this key secure. + +To create an encryption key, create a :php:`MongoDB\\Driver\\ClientEncryption ` +instance with encryption options and create a new data key. The method will +return the key ID which can be used to reference the key later. You can also +pass multiple alternate names for this key and reference the key by these names +instead of the key ID. Creating a new data encryption key would typically be +done on initial deployment, but depending on your use case you may want to use +more than one encryption key or create them dynamically. + +.. code-block:: php + + ', Binary::TYPE_GENERIC); + + $clientEncryptionOpts = [ + 'keyVaultNamespace' => 'encryption.__keyVault', + 'kmsProviders' => [ + 'local' => ['key' => $localKey], + ], + ]; + + $client = new Client(); + $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); + + // Create an encryption key with an alternate name + // To store the key ID for later use, you can use serialize or var_export + $keyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['my-encryption-key']]); + +.. seealso:: :manual:`Encryption Key Management ` in the MongoDB manual + + Automatic Encryption and Decryption ----------------------------------- @@ -21,9 +65,10 @@ Automatic Encryption and Decryption Auto encryption is an enterprise only feature. -The following example uses a local key; however, other key providers such as AWS -are also an option. The data in the ``encryptedField`` field is automatically -encrypted on insertion and decrypted when querying on the client side. +The following example sets up a collection with automatic encryption based on a +``$jsonSchema`` validator. The data in the ``encryptedField`` field is +automatically encrypted on insertion and decrypted when reading on the client +side. .. code-block:: php @@ -34,7 +79,6 @@ encrypted on insertion and decrypted when querying on the client side. use MongoDB\Driver\ClientEncryption; $localKey = new Binary('', Binary::TYPE_GENERIC); - $encryptionOpts = [ 'keyVaultNamespace' => 'encryption.__keyVault', 'kmsProviders' => [ @@ -43,13 +87,13 @@ encrypted on insertion and decrypted when querying on the client side. ]; $client = new Client(); - $clientEncryption = $client->createClientEncryption($encryptionOpts); $database = $client->selectDatabase('test'); $database->dropCollection('coll'); // remove old data - // Create new key in the key vault and store its ID for later use - $keyId = $clientEncryption->createDataKey('local'); + // This uses the key ID from the first example. The key ID could be read from + // configuration. + $keyId = readDataKey(); $database->createCollection('coll', [ 'validator' => [ @@ -80,9 +124,8 @@ encrypted on insertion and decrypted when querying on the client side. Specifying an Explicit Schema for Encryption -------------------------------------------- -The following example shows how to create a new key and store it in the key -vault collection. The encrypted client configures an explicit schema for -encryption using the newly created key. +The following example uses the ``schemaMap`` encryption option to define +encrypted fields. .. note:: @@ -101,18 +144,11 @@ encryption using the newly created key. $localKey = new Binary('', Binary::TYPE_GENERIC); - $clientEncryptionOpts = [ - 'keyVaultNamespace' => 'encryption.__keyVault', - 'kmsProviders' => [ - 'local' => ['key' => $localKey], - ], - ]; - $client = new Client(); - $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); - // Create new key in the key vault and store its ID for later use - $keyId = $clientEncryption->createDataKey('local'); + // This uses the key ID from the first example. The key ID could be read from + // configuration. + $keyId = readDataKey(); $autoEncryptionOpts = [ 'keyVaultNamespace' => 'encryption.__keyVault', @@ -148,10 +184,10 @@ encryption using the newly created key. Manually Encrypting and Decrypting Values ----------------------------------------- -In the MongoDB Community Edition, you will have to manually encrypt and decrypt -values before storing them in the database. The following example assumes that -you have already created an encryption key in the key vault collection and -explicitly encrypts and decrypts values in the document. +In the MongoDB Community Edition, you will have to manually encrypt values +before storing them in the database. The following example assumes that you have +already created an encryption key in the key vault collection and explicitly +encrypts and decrypts values in the document. .. code-block:: php @@ -173,8 +209,9 @@ explicitly encrypts and decrypts values in the document. $client = new Client(); $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); - // Create new key in the key vault and store its ID for later use - $keyId = $clientEncryption->createDataKey('local'); + // This uses the key ID from the first example. The key ID could be read from + // configuration. + $keyId = readDataKey(); $collection = $client->selectCollection('test', 'coll'); $collection->drop(); // clear old data @@ -202,41 +239,6 @@ specified when creating the key. The following example creates an encryption key with an alternative name, which could be done when deploying the application. The software then encrypts data by referencing the key by its alternative name. -Creating the Encryption Key -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To create the encryption key, create a client instance with encryption options -and create a new data key. You can pass multiple alternate names for this key -and later reference the key by these alternate names instead of the key ID. -Creating a new data encryption key would typically be done on initial deployment, -but depending on your use case you may want to use more than one encryption key. - -.. code-block:: php - - ', Binary::TYPE_GENERIC); - - $clientEncryptionOpts = [ - 'keyVaultNamespace' => 'encryption.__keyVault', - 'kmsProviders' => [ - 'local' => ['key' => $localKey], - ], - ]; - - $client = new Client(); - $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); - - // Create an encryption key with an alternate name - $keyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['altname']]); - -Using an Encryption Key by Alternate Name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - To use an alternate name when referencing an encryption key, use the ``keyAltName`` option instead of ``keyId``. @@ -263,9 +265,10 @@ To use an alternate name when referencing an encryption key, use the $collection = $client->selectCollection('test', 'coll'); $collection->drop(); // clear old data - // Reference the encryption key we created earlier by its alternative name + // Reference the encryption key created in the first example by its + // alternative name $encryptionOpts = [ - 'keyAltName' => 'altname', + 'keyAltName' => 'my-encryption-key', 'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, ]; $encryptedValue = $clientEncryption->encrypt('123456789', $encryptionOpts); @@ -363,5 +366,3 @@ query on the ``encryptedIndexed`` field. $unencryptedCollection = $client->selectCollection('test', 'coll'); var_dump($unencryptedCollection->findOne(['_id' => 1])); - -.. seealso:: :manual:`Encryption Key Management ` in the MongoDB manual From b9b4667076fd3375687ef8c9e6ae1d94ac84d196 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Fri, 21 Oct 2022 09:39:15 +0200 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Jeremy Mikola --- docs/tutorial/client-side-encryption.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/client-side-encryption.txt b/docs/tutorial/client-side-encryption.txt index 9bccb55ed..10a3a56ca 100644 --- a/docs/tutorial/client-side-encryption.txt +++ b/docs/tutorial/client-side-encryption.txt @@ -92,7 +92,7 @@ side. $database->dropCollection('coll'); // remove old data // This uses the key ID from the first example. The key ID could be read from - // configuration. + // a configuration file. $keyId = readDataKey(); $database->createCollection('coll', [ @@ -147,7 +147,7 @@ encrypted fields. $client = new Client(); // This uses the key ID from the first example. The key ID could be read from - // configuration. + // a configuration file. $keyId = readDataKey(); $autoEncryptionOpts = [ @@ -210,7 +210,7 @@ encrypts and decrypts values in the document. $clientEncryption = $client->createClientEncryption($clientEncryptionOpts); // This uses the key ID from the first example. The key ID could be read from - // configuration. + // a configuration file. $keyId = readDataKey(); $collection = $client->selectCollection('test', 'coll');