Skip to content

Instantly share code, notes, and snippets.

@mmarcon
Last active August 11, 2024 14:26
Show Gist options
  • Save mmarcon/27d54fbba234c1dc953cc16673e34275 to your computer and use it in GitHub Desktop.
Save mmarcon/27d54fbba234c1dc953cc16673e34275 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 KMS in GCP.
// 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 mongoDBAtlasConnectionString = '<MONGODB_ATLAS_CONNECTION_STRING>';
// Configure KMS Providers
// Using GCP
const kmsProviders = {
gcp: {
email: '<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com',
privateKey: '<BASE64\nPRIVATE\nKEY>',
}
};
// Get a new Mongo object with the KMS provider configuration
const keyMongo = Mongo(mongoDBAtlasConnectionString, {
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('gcp', {
projectId: '<PROJECT_ID>',
location: 'global',
keyRing: '<KEYRING_NAME>',
keyName: '<KEY_NAME>'
});
// 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(mongoDBAtlasConnectionString, {
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: '[email protected]',
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: '[email protected]'});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment