๐ Queryable Encryption
Introductionโ
Queryable Encryption is a groundbreaking technology that allows you to run specific queries on encrypted data without the need to decrypt it on the server. In MongoDB, this means sensitive data can remain encrypted throughout its lifecycle โ at rest, in transit, and even during query processing. By enabling Queryable Encryption, you significantly reduce the attack surface by minimizing the exposure of plaintext data, even to authorized database administrators. This strengthens your security posture and helps meet stringent compliance requirements.
Why is Queryable Encryption Important in MongoDB?โ
MongoDB, while offering various security features, can benefit significantly from Queryable Encryption for scenarios involving highly sensitive data. By implementing it, you ensure:
- Enhanced Data Protection: Sensitive data remains encrypted even when it is being processed on the database side, minimizing the risk of exposure in case of a security breach or unauthorized access.
- Compliance with Regulations: Helps meet stringent data privacy regulations like GDPR, HIPAA, and others that mandate strong encryption and control over sensitive information.
- Reduced Insider Threat: Even database administrators or authorized personnel with access to the database infrastructure cannot see the plaintext data without the appropriate decryption keys managed outside of the database.
- Maintain Functionality: Unlike traditional encryption where data needs to be decrypted for querying, Queryable Encryption allows you to perform specific types of queries directly on the encrypted data, preserving application functionality.
Overviewโ
- MongoDB Atlas
- On-Premises
In MongoDB Atlas, Queryable Encryption is available for:
- M10 or larger clusters
- MongoDB 7.0 or later
- Enterprise or Atlas deployments
To enable Queryable Encryption:
- Create an encryption key in your preferred Key Management System (local, AWS KMS, Azure Key Vault, GCP KMS)
- Configure your Atlas cluster to use the KMS provider
- Use the MongoDB driver with Queryable Encryption support
For self-hosted MongoDB deployments:
- Requires Enterprise Edition for Client Side Level Encryption (community versions support Queryable Encryption only)
- MongoDB 7.0 or later
- A supported Key Management System
Configuration steps:
- Set up a Key Management System
- Configure mongod with encryption settings
- Use the MongoDB driver with Queryable Encryption support
Key Concepts in Queryable Encryption:โ
- Key Management System (KMS): A secure system for managing encryption keys. MongoDB Queryable Encryption relies on either local keys/on-premises vaults like Hasicorp, or external KMS providers like AWS KMS, Azure Key Vault, Google Cloud KMS to store and manage the cryptographic keys.
- Encryption on Field Level Basis: Encryption and decryption operations are performed on the client-side application before data is sent to or retrieved from the MongoDB server. This ensures that the server only handles encrypted data.
- Encryption Schema: Defines which fields in your documents need to be encrypted and specifies the type of encryption to be used for each field, influencing the types of queries that can be performed on that field.
Implementationโ
Setting Up Queryable Encryptionโ
- Configure KMS Provider: This step configures the Key Management System (KMS) provider. In this example, it shows how to configure AWS KMS by providing access key ID and secret access key. It also shows how to configure a master key with its key, region, and endpoint.
const kmsProviders = {
aws: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
}
};
const masterKey = {
key: process.env.MASTER_KEY,
region: "us-east-1",
endpoint: "kms.us-east-1.amazonaws.com"
};
Or local key: This shows how to configure a local key for testing purposes.
local_master_key = os.urandom(96)
kms_providers = {"local": {"key": local_master_key}}
- Create Client Encryption: This step creates a client with auto encryption options.
encrypted_client = MongoClient(
new_connection, auto_encryption_opts=auto_encryption_options)
- Define Encryption Schema: This step defines the encryption schema for the fields that need to be encrypted. In this example, the "accountNumber" field is configured for equality queries.
encrypted_fields_map = {
"fields": [
{
"path": "accountNumber",
"bsonType": "string",
"queries": [{"queryType": "equality"}] # potentially 'range'
}
]
}
;
Using Encrypted Fieldsโ
Creating & Querying Documents with Encrypted Fieldsโ
The following example demonstrates the complete workflow for creating and querying documents with encrypted fields:
# Step 1: Initialize the encrypted client with auto-encryption options
# This client automatically handles encryption/decryption of specified fields
encrypted_client = MongoClient(
new_connection, auto_encryption_opts=auto_encryption_options)
# Step 2: Set up the client encryption object
# This object manages the encryption keys and handles the encryption operations
client_encryption = ClientEncryption(
kms_providers=kms_providers,
key_vault_namespace=key_vault_namespace,
key_vault_client=encrypted_client,
codec_options=CodecOptions()
)
# Step 3: Create an encrypted collection with the specified encryption schema
# This sets up the collection with automatic field-level encryption
client_encryption.create_encrypted_collection(
encrypted_client[encrypted_database_name],
encrypted_collection_name,
encrypted_fields_map,
kms_provider_name,
{},
)
# Step 4: Prepare a document with sensitive information
# Note: The 'accountNumber' field will be automatically encrypted based on the schema
doc = {
"owner": "Jon Doe",
"accountNumber": "987-65-4320", # This field will be encrypted
"billing": {
"type": "Visa",
"number": "4111111111111111", # Consider encrypting this field too
}
}
# Step 5: Get a reference to the encrypted collection
encrypted_collection = encrypted_client[encrypted_database_name][encrypted_collection_name]
# Step 6: Insert the document
# The encryption happens automatically for the specified fields
result = encrypted_collection.insert_one(doc)
print(f"Inserted document ID: {result.inserted_id}")
# Step 7: Query the encrypted collection
# You can query encrypted fields normally - the encryption/decryption is handled automatically
find_result = encrypted_collection.find_one({
"accountNumber": "987-65-4320" # The query value is automatically encrypted
})
print(find_result) # The result is automatically decrypted when retrieved
This example demonstrates the power of Queryable Encryption - you can work with encrypted data as if it were normal data, while the encryption and decryption happen automatically in the background based on your schema configuration.
Supported Query Typesโ
Queryable Encryption supports various query types depending on the encryption algorithm:
-
Equality Queries
- Exact matches on encrypted fields
- Supported with deterministic encryption
- Example:
{"encryptedField": "exactValue"}
-
Range Queries
- Comparison operators ($gt, $gte, $lt, $lte)
- Available for range-queryable encrypted fields
- Example:
{"encryptedField": {"$gt": "value"}}
- Requires RangePreview algorithm
Best Practicesโ
-
Key Management
- Securely Manage KMS Credentials: Protect your KMS access keys and credentials diligently. Use best practices for secret management.
- Regularly rotate encryption keys
- Securely store and backup keys
- Use separate keys for different environments
-
Performance Considerations
- Understand Performance Implications: Queryable Encryption involves additional resources for indexing and storage on the server side. Test and optimize your application accordingly. Tune the relevant parameters and document design for best performance.
- Index encrypted fields when needed
- Monitor query performance on encrypted fields
- Use appropriate encryption algorithms
-
Security Guidelines
- Principle of Least Privilege: Grant only the necessary permissions to access encryption keys.
- Follow the principle of least privilege
- Encrypt only necessary fields
- Regularly audit encryption configurations
Challenges and Exercisesโ
For hands-on practice with Queryable Encryption concepts, check out our practical challenges.
Next Stepsโ
After implementing Queryable Encryption, you can reach the final closing phase of Additional Security Considerations and Summary.