Skip to content

Commit f00f123

Browse files
add support for encrypted schemas
1 parent 39886fb commit f00f123

File tree

5 files changed

+780
-34
lines changed

5 files changed

+780
-34
lines changed

.eslintrc.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ module.exports = {
1414
'**/docs/js/native.js',
1515
'!.*',
1616
'node_modules',
17-
'.git'
17+
'.git',
18+
'data',
19+
'.config'
1820
],
1921
overrides: [
2022
{

docs/field-level-encryption.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,41 @@ With the above connection, if you create a model named 'Test' that uses the 'tes
112112
const Model = mongoose.model('Test', mongoose.Schema({ name: String }));
113113
await Model.create({ name: 'super secret' });
114114
```
115+
116+
## Automatic FLE in Mongoose
117+
118+
Mongoose supports the declaration of encrypted schemas - schemas that, when connected to a model, utilize MongoDB's Client Side
119+
Field Level Encryption or Queryable Encryption under the hood. Mongoose automatically generates either an `encryptedFieldsMap` or a
120+
`schemaMap` when instantiating a MongoClient and encrypts fields on write and decrypts fields on reads.
121+
122+
### Encryption types
123+
124+
MongoDB has to different automatic encryption implementations: client side field level encryption (CSFLE) and queryable encryption (QE).
125+
See [choosing an in-use encryption approach](https://www.mongodb.com/docs/v7.3/core/queryable-encryption/about-qe-csfle/#choosing-an-in-use-encryption-approach).
126+
127+
### Declaring Encrypted Schemas
128+
129+
The following schema declares two properties, `name` and `ssn`. `ssn` is encrypted using queryable encryption, and
130+
is configured for equality queries:
131+
132+
```javascript
133+
const encryptedUserSchema = new Schema({
134+
name: String,
135+
ssn: {
136+
type: String,
137+
// 1
138+
encrypt: {
139+
keyId: '<uuid string of key id>',
140+
queries: 'equality'
141+
}
142+
}
143+
// 2
144+
}, { encryptionType: 'queryable encryption' });
145+
```
146+
147+
To declare a field as encrypted, you must:
148+
149+
1. Annotate the field with encryption metadata in the schema definition
150+
2. Choose an encryption type for the schema and configure the schema for the encryption type
151+
152+
Not all schematypes are supported for CSFLE and QE. For an overview of valid schema types, refer to MongoDB's documentation.

lib/encryption_utils.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
const { Array } = require('./schema/index.js');
4+
const SchemaBigInt = require('./schema/bigint');
5+
const SchemaBoolean = require('./schema/boolean');
6+
const SchemaBuffer = require('./schema/buffer');
7+
const SchemaDate = require('./schema/date');
8+
const SchemaDecimal128 = require('./schema/decimal128');
9+
const SchemaDouble = require('./schema/double');
10+
const SchemaInt32 = require('./schema/int32');
11+
const SchemaObjectId = require('./schema/objectId');
12+
const SchemaString = require('./schema/string');
13+
14+
/**
15+
* Given a schema and a path to a field in the schema, this returns the
16+
* BSON type of the field, if it can be determined. This method specifically
17+
* **only** handles BSON types that are used for CSFLE and QE - any other
18+
* BSON types will return `null`. (example: MinKey and MaxKey).
19+
*
20+
* @param {import('.').Schema} schema
21+
* @param {string} path
22+
* @returns
23+
*/
24+
function inferBSONType(schema, path) {
25+
const type = schema.path(path);
26+
27+
if (type instanceof SchemaString) {
28+
return 'string';
29+
}
30+
31+
if (type instanceof SchemaInt32) {
32+
return 'int';
33+
}
34+
35+
if (type instanceof SchemaBigInt) {
36+
return 'long';
37+
}
38+
39+
if (type instanceof SchemaBoolean) {
40+
return 'bool';
41+
}
42+
43+
if (type instanceof SchemaDate) {
44+
return 'date';
45+
}
46+
47+
if (type instanceof SchemaBuffer) {
48+
return 'binData';
49+
}
50+
51+
if (type instanceof SchemaObjectId) {
52+
return 'objectId';
53+
}
54+
55+
if (type instanceof SchemaDecimal128) {
56+
return 'decimal';
57+
}
58+
59+
if (type instanceof SchemaDouble) {
60+
return 'double';
61+
}
62+
63+
if (type instanceof Array) {
64+
return 'array';
65+
}
66+
67+
return null;
68+
}
69+
70+
module.exports = {
71+
inferBSONType
72+
};

0 commit comments

Comments
 (0)