Client-Side Field Level Encryption: Use a KMS to Store the Master Key¶
Introduction¶
This guide shows you how to migrate from using Client-Side Field Level Encryption (CSFLE) with a locally-managed master key to one that uses a remote Key Management Service (KMS) and is intended for full-stack developers.
Currently, MongoDB drivers support the following Key Management Providers:
Once you complete the steps in this guide, you should have:
- a master key hosted by one of the supported remote Key Management Services
- a working client application that encrypts and decrypts the data encryption key using the KMS master key
Prerequisites¶
This guide requires that you completed the following:
- created a CSFLE-enabled client using our CSFLE guide
- decrypted any data encrypted while using a local KMS master key
Reasons to Use a Remote KMS¶
Choosing a remote KMS for master key management has the following advantages over using your local filesystem to host the master key:
- Secure storage of the key with access auditing
- Reduced risk of access permission issues
- Availability and distribution of the key to remote clients
- Automated key backup and recovery
- Centralized encryption key lifecycle management
Additionally, MongoDB trasmits the data encryption keys to the KMS for encryption and decryption, ensuring the Customer Master Key (CMK) is never exposed to the client.
Set up a Remote Master Key¶
Before you switch from a locally-managed master key to a remote KMS, you must decrypt all documents containing field-encrypted data if you want to keep it. Your existing data encryption keys can only be decrypted with the original locally-managed master key and not the CMK that the KMS generates.
Failure to decrypt all data at this stage may cause permanent and unrecoverable data loss.
The following steps explain the setup and updates necessary to move from a local key provider to a KMS. Select the tab that corresponds to your provider:
Create an AWS IAM User¶
Create a new programmatic IAM user in the AWS management console by following the official AWS documentation on Adding a User. CSFLE-enabled clients authenticate with AWS KMS using the IAM user to encrypt and decrypt the remote master key. Take note of the following IAM credentials needed to authenticate with the KMS:
- access key ID
- secret access key
- Grant the IAM user full
List
andRead
permissions for the KMS service. See Amazon's official documentation on Adding permissions to a user to set these permissions.
Create the Master Key¶
The following diagram shows the steps required to create a new master key on a KMS provider.

- To create a master key, log into your AWS management console and create a new symmetric master key in the KMS section. Choose a name and description that helps you identify it; these fields do not affect the functionality or configuration.
- In the Usage Permissions step of the key generation
process, add the full KMS
List
andRead
permissions to the IAM user you created in the previous step. This authorizes the user to encrypt and decrypt the new master key.
The new client IAM User should not have administrative permissions for the master key. We recommend that you follow the principle of least privilege to keep your data secure.
Specify the AWS KMS Provider Credentials¶
Unlike the local key provider, the AWS KMS provider does not read the master key directly from the client application. Instead, it accepts the Access Key ID and Secret Access Key configurations that point to the master key. The IAM user must have the permissions set up in the previous step in order for the client to use the KMS to encrypt and decrypt data encryption keys. Follow the steps below to specify your credentials:
First, identify the following authentication credentials on AWS KMS:
Field Required Description Access Key ID Yes Identifies the account user Secret Access Key Yes Contains the authentication credentials of the account user - Next, add your authentication credentials to your CSFLE-enabled client code:
kms_providers = { "aws": { "accessKeyId": "<IAM User Access Key ID>", "secretAccessKey": "<IAM User Secret Access Key>" } }
Create a New Data Encryption Key¶
To encrypt your data, you need a data encryption key generated from your KMS-hosted master key. The following diagram shows the requests you need to make from the client application to create and store a new data encryption key:

- First, specify the following information to access the master key:
Field | Required | Description |
---|---|---|
key | Yes | Amazon Resource Number (ARN) of the master key. |
region | No | AWS region of your master key, e.g. "us-west-2"; required only if not specified in your ARN. |
endpoint | No | Custom hostname for the AWS endpoint if configured for your account. |
- Once you have the required information, update and run the following code to generate the new data encryption key:
import pymongo from pymongo import MongoClient from pymongo.encryption_options import AutoEncryptionOpts from bson.binary import STANDARD from bson.codec_options import CodecOptions connection_string = "mongodb://localhost:27017" key_vault_namespace = "encryption.__keyVault" fle_opts = AutoEncryptionOpts( kms_providers, # pass in the kms_providers from the previous step key_vault_namespace ) client_encryption = pymongo.encryption.ClientEncryption( { "aws": { "accessKeyId": "<IAM User Access Key ID>", "secretAccessKey": "<IAM User Secret Access Key>" } }, key_vault_namespace, client, CodecOptions(uuid_representation=STANDARD) ) data_key_id = client_encryption.create_data_key("aws")
To use AWS KMS, you must use pymongocrypt version 1.0 or later in your application's environment.
Update the Automatic Encryption JSON Schema¶
If you previously embedded the key ID of your data encryption key in your automatic encryption rules, update the JSON Schema with your new data encryption key ID.
Your client application is now ready to automatically encrypt your data using the master key on your KMS provider.
Further Reading¶
For more information on client-side field level encryption in MongoDB, check out the reference documentation in the MongoDB server manual: