Skip to content

Commit 2980681

Browse files
zach-carrnbbeeken
andauthored
(DOCSP-18745) Node CSFLE fundementals (#277)
* (DOCSP-18745) Node CSFLE fundementals Co-authored-by: Neal Beeken <[email protected]>
1 parent d5a5128 commit 2980681

File tree

3 files changed

+222
-1
lines changed

3 files changed

+222
-1
lines changed

source/fundamentals.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Fundamentals
1818
/fundamentals/logging
1919
/fundamentals/monitoring
2020
/fundamentals/gridfs
21+
/fundamentals/csfle
2122
/fundamentals/time-series
2223
/fundamentals/typescript
2324
/fundamentals/utf8-validation

source/fundamentals/csfle.txt

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
==================================
2+
Client-Side Field Level Encryption
3+
==================================
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
Overview
14+
--------
15+
16+
In this guide, you can learn how to install and use **Client-Side Field
17+
Level Encryption (CSFLE)** in the MongoDB Node.js driver.
18+
19+
CSFLE allows you to encrypt specific data fields within a document with
20+
your MongoDB client application before sending the data to the server.
21+
Starting in MongoDB 4.2 Enterprise, you can perform this client-side
22+
encryption automatically.
23+
24+
With CSFLE, your client application encrypts fields client-side without
25+
requiring any server-side configuration or directives. CSFLE is useful
26+
for situations in which applications must guarantee that unauthorized
27+
parties, including server administrators, cannot read the encrypted
28+
data.
29+
30+
This guide is a quick introduction to CSFLE using the Node.js driver.
31+
For in-depth information on how CSFLE works, see
32+
the :manual:`CSFLE reference </core/security-client-side-encryption/>`
33+
documentation. For a real-world scenario and implementation, see our
34+
`CSFLE Guide <https://docs.mongodb.com/drivers/security/client-side-field-level-encryption-guide>`_.
35+
36+
Installation
37+
------------
38+
39+
To get started with CSFLE in your client application, you need:
40+
41+
- the MongoDB Node.js driver
42+
- `mongodb-client-encryption <https://www.npmjs.com/package/mongodb-client-encryption>`__
43+
- ``mongocryptd`` if using automatic encryption (Enterprise or Atlas)
44+
45+
``mongodb-client-encryption``
46+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47+
48+
The ``mongodb-client-encryption`` module is the official client
49+
encryption module for the MongoDB Node.js driver. It contains bindings
50+
to communicate with the native library that manages the encryption.
51+
52+
Add it to your project using ``npm``:
53+
54+
.. code-block:: sh
55+
:copyable: true
56+
57+
npm install mongodb-client-encryption --save
58+
59+
``mongocryptd``
60+
~~~~~~~~~~~~~~~
61+
62+
``mongocryptd`` is launched automatically by the package, and it is used for
63+
automatic encryption. ``mongocryptd`` communicates with
64+
``mongodb-client-encryption`` to automatically encrypt the information
65+
specified by a user-provided
66+
:manual:`JSON Schema </reference/security-client-side-automatic-json-schema/>`.
67+
68+
For more detailed information on ``mongocryptd``, see the
69+
:manual:`mongocryptd reference documentation </reference/security-client-side-encryption-appendix/#mongocryptd>`
70+
71+
Example
72+
-------
73+
74+
The following example shows how to configure a CSFLE-enabled client
75+
with a local key and a JSON schema. Values in the ``ssn`` field are
76+
automatically encrypted before insertion, and decrypted when calling
77+
``find()`` with a CSFLE-enabled client.
78+
79+
.. warning::
80+
81+
MongoDB recommends using local key management only for testing
82+
purposes, and using a remote key management service
83+
for production.
84+
85+
An expanded example with support for remote key management services is
86+
available at MongoDB University's GitHub
87+
`Node CSFLE Example <https://github.com/mongodb-university/csfle-guides/tree/master/nodejs>`__.
88+
89+
.. note::
90+
91+
Auto encryption requires MongoDB **Enterprise** or **Atlas**.
92+
93+
To run this example, first complete the following steps:
94+
95+
- Save `master-key.txt <https://github.com/mongodb-university/csfle-guides/raw/master/nodejs/master-key.txt>`__
96+
to the same directory as this example code.
97+
- Start a ``mongod`` locally on the default port 27017.
98+
- Start a ``mongocryptd`` locally on the default port 27020.
99+
100+
.. code-block:: javascript
101+
102+
const { MongoClient, Binary } = require("mongodb");
103+
const { ClientEncryption } = require("mongodb-client-encryption");
104+
const fs = require("fs/promises");
105+
106+
async function getRegularClient() {
107+
const client = new MongoClient("mongodb://localhost:27017");
108+
return await client.connect();
109+
}
110+
111+
async function getCsfleEnabledClient(schemaMap) {
112+
const client = new MongoClient("mongodb://localhost:27017", {
113+
autoEncryption: {
114+
keyVaultNamespace: "encryption.__keyVault",
115+
kmsProviders: {
116+
local: {
117+
key: await fs.readFile("./master-key.txt"),
118+
},
119+
},
120+
schemaMap,
121+
},
122+
});
123+
return await client.connect();
124+
}
125+
126+
function createJsonSchemaMap(dataKey) {
127+
return {
128+
"users.ssns": {
129+
bsonType: "object",
130+
encryptMetadata: {
131+
keyId: [new Binary(Buffer.from(dataKey, "base64"), 4)],
132+
},
133+
properties: {
134+
ssn: {
135+
encrypt: {
136+
bsonType: "int",
137+
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
138+
},
139+
},
140+
},
141+
},
142+
};
143+
}
144+
145+
async function makeDataKey(client) {
146+
const encryption = new ClientEncryption(client, {
147+
keyVaultNamespace: "encryption.__keyVault",
148+
kmsProviders: {
149+
local: {
150+
key: await fs.readFile("./master-key.txt"),
151+
},
152+
},
153+
});
154+
155+
let dataKey = await encryption.createDataKey("local", {
156+
masterKey: null,
157+
});
158+
159+
return dataKey.toString("base64");
160+
}
161+
162+
async function run(regularClient, csfleClient) {
163+
try {
164+
165+
regularClient = await getRegularClient();
166+
167+
let dataKey = await makeDataKey(regularClient);
168+
console.log(
169+
"New dataKey created for this run:\n",
170+
dataKey
171+
);
172+
173+
const schemaMap = createJsonSchemaMap(dataKey);
174+
175+
csfleClient = await getCsfleEnabledClient(schemaMap);
176+
177+
const regularClientSsnsColl = regularClient
178+
.db("users")
179+
.collection("ssns");
180+
const csfleClientSsnsColl = csfleClient
181+
.db("users")
182+
.collection("ssns");
183+
184+
const exampleDocument = {
185+
name: "Jon Doe",
186+
ssn: 241014209,
187+
};
188+
189+
await csfleClientSsnsColl.updateOne(
190+
{ ssn: exampleDocument.ssn },
191+
{ $set: exampleDocument },
192+
{ upsert: true }
193+
);
194+
195+
const csfleFindResult = await csfleClientSsnsColl.findOne({
196+
ssn: exampleDocument.ssn,
197+
});
198+
console.log(
199+
"Document retrieved with csfle enabled client:\n",
200+
csfleFindResult
201+
);
202+
203+
const regularFindResult = await regularClientSsnsColl.findOne({
204+
name: "Jon Doe",
205+
});
206+
console.log(
207+
"Document retrieved with regular client:\n",
208+
regularFindResult
209+
);
210+
211+
} finally {
212+
if (regularClient) await regularClient.close();
213+
if (csfleClient) await csfleClient.close();
214+
}
215+
}
216+
217+
run().catch(error => {
218+
console.dir(error);
219+
process.exit(1);
220+
});

source/includes/fundamentals-sections.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Fundamentals section:
1313
- :doc:`Log Events in the Driver </fundamentals/logging>`
1414
- :doc:`Monitor Driver Events </fundamentals/monitoring>`
1515
- :doc:`Store and Retrieve Large Files in MongoDB </fundamentals/gridfs>`
16+
- :doc:`Encrypt Fields from the Client </fundamentals/csfle>`
1617
- :doc:`Create and Query Time Series Collection </fundamentals/time-series>`
1718
- :doc:`Specify Type Parameters with TypeScript </fundamentals/typescript>`
1819
- :doc:`Specify UTF-8 Validation Settings </fundamentals/utf8-validation>`
19-

0 commit comments

Comments
 (0)