Skip to content

Instantly share code, notes, and snippets.

@mmarcon
Last active February 17, 2021 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmarcon/212795f327d940db5390adacd9b3d13a to your computer and use it in GitHub Desktop.
Save mmarcon/212795f327d940db5390adacd9b3d13a to your computer and use it in GitHub Desktop.
Simple mongosh script to insert a document into MongoDB with Client-side Field-level Encryption and a local KMS.
// To run this script you can start the shell with `mongosh --nodb`
// Wrap everything into a function so we don't
// affect the shell's scope
(function insertTestData() {
// Config DB and Collection names
const dbName = '<TEST_DBNAME>';
const collectionName = '<TEST_COLLNAME>';
const mongoDBConnectionString = '<MONGODB_CONNECTION_STRING>';
// Configure KMS Providers
// Using a local one
const kmsProviders = {
local: { key: BinData(0, 'kh4Gv2N8qopZQMQYMEtww/AkPsIrXNmEMxTrs3tUoTQZbZu4msdRUaR8U5fXD7A7QXYHcEvuu4WctJLoT+NvvV3eeIg3MD+K8H9SR794m/safgRHdIfy6PD+rFpvmFbY') }
};
// Get a new Mongo object with the KMS provider configuration
const keyMongo = Mongo(mongoDBConnectionString, {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders
});
// Get a reference to the Key Vault
const keyVault = keyMongo.getKeyVault();
// Generate a key
// In this example, we will use the same key for all the test documents.
// However, this is a good use case for assigning one key per customer.
const keyId = keyVault.createKey('local', '');
// Schema map for auto encryption
// See https://docs.mongodb.com/manual/core/security-automatic-client-side-encryption/ for
// the details on how automatic encryption works.
// The automatic feature of field level encryption is only available in
// MongoDB 4.2+ Enterprise and MongoDB Atlas 4.2+ clusters.
const schemaMap = {};
schemaMap[`${dbName}.${collectionName}`] = {
bsonType: 'object',
properties: {
birthDate: {
encrypt: {
keyId: [keyId],
bsonType: 'string',
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
}
},
email: {
encrypt: {
keyId: [keyId],
bsonType: 'string',
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
}
},
phone: {
encrypt: {
keyId: [keyId],
bsonType: 'string',
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
}
},
bankAccount: {
encrypt: {
keyId: [keyId],
bsonType: 'object',
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'
}
}
}
};
// Create a new instance of Mongo connected to the same
// cluster but this time with the schemaMap configured as well.
const autoMongo = Mongo(mongoDBConnectionString, {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders,
schemaMap
});
sleep(1000);
// Generate a bunch of fake customer data...
const autoMongoDb = autoMongo.getDB(dbName);
// ... but first clean up old test data ...
autoMongoDb.getCollection(collectionName).drop();
// ... finally, store the new data into the destination collection.
// Fields that the schema map indicates they should be encrypted
// will be encrypted client-side and then stored encrypted in MongoDB
autoMongoDb.getCollection(collectionName).insertOne({
name: {
first: 'Mia',
last: 'Rolfson'
},
email: 'mia4@example.com',
phone: '(123) 456-789',
company: {
name: 'Ernser - Brekke'
},
address: {
zip: '31854',
street: '3196 Era Place',
state: 'NJ'
},
birthDate: '1980-02-18',
bankAccount: {
name: 'Auto Loan Account',
account: '17545520',
bic: 'EEAACUD1411'
},
birthYear: 1980
});
// `email` is encrypted but I can still use it in a filter
// the document resulting from this find will have all the fields automatically decrypted
return autoMongoDb.getCollection(collectionName).find({email: 'mia4@example.com'});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment