Manage Data Encryption Keys

beta

Client-Side Field Level Encryption is available as a beta. The contentsof this page may change during the beta period.

New in version 4.2.

Client-side field level encryption uses data encryption keys forencryption and decryption. The mongo shellgetKeyVault() method returns a key vault object for creating,modifying, and deleting data encryption keys.

This page documents client-side field level encryption using themongo shell, and does not refer to any official MongoDB4.2-compatible driver. See the relevant documentation for driver-specific data encryption keymanagement methods and syntax.

Create a data encryption key

The following procedure uses the mongo shell to create adata encryption key for use with client-side field level encryption anddecryption. For guidance on data encryption key management using a4.2-compatible driver, see the documentation for that driver.

Create the database connection.

Client-side field level encryption requires a Key Management Service(KMS). Each tab corresponds to a supported KMS and containsinstructions specific to that KMS.

  • Amazon Web Services KMS
  • Locally Managed Key

Configuring client-side field level encryption for the AWS KMSrequires an AWS Access Key ID and its associated Secret AccessKey. The AWS Access Key must correspond to an IAM user withall List and Read permissions for the KMS service. Tomitigate the risk of the AWS Access Key ID or Secret leakinginto logs, this procedure passes those values into the shellusing environment variables.

Create a mongo shell session using the—eval,—shell, and—nodb options:

  1. mongo --eval "
  2. var AWS_ACCESS_KEY_ID = '$AWS_ACCESS_KEY_ID'
  3. var AWS_SECRET_ACCESS_KEY = '$AWS_SECRET_ACCESS_KEY'
  4. " \
  5. --shell --nodb

The example automatically opens a mongoshell without a connection to a MongoDB database. The—eval option set the AWS_ACCESS_KEY_ID andAWS_SECRET_ACCESS_KEY variables in the shell to the valueof the corresponding environment variable. The specifiedvariables are also supported by theAWS CLI.

Create a new variable for storing the client-side field levelencryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "aws" : {
  5. "accessKeyId" : AWS_ACCESS_KEY_ID,
  6. "secretAccessKey" : AWS_SECRET_ACCESS_KEY
  7. }
  8. }
  9. }

Configuring client-side field level encryption for a locallymanaged key requires specifying a base64-encoded 96-byte stringwith no line breaks. To mitigate the risk of the key leakinginto logs, this procedure passes the value into the mongoshell using an environment variable.

The following operation generates a key that meets thestated requirements and adds it to the users~/.profile. If the key DEV_LOCAL_KEY already exists,skip this operation.

  1. echo "export DEV_LOCAL_KEY=\"$(head -c 96 /dev/urandom | base64 | tr -d '\n')\"" >> ~/.profile

The host operating system may require logging out and into refresh the loaded environment variables. Alternatively,use source ~/.profile to manually refresh the shell.

Note

The host operating system or shell may have differentprocedures for setting persistent environment variables.Defer to the documentation for the host OS or shell fora more specific procedure.

Create a mongo shell session using the—eval,—shell and—nodb options.

  1. mongo --eval "var LOCAL_KEY = '$DEV_LOCAL_KEY' " \
  2. --shell --nodb

The example automatically opens a mongo shellwithout a connection to a MongoDB database. The —evaloption set the LOCAL_KEY variable in the mongo shell tothe value of the corresponding environment variable.

Create a new variable in the mongo shell for storing theclient-side field level encryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "local" : {
  5. "key" : BinData(0, LOCAL_KEY)
  6. }
  7. }
  8. }

Use the Mongo() constructor in the mongo shell toestablish a database connection to the target cluster. Configure theconnection for client-side field level encryption by specifying theClientSideFieldLevelEncryption document as the second parameter:

  1. csfleDatabaseConnection = Mongo(
  2. "mongodb://replaceMe.example.net:27017/?replicaSet=myMongoCluster",
  3. ClientSideFieldLevelEncryptionOptions
  4. )

Replace the replaceMe.example.net URI withthe connection string for the target cluster.

Use the csfleDatabaseConnection object to accessclient-side field level encryption shellmethods.

For complete documentation on establishing database connectionsconfigured for client-side field level encryption, see theMongo() constructor reference.

Create the key vault object.

Use the getKeyVault() method on thecsfleDatabaseConnection database connection object to create thekey vault object:

  1. keyVault = csfleDatabaseConnection.getKeyVault();

Important

Client-side field level encryption depends on server-enforceduniqueness of key alternate names. getKeyVault()creates a unique index onkeyAltNames if one does not exist. Do not drop theunique index created bygetKeyVault().

Create the data encryption key.

Use the KeyVault.createKey() method on the keyVaultobject to create a new data encryption key in the key vault.

  • Amazon Web Services KMS
  • Locally Managed Key
  1. keyVault.createKey(
  2. "aws",
  3. "arn:aws:kms:region:account:key/keystring",
  4. [ "keyAlternateName" ]
  5. )

The first parameter must be "aws" to specify the configuredAmazon Web Services KMS.

The second parameter must be the full Amazon Resource Name(ARN) of the Customer Master Key (CMK). MongoDB uses thespecified CMK to encrypt the data encryption key.

  1. keyVault.createKey(
  2. "local",
  3. "",
  4. [ "myFirstCSFLEDataKey" ]
  5. )

The first parameter must be local to specify theconfigured Locally Managed Key.

The second parameter must be an empty string. MongoDB doesnot use the value specified for this parameter.

The third parameter may be an array of one or more keyAltNamesfor the data encryption key. Each key alternate name must be unique.getKeyVault() creates a unique index on keyAltNames toenforce uniqueness on the field if one does not already exist. Keyalternate names facilitate data encryption key findability.

If successful, createKey() returns the UUID ofthe new data encryption key. The UUID is a BSON Binary (BinData) objectwith subtype 4 that uniquely identifies the data encryption key.The UUID string is the hexadecimal representation of theunderlying binary data.

Configuring official 4.2-compatible drivers for automaticclient-side field level encryption requires specifying the dataencryption key using the base64 representation of the UUID string.The following operation converts the UUID hexadecimal string toits base64 representation:

  1. UUID("b4b41b33-5c97-412e-a02b-743498346079").base64()

Manage a data encryption key’s alternate name

The following procedure uses the mongo shell to managethe alternate names of a data encryption key. For guidance on dataencryption key management using a 4.2-compatible driver, see thedocumentation for that driver.

Create the database connection.

Client-side field level encryption requires a Key Management Service(KMS). Each tab corresponds to a supported KMS and containsinstructions specific to that KMS.

  • Amazon Web Services KMS
  • Locally Managed Key

Configuring client-side field level encryption for the AWS KMSrequires an AWS Access Key ID and its associated Secret AccessKey. The AWS Access Key must correspond to an IAM user withall List and Read permissions for the KMS service. Tomitigate the risk of the AWS Access Key ID or Secret leakinginto logs, this procedure passes those values into the shellusing environment variables.

Create a mongo shell session using the—eval,—shell, and—nodb options:

  1. mongo --eval "
  2. var AWS_ACCESS_KEY_ID = '$AWS_ACCESS_KEY_ID'
  3. var AWS_SECRET_ACCESS_KEY = '$AWS_SECRET_ACCESS_KEY'
  4. " \
  5. --shell --nodb

The example automatically opens a mongoshell without a connection to a MongoDB database. The—eval option set the AWS_ACCESS_KEY_ID andAWS_SECRET_ACCESS_KEY variables in the shell to the valueof the corresponding environment variable. The specifiedvariables are also supported by theAWS CLI.

Create a new variable for storing the client-side field levelencryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "aws" : {
  5. "accessKeyId" : AWS_ACCESS_KEY_ID,
  6. "secretAccessKey" : AWS_SECRET_ACCESS_KEY
  7. }
  8. }
  9. }

Configuring client-side field level encryption for a locallymanaged key requires specifying a base64-encoded 96-byte stringwith no line breaks. To mitigate the risk of the key leakinginto logs, this procedure passes the value into the mongoshell using an environment variable.

