mirage-encryption
v1.0.0
Published
A utility package for implementing MongoDB Client-Side Field Level Encryption (CSFLE) with support for multiple KMS providers
Downloads
82
Maintainers
Readme
Mirage Encryption
An utility encryption package for implementing MongoDB Client-Side Field Level Encryption (CSFLE).
Features
- Simplified MongoDB CSFLE integration for Node.js applications
- Support for multiple KMS providers (Local, AWS, Azure, GCP)
- Automated Data Encryption Key (DEK) management
- Schema-based encryption configuration
- Cross-platform support (Windows, macOS, Linux)
Documentation
Detailed documentation for all features is available in the docs directory:
- Getting Started Guide - Quick start guide for new users
- ServerEncryptionService - Core encryption service documentation
- KMS Providers - Key Management Service provider details
- Encryption Schema - Schema definition and management
- DekManager - Data Encryption Key management
- EncryptionSchemaService - Schema generation and handling
- Utility Functions - Helper functions reference
- Error Handling - Error types and handling strategies
- Performance & Best Practices - Optimization tips and recommendations
- Testing Guide - Instructions for running and writing tests
Prerequisites
- Node.js v16 or newer
- MongoDB v6.0 or newer
- MongoDB crypt_shared library (platform-specific)
Peer Dependencies:
mongodb(^6.18.0) - MongoDB Node.js drivermongodb-client-encryption(^6.5.0) - MongoDB client-side encryption library
Installation
Install the package and its required peer dependencies:
npm install mirage-encryption mongodb mongodb-client-encryptionOr if using yarn:
yarn add mirage-encryption mongodb mongodb-client-encryptionNote:
mongodbandmongodb-client-encryptionare peer dependencies and must be installed separately to ensure compatibility with your application's MongoDB driver version.
Getting Started
Basic Usage
import { ServerEncryptionService, generateLocalKey } from "mirage-encryption";
import path from "path";
// Configure KMS provider (using local KMS in this example)
const kmsProvider = {
type: "local",
local: {
key: generateLocalKey(), // Generates or loads a key from local-master-key.txt
},
};
// Configure key vault details (where MongoDB stores the encryption keys)
const keyVault = {
database: "encryption",
collection: "_keys_",
};
// Create encryption service
const encryptionService = new ServerEncryptionService(
"mongodb://localhost:27017", // MongoDB URI
kmsProvider,
keyVault,
path.resolve("./path/to/mongo_crypt_v1.dll") // Path to crypt_shared library
);
// Initialize with schema file
await encryptionService.initializeWithFile(
path.resolve("./path/to/schema.json")
);
// Get the MongoDB client with encryption enabled
const client = encryptionService.getMongoClient();
// Use the client as usual
const db = client.db("mydb");
const collection = db.collection("mycollection");
// Data is automatically encrypted/decrypted
await collection.insertOne({
name: "John Doe",
ssn: "123-45-6789", // Will be encrypted if specified in schema
});Schema Definition
To specify which fields should be encrypted, create a schema file like this:
[
{
"mydb.mycollection": {
"ssn": "string",
"creditCard": "string",
"dob": "date",
"medicalRecords": "array",
"contact": {
"email": "string",
"phone": "string"
}
}
}
]This schema will encrypt ssn, creditCard, dob, medicalRecords, and the nested email and phone fields.
Supported KMS Providers
Local KMS
const kmsProvider = {
type: "local",
local: {
key: generateLocalKey(),
},
};AWS KMS
const kmsProvider = {
type: "aws",
aws: {
accessKeyId: "YOUR_ACCESS_KEY",
secretAccessKey: "YOUR_SECRET_KEY",
sessionToken: "YOUR_SESSION_TOKEN", // Optional
},
masterKey: {
region: "us-east-1",
key: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
endpoint: "kms.us-east-1.amazonaws.com", // Optional
},
};Azure Key Vault
const kmsProvider = {
type: "azure",
azure: {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
tenantId: "YOUR_TENANT_ID",
},
masterKey: {
keyVaultEndpoint: "https://your-key-vault.vault.azure.net/",
keyName: "YOUR_KEY_NAME",
keyVersion: "YOUR_KEY_VERSION", // Optional
},
};Google Cloud KMS
const kmsProvider = {
type: "gcp",
gcp: {
email: "[email protected]",
privateKey: "YOUR_PRIVATE_KEY",
},
masterKey: {
projectId: "your-project",
location: "global",
keyRing: "your-key-ring",
keyName: "your-key-name",
keyVersion: "1", // Optional
endpoint: "cloudkms.googleapis.com", // Optional
},
};Advanced Usage
Using EncryptionSchemaService
You can programmatically generate encryption schemas:
import {
DekManager,
EncryptionSchemaService,
MongoClient,
} from "mirage-encryption";
const client = new MongoClient("mongodb://localhost:27017");
const keyVault = { database: "encryption", collection: "_keys_" };
const keyVaultNamespace = `${keyVault.database}.${keyVault.collection}`;
const dekManager = new DekManager(
client,
keyVaultNamespace,
keyVault,
kmsProvider
);
const schemaService = new EncryptionSchemaService(dekManager);
// Generate schema from file
const schema = await schemaService.generateCSFLESchema("./path/to/schema.json");
// Initialize encryption service with the generated schema
encryptionService.initializeWithSchema(schema);Direct Schema Initialization
You can also create and provide the schema directly:
const schema = {
"mydb.mycollection": {
bsonType: "object",
properties: {
ssn: {
encrypt: {
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
keyId: [
/* Binary key IDs */
],
},
},
// Other encrypted fields...
},
},
};
encryptionService.initializeWithSchema(schema);Crypt Shared Library
You need to download the platform-specific MongoDB crypt_shared library:
- Windows:
mongo_crypt_v1.dll - macOS:
mongo_crypt_v1.dylib - Linux:
mongo_crypt_v1.so
For detailed instructions on downloading, installing, and configuring the crypt_shared library, refer to our Crypt Shared Library Guide.
API Reference
Classes
ServerEncryptionService
Main class for setting up MongoDB client-side field level encryption.
constructor(
mongoUri: string,
kmsProvider: IKMSProvider,
keyVault: IKeyVault,
cryptSharedFilePath: string,
options?: MongoClientOptions
)Methods:
initializeWithFile(schemaFilePath: string): Promise<void>initializeWithSchema(schema: IEncryptionSchema): voidgetMongoClient(): MongoClientgetSchema(): IEncryptionSchema
DekManager
Handles Data Encryption Key (DEK) management.
constructor(
mongoClient: MongoClient,
keyVaultNamespace: string,
keyVault: IKeyVault,
kmsProvider: IKMSProvider
)Methods:
getDEK(fieldKeyAltName: string): Promise<Binary>
EncryptionSchemaService
Creates encryption schemas for MongoDB CSFLE.
constructor(dekManager: DekManager)Methods:
generateCSFLESchema(schemaFilePath: string): Promise<IEncryptionSchema>
Utility Functions
generateLocalKey(filePath?: string): string- Generates or loads a local master keyfileExists(filePath: string): boolean- Checks if a file existsvalidateCryptSharedLib(libPath: string): string- Validates the crypt_shared libraryvalidateCSFLESchema(schema: any): boolean- Validates CSFLE schema structure
Error Handling
The package provides several error types:
ConfigurationError- Configuration issuesValidationError- Schema or input validation failuresEncryptionError- Encryption operation failuresKMSError- Key Management Service issues
Example:
import { ConfigurationError, ValidationError } from "mirage-encryption";
try {
// Encryption operations
} catch (error) {
if (error instanceof ConfigurationError) {
// Handle configuration issues
} else if (error instanceof ValidationError) {
// Handle validation failures
} else {
// Handle other errors
}
}Examples
Basic Example with Local KMS
import { ServerEncryptionService, generateLocalKey } from "mirage-encryption";
import path from "path";
async function main() {
// Configuration
const mongoUri = "mongodb://localhost:27017";
const kmsProvider = {
type: "local",
local: {
key: generateLocalKey(),
},
};
const keyVault = {
database: "encryption",
collection: "_keys_",
};
const cryptSharedPath = path.resolve("./path/to/mongo_crypt_v1.dll");
// Initialize encryption service
const encryptionService = new ServerEncryptionService(
mongoUri,
kmsProvider,
keyVault,
cryptSharedPath
);
// Initialize with schema
await encryptionService.initializeWithFile(path.resolve("./schema.json"));
// Get MongoDB client
const client = encryptionService.getMongoClient();
// Connect and use
await client.connect();
// Use client as normal - encryption/decryption is automatic
const db = client.db("mydb");
const collection = db.collection("users");
// Insert data with fields that will be automatically encrypted
const result = await collection.insertOne({
name: "John Doe",
ssn: "123-45-6789", // Will be encrypted
email: "[email protected]", // Will be encrypted if specified in schema
});
console.log(`Inserted document with ID: ${result.insertedId}`);
// Query - automatic decryption happens when reading
const user = await collection.findOne({ name: "John Doe" });
console.log(user);
await client.close();
}
main().catch(console.error);License
ISC
Authors
- Nikhil Gautam
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
