Mongo Ruby Field-Level Encryption
MongoDB makes Client-Side Field-Level Encryption easy to implement. Take a look at this code snippet:
require 'mongo'
require 'securerandom'
local_master_key = SecureRandom.random_bytes(96)
kms_providers = {
local: {
key: local_master_key
}
}
key_vault_client = Mongo::Client.new(['localhost:27017'])
client_encryption = Mongo::ClientEncryption.new(
key_vault_client,
key_vault_namespace: 'admin.datakeys',
kms_providers: kms_providers
)
data_key_id = client_encryption.create_data_key('local')
schema_map = {
'encryption_db.encryption_coll': {
properties: {
encrypted_field: {
encrypt: {
keyId: [data_key_id],
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
},
bsonType: "object"
}
}
client = Mongo::Client.new(
['localhost:27017'],
auto_encryption_options: {
key_vault_namespace: 'admin.datakeys',
kms_providers: kms_providers,
schema_map: schema_map
}
)
collection = client.use('encryption_db')['encryption_coll']
collection.drop
collection.insert_one(encrypted_field: 'sensitive data')
collection.find(encrypted_field: 'sensitive data').first['encrypted_field']
client_no_encryption = Mongo::Client.new(['localhost:27017'])
client_no_encryption.use('encryption_db')['encryption_coll'].find.first['encrypted_field']
We define the schema for the fields that will be encrypted - this is an option passed to the database client object. Any operations performed through this client object has the encryption/decryption handled transparently.