Skip to content

Commit 4bc0120

Browse files
committed
commit
1 parent ee09cba commit 4bc0120

14 files changed

+2848
-69
lines changed

.gitignore copy

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
*.lcov
24+
25+
# nyc test coverage
26+
.nyc_output
27+
28+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29+
.grunt
30+
31+
# Bower dependency directory (https://bower.io/)
32+
bower_components
33+
34+
# node-waf configuration
35+
.lock-wscript
36+
37+
# Compiled binary addons (https://nodejs.org/api/addons.html)
38+
build/Release
39+
40+
# Dependency directories
41+
node_modules/
42+
jspm_packages/
43+
44+
# TypeScript v1 declaration files
45+
typings/
46+
47+
# TypeScript cache
48+
*.tsbuildinfo
49+
50+
# Optional npm cache directory
51+
.npm
52+
53+
# Optional eslint cache
54+
.eslintcache
55+
56+
# Microbundle cache
57+
.rpt2_cache/
58+
.rts2_cache_cjs/
59+
.rts2_cache_es/
60+
.rts2_cache_umd/
61+
62+
# Optional REPL history
63+
.node_repl_history
64+
65+
# Output of 'npm pack'
66+
*.tgz
67+
68+
# Yarn Integrity file
69+
.yarn-integrity
70+
71+
# dotenv environment variables file
72+
.env
73+
.env.test
74+
75+
# parcel-bundler cache (https://parceljs.org/)
76+
.cache
77+
78+
# Next.js build output
79+
.next
80+
81+
# Nuxt.js build / generate output
82+
.nuxt
83+
dist
84+
85+
# Gatsby files
86+
.cache/
87+
# Comment in the public line in if your project uses Gatsby and *not* Next.js
88+
# https://nextjs.org/blog/next-9-1#public-directory-support
89+
# public
90+
91+
# vuepress build output
92+
.vuepress/dist
93+
94+
# Serverless directories
95+
.serverless/
96+
97+
# FuseBox cache
98+
.fusebox/
99+
100+
# DynamoDB Local files
101+
.dynamodb/
102+
103+
# TernJS port file
104+
.tern-port

README.md

+97-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,100 @@
1-
# MonogDB Field Level Encryption Node Demo
1+
# MonogDB Client Side Field Level Encryption (CSFLE) Node.js Demo
2+
3+
This guide shows you how to implement automatic Client-Side Field Level Encryption (CSFLE) using supported MongoDB drivers and is intended for full-stack developers. The guide presents the following information in the context of a real-world scenario.
4+
5+
Once you complete the steps in this guide, you should have:
6+
7+
* an understanding of how client-side field level encryption works and in what situations it is practical
8+
* a working client application that demonstrates automatic CSFLE
9+
* resources on how to move the sample client application to production
10+
11+
## Running Locally
12+
13+
### Requirements
14+
15+
* MongoDB Atlas 4.2+
16+
* MongoDB Node driver 3.6.2+
17+
* The libmongocrypt library installed
18+
* The mongocryptd binary installed
19+
20+
1. Clone this repository and navigate to the **nodejs** directory.
21+
22+
```sh
23+
git clone https://github.com/mongodb-university/csfle-guides.git
24+
cd nodejs
25+
```
26+
27+
Work from the **nodejs** directory for the remainder of these instructions.
28+
29+
2. Start a locally running `mongod` instance (Enterprise version >= 4.2) running on port 27017
30+
31+
3. Install the dependencies in `package.json`
32+
33+
```js
34+
npm install
35+
```
36+
37+
4. Make sure you have the `master-key.txt` file in the root of your execution
38+
environment. This is a 96-byte cryptographically-secure generated master
39+
encryption key required to run this example project. To generate your own
40+
master key or use a KMS, refer to the [CSFLE Use Case Guide](https://docs.mongodb.com/ecosystem/use-cases/client-side-field-level-encryption-guide/).
41+
42+
5. Run the `make-data-key.js` script to make a data key. If there is an
43+
existing data key in the **encryption.\_\_keyVault** collection this script
44+
will not create a duplicate data key.
45+
46+
```js
47+
node make-data-key.js
48+
```
49+
50+
This outputs a base64 encoded string of the UUID of your newly created data key. Paste
51+
this into `clients.js` where you see this line
52+
53+
```js
54+
let dataKey = null // change this!
55+
```
56+
57+
6. Run the `clients.js` script to insert a document with the CSFLE-enabled client
58+
and then read that document with it as well as a regular client. You
59+
will see that the CSFLE-enabled client prints the document out in plaintext,
60+
and the regular client prints the document out with encrypted fields in
61+
binary format. This is safe to run multiple times as the insert operation
62+
used is an update with `upsert` specified.
63+
64+
```js
65+
node clients.js
66+
```
67+
68+
7. Suggestion: Try inserting a document with the regular client. What happens?
69+
70+
## Running CSFLE with Docker
71+
72+
1. Change directories to the docker directory.
73+
```sh
74+
cd docker
75+
```
76+
77+
2. Build Docker image with a tag name. Within this directory execute:
78+
* For using the latest driver version:
79+
```sh
80+
docker build . -t mdb-csfle-example
81+
```
82+
This will build a Docker image with a tag name `mdb-csfle-example`.
83+
84+
3. Run the Docker image by executing:
85+
```sh
86+
docker run -tih csfle mdb-csfle-example
87+
```
88+
The command above will run a Docker image with tag `mdb-csfle-example` and provide it with `csfle` as its hostname.
89+
90+
4. Once you're inside the Docker container, you could follow below steps to run the NodeJS code example.
91+
92+
```sh
93+
$ export MONGODB_URL="mongodb+srv://USER:PWD@EXAMPLE.mongodb.net/dbname?retryWrites=true&w=majority"`
94+
$ node ./example.js
95+
```
96+
97+
If you're connecting to MongoDB Atlas please make sure to [Configure Whitelist Entries](https://docs.atlas.mongodb.com/security-whitelist/)
298

399
## Contributing
4100

app.js

-48
This file was deleted.

clients.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
const { readMasterKey, CsfleHelper } = require("./helpers")
2+
3+
const localMasterKey = readMasterKey()
4+
5+
const csfleHelper = new CsfleHelper({
6+
kmsProviders: {
7+
local: {
8+
key: localMasterKey
9+
}
10+
},
11+
connectionString: "mongodb+srv://joe:karlsson@cluster0.m7f10.mongodb.net/medicalRecords?retryWrites=true&w=majority"
12+
})
13+
14+
async function main() {
15+
// change this to the base64 encoded data key generated from make-data-key.js
16+
let dataKey = "HZrq+a+TSBeZ0txrrnhaqw==";
17+
18+
let regularClient = await csfleHelper.getRegularClient()
19+
let schemeMap = csfleHelper.createJsonSchemaMap(dataKey)
20+
let csfleClient = await csfleHelper.getCsfleEnabledClient(schemeMap)
21+
22+
let exampleDocument = {
23+
name: "Jon Doe",
24+
ssn: 241014209,
25+
bloodType: "AB+",
26+
medicalRecords: [
27+
{
28+
weight: 180,
29+
bloodPressure: "120/80"
30+
}
31+
],
32+
insurance: {
33+
provider: "MaestCare",
34+
policyNumber: 123142
35+
}
36+
}
37+
38+
const regularClientPatientsColl = regularClient
39+
.db("medicalRecords")
40+
.collection("patients")
41+
const csfleClientPatientsColl = csfleClient
42+
.db("medicalRecords")
43+
.collection("patients")
44+
45+
// Performs the insert operation with the csfle-enabled client
46+
// We're using an update with an upsert so that subsequent runs of this script
47+
// don't insert new documents
48+
await csfleClientPatientsColl.updateOne(
49+
{ ssn: exampleDocument["ssn"] },
50+
{ $set: exampleDocument },
51+
{ upsert: true }
52+
)
53+
54+
// Performs a read using the encrypted client, querying on an encrypted field
55+
const csfleFindResult = await csfleClientPatientsColl.findOne({
56+
ssn: exampleDocument["ssn"]
57+
})
58+
console.log(
59+
"Document retreived with csfle enabled client:\n",
60+
csfleFindResult
61+
)
62+
63+
// Performs a read using the regular client. We must query on a field that is
64+
// not encrypted.
65+
// Try - query on the ssn field. What is returned?
66+
const regularFindResult = await regularClientPatientsColl.findOne({
67+
name: "Jon Doe"
68+
})
69+
console.log("Document retreived with regular client:\n", regularFindResult)
70+
71+
await regularClient.close()
72+
await csfleClient.close()
73+
}
74+
75+
main().catch(console.dir)

create-mongodb-data-key.js

-9
This file was deleted.

docker/Dockerfile

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
FROM ubuntu:20.04
2+
3+
ARG DRIVER_VERSION=3.6.2
4+
ARG DEBIAN_FRONTEND=noninteractive
5+
6+
RUN apt-get update && apt-get install -y sudo \
7+
nano \
8+
gnupg \
9+
git \
10+
nodejs \
11+
wget \
12+
npm \
13+
build-essential && \
14+
apt-get clean && \
15+
rm -rf /var/lib/apt/lists/*
16+
17+
RUN wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add -
18+
19+
RUN echo "deb [ arch=amd64,arm64,s390x ] http://repo.mongodb.com/apt/ubuntu focal/mongodb-enterprise/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-enterprise.list
20+
21+
RUN apt-get update && apt-get install -y mongodb-enterprise-cryptd=4.4.1
22+
23+
RUN export uid=1000 gid=1000 && \
24+
mkdir -p /home/ubuntu && \
25+
echo "ubuntu:x:${uid}:${gid}:Developer,,,:/home/ubuntu:/bin/bash" >> /etc/passwd && \
26+
echo "ubuntu:x:${uid}:" >> /etc/group && \
27+
echo "ubuntu ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ubuntu && \
28+
chmod 0440 /etc/sudoers.d/ubuntu && \
29+
chown ${uid}:${gid} -R /home/ubuntu
30+
31+
ENV HOME /home/ubuntu
32+
33+
USER ubuntu
34+
35+
RUN mkdir ${HOME}/csfle
36+
COPY ./csfle/example.js ./csfle/package.json ${HOME}/csfle/
37+
38+
WORKDIR ${HOME}/csfle
39+
RUN npm install mongodb@${DRIVER_VERSION} mongodb-client-encryption uuid-mongodb --save
40+
41+
CMD ["/bin/bash"]

0 commit comments

Comments
 (0)