MongoDB Queryable Encryption
Specific fields stay queryable — for equality or range — while remaining encrypted client-side end to end.
Overview
MongoDB Queryable Encryption (QE) keeps fields encrypted client-side, the same way CSFLE does, but with one key difference: specific fields can still be queried — for equality, or for a numeric/date range — without the server ever seeing plaintext or a value it can otherwise correlate the way a deterministic CSFLE field can. Each queryable field carries its own Data Encryption Key (DEK), and those DEKs are wrapped by a Customer Master Key (CMK) — a DuoKey vault key.
This app's role mirrors CSFLE: it provisions and manages the CMK, and it emits the two artifacts the MongoDB driver needs — the encryptedFieldsMap (which fields are QE-encrypted, and with which query type) and the CMK reference (KMS provider plus key ID) the driver passes as the masterKey when creating a DEK.
The server still never sees plaintext — but for declared fields, it can match encrypted structures without decrypting.
| Property | Value |
|---|---|
| Encryption model | Client-side field-level encryption — queryable (equality / range) or non-queryable per field |
| Key custody | DuoKey vault key acts as the CMK wrapping per-field DEKs |
| Onboarding | App detail page — no wizard entry |
| Proof status | The emitted `encryptedFieldsMap` and CMK reference are real and usable as-is; the self-test is currently simulated — see below |
CSFLE vs. Queryable Encryption
| CSFLE | Queryable Encryption | |
|---|---|---|
| What the server sees | Opaque ciphertext, never queryable | Ciphertext, but structured so equality/range queries still work |
| Query support | None on encrypted fields (unless deterministic, and then only exact equality with a correlation trade-off) | Equality and range predicates on declared fields, without deterministic ciphertext repetition |
| Per-field configuration | A single encryption schema (deterministic or random) per field | Each field declares a query_type: equality, range (with optional min/max bounds), or none |
| Key custody model | CMK wraps per-field DEKs | Same — CMK wraps per-field DEKs |
Use CSFLE when a field never needs to be queried, or only ever needs exact-match lookups and you accept the correlation trade-off of deterministic encryption. Use Queryable Encryption when you need equality or range queries on an encrypted field without that trade-off — for example, filtering patient records by an encrypted date-of-birth range. See MongoDB CSFLE for the simpler model.
How an equality or range query stays server-side
This is the step CSFLE's model cannot do. A CSFLE field is opaque ciphertext end to end — the server can store and return it, but never compare it. A Queryable Encryption field uses a structured, searchable encryption scheme: the driver turns a query predicate into an encrypted token, and MongoDB compares that token against encrypted index structures for the field — matching without ever decrypting.
Step 3 is what CSFLE cannot do: the server matches encrypted structures for a declared field instead of only storing opaque ciphertext.
A field is declared for one query type at a time — equality or range — matching the query_type in its field declaration (see below). This mirrors MongoDB's own constraint: a queryable-encrypted field supports the query type it was configured for, not arbitrary predicates.
Configuration
| Field | Purpose | ||
|---|---|---|---|
mongodb_uri | database | collection | Connection URI and target collection whose fields are QE-encrypted. |
key_vault_namespace | Namespace (`database.collection`) MongoDB uses to store encrypted data keys. Defaults to `encryption.__keyVault`. | ||
kms_provider | KMS provider type wrapping the DEKs — `kmip` (DuoKey), `aws`, `azure`, `gcp`, or `local`. | ||
cmk_key_id | The DuoKey vault key acting as the Customer Master Key. | ||
fields | The declared queryable-encrypted fields (see below). |
Field declarations
Each entry in fields declares one document field to bring under Queryable Encryption:
| Property | Purpose | |
|---|---|---|
path | Dotted field path within the document, e.g. `ssn` or `patient.dob`. | |
bson_type | BSON type of the field (`string`, `int`, `long`, `date`, `decimal`, …). Defaults to `string`. | |
query_type | `equality`, `range`, or `none` (encrypted but not queryable). Defaults to `equality`. | |
min | max | Optional inclusive bounds for a `range` field. |
What gets emitted
Deploying the app returns the CMK reference and the encryptedFieldsMap, ready to pass into the MongoDB driver's AutoEncryptionOpts or db.createCollection(..., { encryptedFields }).
{
"provider": "kmip",
"key_id": "<cmk-vault-key-id>",
"key_vault_namespace": "encryption.__keyVault",
"endpoint_guid": "<app-endpoint-guid>"
}{
"medical.patients": {
"fields": [
{
"path": "ssn",
"bsonType": "string",
"keyId": null,
"queries": [{ "queryType": "equality" }]
},
{
"path": "age",
"bsonType": "int",
"keyId": null,
"queries": [{ "queryType": "range", "min": 0, "max": 150 }]
},
{
"path": "notes",
"bsonType": "string",
"keyId": null
}
]
}
}A null keyId instructs the MongoDB driver to auto-create a per-field DEK on first use, wrapped by the CMK above. The notes field above has no queries array — it is encrypted but deliberately not queryable, matching a query_type of none.
Health and self-test
| Check | What it reports | Live probe today |
|---|---|---|
| Health | MongoDB reachability, key vault access, CMK reachability | No — returns a fixed healthy status envelope |
| Self-test | MongoDB connection, key vault access, CMK wrap/unwrap, equality/range query round-trip | No — all four checks return a hardcoded pass |
The handler behavior for enable/disable/health/self-test is simulated — there is no live MongoDB round-trip yet. But the encryptedFieldsMap and CMK reference shown above are not placeholders: they are generated from your actual field declarations and vault key, and can be used as-is in a driver's AutoEncryptionOpts.
Queryable Encryption's encryptedFields must be supplied when the collection is created — you cannot retroactively enable it on an existing collection's existing documents.