The following operation generates a key that meets thestated requirements and adds it to the users~/.profile. If the key DEV_LOCAL_KEY already exists,skip this operation.

  1. echo "export DEV_LOCAL_KEY=\"$(head -c 96 /dev/urandom | base64 | tr -d '\n')\"" >> ~/.profile

The host operating system may require logging out and into refresh the loaded environment variables. Alternatively,use source ~/.profile to manually refresh the shell.

Note

The host operating system or shell may have differentprocedures for setting persistent environment variables.Defer to the documentation for the host OS or shell fora more specific procedure.

Create a mongo shell session using the—eval,—shell and—nodb options.

  1. mongo --eval "var LOCAL_KEY = '$DEV_LOCAL_KEY' " \
  2. --shell --nodb

The example automatically opens a mongo shellwithout a connection to a MongoDB database. The —evaloption set the LOCAL_KEY variable in the mongo shell tothe value of the corresponding environment variable.

Create a new variable in the mongo shell for storing theclient-side field level encryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "local" : {
  5. "key" : BinData(0, LOCAL_KEY)
  6. }
  7. }
  8. }

Use the Mongo() constructor in the mongo shell toestablish a database connection to the target cluster. Configure theconnection for client-side field level encryption by specifying theClientSideFieldLevelEncryption document as the second parameter:

  1. csfleDatabaseConnection = Mongo(
  2. "mongodb://replaceMe.example.net:27017/?replicaSet=myMongoCluster",
  3. ClientSideFieldLevelEncryptionOptions
  4. )

Replace the replaceMe.example.net URI withthe connection string for the target cluster.

Use the csfleDatabaseConnection object to accessclient-side field level encryption shellmethods.

For complete documentation on establishing database connectionsconfigured for client-side field level encryption, see theMongo() constructor reference.

Create the key vault object.

Use the getKeyVault() method on thecsfleDatabaseConnection database connection object to create thekey vault object:

  1. keyVault = csfleDatabaseConnection.getKeyVault();

Important

Client-side field level encryption depends on server-enforceduniqueness of key alternate names. getKeyVault()creates a unique index onkeyAltNames if one does not exist. Do not drop theunique index created bygetKeyVault().

Manage the data encryption key’s alternate name.

  • Add Key Alternate Name

Important

Client-side field level encryption depends on server-enforceduniqueness of key alternate names. Validate that a uniqueindex exists on keyAltNames prior to adding a newkey alternate name. If the unique index was dropped, you mustre-create it prior to addingany key alternate names.

Use the KeyVault.addKeyAlternateName() to add a newalternate name to a data encryption key:

  1. keyVault.addKeyAlternateName(
  2. UUID("<Replace Me With The UUID Of The Key To Modify"),
  3. "NewKeyAltNameForMyFirstCSFLEDataKey"
  4. )

The first parameter must be the UUID of the data encryption key tomodify.

The second parameter must be a unique string.getKeyVault() creates a unique index on keyAltNamesto enforce uniqueness of key alternate names.

KeyVault.addKeyAlternateName() returns the data encryptionkey document prior to modification. UseKeyVault.getKey() to retrive the modified data encryptionkey.

  1. keyVault.removeKeyAlternateName(
  2. UUID("<Replace Me With The UUID Of The Key To Modify"),
  3. "NewKeyAltNameForMyFirstCSFLEDataKey"
  4. )

The first parameter must be the UUID of the data encryption key tomodify.

The second parameter must be a string key alternate name.

KeyVault.removeKeyAlternateName() returns the dataencryption key prior to modification. UseKeyVault.getKey() to retrieve the modified data encryptionkey.

Remove a data encryption key

Warning

Deleting a data encryption key renders all fields encrypted usingthat key as permanently unreadable.

The following procedure uses the mongo shell to remove adata encryption key from the key vault. For guidance on data encryptionkey management using a 4.2-compatible driver, see the documentation forthat driver.

Create the database connection.

Client-side field level encryption requires a Key Management Service(KMS). Each tab corresponds to a supported KMS and containsinstructions specific to that KMS.

  • Amazon Web Services KMS
  • Locally Managed Key

Configuring client-side field level encryption for the AWS KMSrequires an AWS Access Key ID and its associated Secret AccessKey. The AWS Access Key must correspond to an IAM user withall List and Read permissions for the KMS service. Tomitigate the risk of the AWS Access Key ID or Secret leakinginto logs, this procedure passes those values into the shellusing environment variables.

Create a mongo shell session using the—eval,—shell, and—nodb options:

  1. mongo --eval "
  2. var AWS_ACCESS_KEY_ID = '$AWS_ACCESS_KEY_ID'
  3. var AWS_SECRET_ACCESS_KEY = '$AWS_SECRET_ACCESS_KEY'
  4. " \
  5. --shell --nodb

The example automatically opens a mongoshell without a connection to a MongoDB database. The—eval option set the AWS_ACCESS_KEY_ID andAWS_SECRET_ACCESS_KEY variables in the shell to the valueof the corresponding environment variable. The specifiedvariables are also supported by theAWS CLI.

Create a new variable for storing the client-side field levelencryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "aws" : {
  5. "accessKeyId" : AWS_ACCESS_KEY_ID,
  6. "secretAccessKey" : AWS_SECRET_ACCESS_KEY
  7. }
  8. }
  9. }

Configuring client-side field level encryption for a locallymanaged key requires specifying a base64-encoded 96-byte stringwith no line breaks. To mitigate the risk of the key leakinginto logs, this procedure passes the value into the mongoshell using an environment variable.

The following operation generates a key that meets thestated requirements and adds it to the users~/.profile. If the key DEV_LOCAL_KEY already exists,skip this operation.

  1. echo "export DEV_LOCAL_KEY=\"$(head -c 96 /dev/urandom | base64 | tr -d '\n')\"" >> ~/.profile

The host operating system may require logging out and into refresh the loaded environment variables. Alternatively,use source ~/.profile to manually refresh the shell.

Note

The host operating system or shell may have differentprocedures for setting persistent environment variables.Defer to the documentation for the host OS or shell fora more specific procedure.

Create a mongo shell session using the—eval,—shell and—nodb options.

  1. mongo --eval "var LOCAL_KEY = '$DEV_LOCAL_KEY' " \
  2. --shell --nodb

The example automatically opens a mongo shellwithout a connection to a MongoDB database. The —evaloption set the LOCAL_KEY variable in the mongo shell tothe value of the corresponding environment variable.

Create a new variable in the mongo shell for storing theclient-side field level encryption configuration document:

  1. var ClientSideFieldLevelEncryptionOptions = {
  2. "keyVaultNamespace" : "encryption.__dataKeys",
  3. "kmsProviders" : {
  4. "local" : {
  5. "key" : BinData(0, LOCAL_KEY)
  6. }
  7. }
  8. }

Use the Mongo() constructor in the mongo shell toestablish a database connection to the target cluster. Configure theconnection for client-side field level encryption by specifying theClientSideFieldLevelEncryption document as the second parameter:

  1. csfleDatabaseConnection = Mongo(
  2. "mongodb://replaceMe.example.net:27017/?replicaSet=myMongoCluster",
  3. ClientSideFieldLevelEncryptionOptions
  4. )

Replace the replaceMe.example.net URI withthe connection string for the target cluster.

Use the csfleDatabaseConnection object to accessclient-side field level encryption shellmethods.

For complete documentation on establishing database connectionsconfigured for client-side field level encryption, see theMongo() constructor reference.

Create the key vault object.

Use the getKeyVault() method on thecsfleDatabaseConnection database connection object to create thekey vault object:

  1. keyVault = csfleDatabaseConnection.getKeyVault();

Important

Client-side field level encryption depends on server-enforceduniqueness of key alternate names. getKeyVault()creates a unique index onkeyAltNames if one does not exist. Do not drop theunique index created bygetKeyVault().

Delete the data encryption key using its UUID.

Use the KeyVault.deleteKey() method on the keyVaultobject to delete a data key from the key vault:

  1. keyVault.deleteKey(UUID("<Replace Me With The UUID Of The Key To Delete"))